/// <summary> /// Generates the zeta tables /// </summary> static void init_ntt() { int i, j, k; var tmp = new int16_t[128]; tmp[0] = MONT; for (i = 1; i < 128; ++i) { tmp[i] = fqmul(tmp[i - 1], KYBER_ROOT_OF_UNITY * MONT % KYBER_Q); } for (i = 0; i < 128; ++i) { zetas[i] = tmp[tree[i]]; } k = 0; for (i = 64; i >= 1; i >>= 1) { for (j = i; j < 2 * i; ++j) { zetas_inv[k++] = -tmp[128 - tree[j]]; } } zetas_inv[127] = MONT * (MONT * (KYBER_Q - 1) * ((KYBER_Q - 1) / 128) % KYBER_Q) % KYBER_Q; }
public static int16_t csubq(int16_t a) { var result = a - KYBER_Q; result += (a >> 15) & KYBER_Q; return((int16_t)result); }
public static int16_t barrett_reduce(int16_t a) { var t = BR * a; t >>= 26; t *= KYBER_Q; return((int16_t)(a - t)); }
public static void basemul(Span <N2, int16_t> r, Span <N2, int16_t> a, Span <N2, int16_t> b, int16_t zeta) { r[0] = fqmul(a[1], b[1]); r[0] = fqmul(r[0], zeta); r[0] += fqmul(a[0], b[0]); r[1] = fqmul(a[0], b[1]); r[1] += fqmul(a[1], b[0]); }
public static int16_t fqmul(int16_t a, int16_t b) => montgomery_reduce((int32_t)a * b);