#include #include "params.h" #include "reduce.h" /************************************************* * Name: fqmul * * Description: Multiplication followed by Montgomery reduction * For finite field element a with -2^{31}Q <= a <= Q*2^31, * compute r \equiv a*2^{-32} (mod Q) such that -Q < r < Q. * * Arguments: - int32_t a: first factor * - int32_t b: second factor * * Returns r. **************************************************/ int64_t fqmul(int32_t a, int32_t b) { int64_t s; int32_t t; s = (int64_t)a*b; t = (int64_t)(int32_t)s*QINV; t = (s - (int64_t)t*Q) >> 32; return t; } /************************************************* * Name: reduce32 * * Description: For finite field element a with a <= 2^{31} - 2^{22} - 1, * compute r \equiv a (mod Q) such that -6283009 <= r <= 6283008. * * Arguments: - int32_t: finite field element a * * Returns r. **************************************************/ int32_t reduce32(int32_t a) { int32_t t; t = (a + (1 << 22)) >> 23; t = a - t*Q; return t; } /************************************************* * Name: caddq * * Description: Add Q if input coefficient is negative. * * Arguments: - int32_t: finite field element a * * Returns r. **************************************************/ int32_t caddq(int32_t a) { a += (a >> 31) & Q; return a; } /************************************************* * Name: freeze * * Description: For finite field element a, compute standard * representative r = a mod^+ Q. * * Arguments: - int32_t: finite field element a * * Returns r. **************************************************/ int32_t freeze(int32_t a) { a = reduce32(a); a = caddq(a); return a; }