kyber512r3_ntt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <stdint.h>
  2. #include "kyber512r3_params.h"
  3. #include "kyber512r3_ntt.h"
  4. #include "kyber512r3_reduce.h"
  5. S2N_ENSURE_PORTABLE_OPTIMIZATIONS
  6. const int16_t zetas[128] = {
  7. 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962,
  8. 2127, 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017,
  9. 732, 608, 1787, 411, 3124, 1758, 1223, 652, 2777, 1015, 2036, 1491, 3047,
  10. 1785, 516, 3321, 3009, 2663, 1711, 2167, 126, 1469, 2476, 3239, 3058, 830,
  11. 107, 1908, 3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, 2226,
  12. 430, 555, 843, 2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574,
  13. 1653, 3083, 778, 1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349,
  14. 418, 329, 3173, 3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193,
  15. 1218, 1994, 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475, 2459,
  16. 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628
  17. };
  18. const int16_t zetas_inv[128] = {
  19. 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535,
  20. 1278, 1530, 1185, 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465,
  21. 1285, 2007, 2719, 2726, 2232, 2512, 75, 156, 3000, 2911, 2980, 872, 2685,
  22. 1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, 1676, 1755, 460, 291, 235,
  23. 3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, 1275, 2652,
  24. 1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853,
  25. 1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552,
  26. 2677, 2106, 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871,
  27. 829, 2946, 3065, 1325, 2756, 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171,
  28. 3127, 3042, 1907, 1836, 1517, 359, 758, 1441
  29. };
  30. /*************************************************
  31. * Name: fqmul
  32. *
  33. * Description: Multiplication followed by Montgomery reduction
  34. *
  35. * Arguments: - int16_t a: first factor
  36. * - int16_t b: second factor
  37. *
  38. * Returns 16-bit integer congruent to a*b*R^{-1} mod q
  39. **************************************************/
  40. static int16_t fqmul(int16_t a, int16_t b) {
  41. return montgomery_reduce((int32_t)a * b);
  42. }
  43. /*************************************************
  44. * Name: ntt
  45. *
  46. * Description: Inplace number-theoretic transform (NTT) in Rq
  47. * input is in standard order, output is in bitreversed order
  48. *
  49. * Arguments: - int16_t r[256]: pointer to input/output vector of elements
  50. * of Zq
  51. **************************************************/
  52. void ntt(int16_t r[256]) {
  53. unsigned int len, start, j, k;
  54. int16_t t, zeta;
  55. k = 1;
  56. for (len = 128; len >= 2; len >>= 1) {
  57. for (start = 0; start < 256; start = j + len) {
  58. zeta = zetas[k++];
  59. for (j = start; j < start + len; ++j) {
  60. t = fqmul(zeta, r[j + len]);
  61. r[j + len] = r[j] - t;
  62. r[j] = r[j] + t;
  63. }
  64. }
  65. }
  66. }
  67. /*************************************************
  68. * Name: invntt_tomont
  69. *
  70. * Description: Inplace inverse number-theoretic transform in Rq and
  71. * multiplication by Montgomery factor 2^16.
  72. * Input is in bitreversed order, output is in standard order
  73. *
  74. * Arguments: - int16_t r[256]: pointer to input/output vector of elements
  75. * of Zq
  76. **************************************************/
  77. void invntt(int16_t r[256]) {
  78. unsigned int start, len, j, k;
  79. int16_t t, zeta;
  80. k = 0;
  81. for (len = 2; len <= 128; len <<= 1) {
  82. for (start = 0; start < 256; start = j + len) {
  83. zeta = zetas_inv[k++];
  84. for (j = start; j < start + len; ++j) {
  85. t = r[j];
  86. r[j] = barrett_reduce(t + r[j + len]);
  87. r[j + len] = t - r[j + len];
  88. r[j + len] = fqmul(zeta, r[j + len]);
  89. }
  90. }
  91. }
  92. for (j = 0; j < 256; ++j) {
  93. r[j] = fqmul(r[j], zetas_inv[127]);
  94. }
  95. }
  96. /*************************************************
  97. * Name: basemul
  98. *
  99. * Description: Multiplication of polynomials in Zq[X]/(X^2-zeta)
  100. * used for multiplication of elements in Rq in NTT domain
  101. *
  102. * Arguments: - int16_t r[2]: pointer to the output polynomial
  103. * - const int16_t a[2]: pointer to the first factor
  104. * - const int16_t b[2]: pointer to the second factor
  105. * - int16_t zeta: integer defining the reduction polynomial
  106. **************************************************/
  107. void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta) {
  108. r[0] = fqmul(a[1], b[1]);
  109. r[0] = fqmul(r[0], zeta);
  110. r[0] += fqmul(a[0], b[0]);
  111. r[1] = fqmul(a[0], b[1]);
  112. r[1] += fqmul(a[1], b[0]);
  113. }