<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

Ntt

static class 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))); } } }