KpqC-0.1.0: cbits/third_party/HAETAE/src/ntt.c
// SPDX-License-Identifier: MIT
#include "ntt.h"
#include "params.h"
#include "reduce.h"
#include <stdint.h>
static const int32_t zetas[HAETAE_N] = {
0, 26964, -16505, 22229, 30746, 20243, 19064, -31218, 9395,
-30985, 22859, -8851, 32144, 13744, 21408, 17599, -16039, -22946,
6241, -19553, 10681, 22935, 22431, -29104, 28147, -27527, -29133,
-20035, 20143, -11361, 30820, 25252, -22562, -6789, -10049, 9383,
16304, -12296, 16446, 18239, -1296, -19725, -32076, 11782, -17941,
29643, -8577, 7893, -21464, -19646, -15130, -2391, 30608, -23970,
-16608, 19616, -7941, 26533, -19129, 27690, 7597, -11459, 10615,
-9430, 11591, 7814, 12697, 32114, -3761, -9604, 19813, 20353,
17456, -16267, -19555, 598, -29942, 4538, 835, 15546, 3970,
-27685, 1488, 8311, -12442, 31352, -17631, 1806, -5342, 9790,
29068, 16507, -29051, 22131, 6759, 15510, -14941, 28710, 1160,
-31327, 24985, 11261, -10623, -27727, 21502, 18731, -16186, -4127,
-18832, 12050, -14501, 7929, 29563, -31064, 5913, 5322, -16405,
2844, 29439, 5876, -9522, -18586, -9874, 23844, 30362, -21442,
9560, 17671, -27989, 3350, 787, -13857, 1657, -21224, -7374,
-9190, 2464, 25555, -3529, -28772, 16588, -15739, 23475, 13666,
5764, 30980, 13633, -7401, -30317, 28847, 7682, -11808, -8796,
14864, -24162, -19194, 689, -1311, -31332, -16319, 1025, 10971,
-23016, -2648, -21900, -12543, -25921, 28254, 28521, -16160, 12380,
-12882, -30332, -16630, 23439, 7742, 17182, 17494, 5920, 13642,
7382, -18166, 21422, -30274, -28190, 13283, -20316, -9939, 10672,
21454, 6080, -17374, -29735, -25912, -10170, 3808, 10639, -26985,
-10865, 25636, 17261, -26851, -8253, -3304, 18282, -2202, -31368,
-22243, 13882, 12069, -11242, -7729, -10226, 1761, -27298, -4800,
-17737, -22805, -3528, 65, 10770, 8908, -23751, 26934, 21921,
-27010, -21944, 8889, -1035, 23224, -9488, -5823, -994, -20206,
7655, -16251, -22820, -27740, 15822, 23078, 13803, -8099, 2931,
9217, -21126, -14203, 25492, -12831, 7947, 17463, -12979, 29003,
31612, 26554, 8241, -20175}; // q = 64513
/*************************************************
* Name: ntt
*
* Description: Forward NTT, in-place. No modular reduction is performed after
* additions or subtractions. Output vector is in bitreversed
* order.
*
* Arguments: - uint32_t p[HAETAE_N]: input/output coefficient array
*
* Specification: Implements @[Algorithm 2, NTT]
**************************************************/
void ntt(int32_t a[HAETAE_N]) {
unsigned int len, start, j, k;
int32_t zeta, t;
k = 0;
for (len = 128; len > 0; len >>= 1) {
for (start = 0; start < HAETAE_N; start = j + len) {
zeta = zetas[++k];
for (j = start; j < start + len; ++j) {
t = montgomery_reduce((int64_t)zeta * a[j + len]);
a[j + len] = a[j] - t;
a[j] = a[j] + t;
}
}
}
}
/*************************************************
* Name: invntt_tomont
*
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
* In-place. No modular reductions after additions or
* subtractions; input coefficients need to be smaller than
* HAETAE_Q in absolute value. Output coefficient are smaller than
* HAETAE_Q in absolute value.
*
* Arguments: - uint32_t p[HAETAE_N]: input/output coefficient array
**************************************************/
void invntt_tomont(int32_t a[HAETAE_N]) {
unsigned int start, len, j, k;
int32_t t, zeta;
const int32_t f = -29720; // mont^2/256
k = 256;
for (len = 1; len < HAETAE_N; len <<= 1) {
for (start = 0; start < HAETAE_N; start = j + len) {
zeta = -zetas[--k];
for (j = start; j < start + len; ++j) {
t = a[j];
a[j] = t + a[j + len];
a[j + len] = t - a[j + len];
a[j + len] = montgomery_reduce((int64_t)zeta * a[j + len]);
}
}
}
for (j = 0; j < HAETAE_N; ++j) {
a[j] = montgomery_reduce((int64_t)f * a[j]);
}
}