/*- * Copyright (c) 2015-2017 Taylor R. Campbell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef MOD311_H #define MOD311_H #include /* * Arithmetic modulo 2^31 - 1 * * We represent a residue class of Z/(2^31 - 1)Z by a 32-bit * representative, not necessarily fully reduced. Callers requiring * the least representative must use reduce311. */ #define M31 UINT32_C(0x7fffffff) /* * reduce311(x) * * Given 0 <= x <= 2^32 - 1, yield a residue of x modulo 2^31 - 1. * For 0 < x < 2^32 - 1, this is the least positive residue; * otherwise, reduce311(0) = 0 and reduce311(2^32 - 1) = 2^31. * Note that reduce311(2^31 - 1) = 2^31 - 1. */ static inline uint32_t reduce311(uint32_t x) { /* 2^31 = 1 (mod 2^31 - 1), so 2^31 h + l = h + l (mod 2^31 - 1). */ return (x >> 31) + (x & M31); } /* * add311(a, b) * * Given a, b <= 2^31 - 1, compute an integer x <= 2^31 - 1 * congruent to a + b modulo 2^31 - 1. */ static inline uint32_t add311(uint32_t a, uint32_t b) { /* * a, b <= 2^31 - 1, so a + b <= 2^32 - 2 < 2^32. Further, * reduce311(2^32 - 2) = 1 + (2^31 - 2) = 2^31 - 1 is the * greatest possible image. */ return reduce311(a + b); } /* * neg311(x) * * Given x <= 2^31 - 1, compute an integer y <= 2^31 - 1 congruent * to 0 - x modulo 2^31 - 1. */ static inline uint32_t neg311(uint32_t x) { /* x <= 2^32 - 1, so 2^32 - 1 - x <= 2^32 - 1. */ return M31 - x; } /* * mul311(a, b) * * Given a, b <= 2^31 - 1, compute an integer x <= 2^31 - 1 * congruent to a*b modulo 2^31 - 1. */ static inline uint32_t mul311(uint32_t a, uint32_t b) { const uint64_t p = ((uint64_t)a * (uint64_t)b); /* * a, b <= 2^31 - 1, so that p = a * b <= 2^62 - 2^32 + 1. * Hence (p >> 31) <= 2^31 - 2 and (p & M31) <= 2^31 - 1, so * we can safely use add311 to do the reduction. */ return add311(p >> 31, p & M31); } #endif /* MOD311_H */