Ntt
namespace Org.BouncyCastle.Crypto.Kems.MLKem
{
internal static class Ntt
{
internal static readonly short[] Zetas = new short[128] {
2285,
2571,
2970,
1812,
1493,
1422,
287,
202,
3158,
622,
1577,
182,
962,
2127,
1855,
1468,
573,
2004,
264,
383,
2500,
1458,
1727,
3199,
2648,
1017,
732,
608,
1787,
411,
3124,
1758,
1223,
652,
2777,
1015,
2036,
1491,
3047,
1785,
516,
3321,
3009,
2663,
1711,
2167,
126,
1469,
2476,
3239,
3058,
830,
107,
1908,
3082,
2378,
2931,
961,
1821,
2604,
448,
2264,
677,
2054,
2226,
430,
555,
843,
2078,
871,
1550,
105,
422,
587,
177,
3094,
3038,
2869,
1574,
1653,
3083,
778,
1159,
3182,
2552,
1483,
2727,
1119,
1739,
644,
2457,
349,
418,
329,
3173,
3254,
817,
1097,
603,
610,
1322,
2044,
1864,
384,
2114,
3193,
1218,
1994,
2455,
220,
2142,
1670,
2144,
1799,
2051,
794,
1819,
2475,
2459,
478,
3221,
3021,
996,
991,
958,
1869,
1522,
1628
};
internal static readonly short[] ZetasInv = new short[128] {
1701,
1807,
1460,
2371,
2338,
2333,
308,
108,
2851,
870,
854,
1510,
2535,
1278,
1530,
1185,
1659,
1187,
3109,
874,
1335,
2111,
136,
1215,
2945,
1465,
1285,
2007,
2719,
2726,
2232,
2512,
75,
156,
3000,
2911,
2980,
872,
2685,
1590,
2210,
602,
1846,
777,
147,
2170,
2551,
246,
1676,
1755,
460,
291,
235,
3152,
2742,
2907,
3224,
1779,
2458,
1251,
2486,
2774,
2899,
1103,
1275,
2652,
1065,
2881,
725,
1508,
2368,
398,
951,
247,
1421,
3222,
2499,
271,
90,
853,
1860,
3203,
1162,
1618,
666,
320,
8,
2813,
1544,
282,
1838,
1293,
2314,
552,
2677,
2106,
1571,
205,
2918,
1542,
2721,
2597,
2312,
681,
130,
1602,
1871,
829,
2946,
3065,
1325,
2756,
1861,
1474,
1202,
2367,
3147,
1752,
2707,
171,
3127,
3042,
1907,
1836,
1517,
359,
758,
1441
};
private static short FactorQMulMont(short a, short b)
{
return Reduce.MontgomeryReduce(a * b);
}
internal static void NTT(short[] r)
{
int num = 1;
for (int num2 = 128; num2 >= 2; num2 >>= 1) {
int i;
for (int num3 = 0; num3 < 256; num3 = i + num2) {
short a = Zetas[num++];
for (i = num3; i < num3 + num2; i++) {
short num5 = FactorQMulMont(a, r[i + num2]);
r[i + num2] = (short)(r[i] - num5);
r[i] += num5;
}
}
}
}
internal static void InvNTT(short[] r)
{
int num = 0;
int num2 = 0;
for (int num3 = 2; num3 <= 128; num3 <<= 1) {
for (int num4 = 0; num4 < 256; num4 = num + num3) {
short a = ZetasInv[num2++];
for (num = num4; num < num4 + num3; num++) {
short num6 = r[num];
r[num] = Reduce.BarrettReduce((short)(num6 + r[num + num3]));
r[num + num3] = (short)(num6 - r[num + num3]);
r[num + num3] = FactorQMulMont(a, r[num + num3]);
}
}
}
for (int i = 0; i < 256; i++) {
r[i] = FactorQMulMont(r[i], ZetasInv[127]);
}
}
internal static void BaseMult(short[] r, int off, short a0, short a1, short b0, short b1, short zeta)
{
short a2 = FactorQMulMont(a1, b1);
a2 = FactorQMulMont(a2, zeta);
a2 = (r[off] = (short)(a2 + FactorQMulMont(a0, b0)));
short num = FactorQMulMont(a0, b1);
num = (r[off + 1] = (short)(num + FactorQMulMont(a1, b0)));
}
}
}