kpqc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.md +174 -0
  5. data/Rakefile +57 -0
  6. data/THIRD_PARTY_NOTICES.md +53 -0
  7. data/ext/kpqc/aimer128f/extconf.rb +4 -0
  8. data/ext/kpqc/aimer128s/extconf.rb +4 -0
  9. data/ext/kpqc/aimer192f/extconf.rb +4 -0
  10. data/ext/kpqc/aimer192s/extconf.rb +4 -0
  11. data/ext/kpqc/aimer256f/extconf.rb +4 -0
  12. data/ext/kpqc/aimer256s/extconf.rb +4 -0
  13. data/ext/kpqc/extconf_helper.rb +93 -0
  14. data/ext/kpqc/haetae2/extconf.rb +4 -0
  15. data/ext/kpqc/haetae3/extconf.rb +4 -0
  16. data/ext/kpqc/haetae5/extconf.rb +4 -0
  17. data/ext/kpqc/module.c +195 -0
  18. data/ext/kpqc/ntruplus1152/extconf.rb +4 -0
  19. data/ext/kpqc/ntruplus768/extconf.rb +4 -0
  20. data/ext/kpqc/ntruplus864/extconf.rb +4 -0
  21. data/ext/kpqc/randombytes.c +107 -0
  22. data/ext/kpqc/smaugt128/extconf.rb +4 -0
  23. data/ext/kpqc/smaugt192/extconf.rb +4 -0
  24. data/ext/kpqc/smaugt256/extconf.rb +4 -0
  25. data/ext/kpqc/timer/extconf.rb +4 -0
  26. data/kpqc.gemspec +41 -0
  27. data/lib/kpqc/aimer.rb +38 -0
  28. data/lib/kpqc/api.rb +129 -0
  29. data/lib/kpqc/haetae.rb +25 -0
  30. data/lib/kpqc/ntruplus.rb +25 -0
  31. data/lib/kpqc/smaugt.rb +29 -0
  32. data/lib/kpqc/types.rb +103 -0
  33. data/lib/kpqc/version.rb +6 -0
  34. data/lib/kpqc.rb +33 -0
  35. data/test/algorithm_test.rb +111 -0
  36. data/test/api_test.rb +52 -0
  37. data/test/interop.mjs +34 -0
  38. data/test/interop_test.rb +82 -0
  39. data/test/kat/aimer128f.rsp +10 -0
  40. data/test/kat/aimer128s.rsp +10 -0
  41. data/test/kat/aimer192f.rsp +10 -0
  42. data/test/kat/aimer192s.rsp +10 -0
  43. data/test/kat/aimer256f.rsp +10 -0
  44. data/test/kat/aimer256s.rsp +10 -0
  45. data/test/kat/haetae2.rsp +10 -0
  46. data/test/kat/haetae3.rsp +10 -0
  47. data/test/kat/haetae5.rsp +10 -0
  48. data/test/kat/ntruplus1152.rsp +8 -0
  49. data/test/kat/ntruplus768.rsp +8 -0
  50. data/test/kat/ntruplus864.rsp +8 -0
  51. data/test/kat/smaugt128.rsp +8 -0
  52. data/test/kat/smaugt192.rsp +8 -0
  53. data/test/kat/smaugt256.rsp +8 -0
  54. data/test/kat/timer.rsp +8 -0
  55. data/test/kat_drbg.rb +155 -0
  56. data/test/kat_test.rb +99 -0
  57. data/test/test_helper.rb +21 -0
  58. data/vendor/AIMer/LICENSE +21 -0
  59. data/vendor/AIMer/aim2.c +163 -0
  60. data/vendor/AIMer/aim2.h +36 -0
  61. data/vendor/AIMer/aim2_constant.h +74 -0
  62. data/vendor/AIMer/api.h +42 -0
  63. data/vendor/AIMer/common/crypto_declassify.h +7 -0
  64. data/vendor/AIMer/common/fips202.c +878 -0
  65. data/vendor/AIMer/common/fips202.h +166 -0
  66. data/vendor/AIMer/common/rng.h +56 -0
  67. data/vendor/AIMer/field.h +43 -0
  68. data/vendor/AIMer/field128.c +454 -0
  69. data/vendor/AIMer/field192.c +485 -0
  70. data/vendor/AIMer/field256.c +564 -0
  71. data/vendor/AIMer/hash.c +50 -0
  72. data/vendor/AIMer/hash.h +37 -0
  73. data/vendor/AIMer/params/params-aimer-128f.h +34 -0
  74. data/vendor/AIMer/params/params-aimer-128s.h +34 -0
  75. data/vendor/AIMer/params/params-aimer-192f.h +34 -0
  76. data/vendor/AIMer/params/params-aimer-192s.h +34 -0
  77. data/vendor/AIMer/params/params-aimer-256f.h +34 -0
  78. data/vendor/AIMer/params/params-aimer-256s.h +34 -0
  79. data/vendor/AIMer/params.h +5 -0
  80. data/vendor/AIMer/sign.c +631 -0
  81. data/vendor/AIMer/sign.h +40 -0
  82. data/vendor/AIMer/tree.c +75 -0
  83. data/vendor/AIMer/tree.h +26 -0
  84. data/vendor/HAETAE/LICENSE +22 -0
  85. data/vendor/HAETAE/include/api.h +54 -0
  86. data/vendor/HAETAE/include/common.h +12 -0
  87. data/vendor/HAETAE/include/config.h +42 -0
  88. data/vendor/HAETAE/include/decompose.h +19 -0
  89. data/vendor/HAETAE/include/encoding.h +20 -0
  90. data/vendor/HAETAE/include/fft.h +26 -0
  91. data/vendor/HAETAE/include/fips202.h +40 -0
  92. data/vendor/HAETAE/include/fixpoint.h +125 -0
  93. data/vendor/HAETAE/include/ntt.h +16 -0
  94. data/vendor/HAETAE/include/packing.h +58 -0
  95. data/vendor/HAETAE/include/params.h +117 -0
  96. data/vendor/HAETAE/include/poly.h +65 -0
  97. data/vendor/HAETAE/include/polyfix.h +65 -0
  98. data/vendor/HAETAE/include/polymat.h +32 -0
  99. data/vendor/HAETAE/include/polyvec.h +131 -0
  100. data/vendor/HAETAE/include/randombytes.h +39 -0
  101. data/vendor/HAETAE/include/rans_byte.h +335 -0
  102. data/vendor/HAETAE/include/reduce.h +31 -0
  103. data/vendor/HAETAE/include/sampler.h +23 -0
  104. data/vendor/HAETAE/include/symmetric.h +52 -0
  105. data/vendor/HAETAE/src/decompose.c +73 -0
  106. data/vendor/HAETAE/src/encoding.c +700 -0
  107. data/vendor/HAETAE/src/fft.c +235 -0
  108. data/vendor/HAETAE/src/fips202.c +745 -0
  109. data/vendor/HAETAE/src/fixpoint.c +143 -0
  110. data/vendor/HAETAE/src/ntt.c +98 -0
  111. data/vendor/HAETAE/src/packing.c +595 -0
  112. data/vendor/HAETAE/src/poly.c +371 -0
  113. data/vendor/HAETAE/src/polyfix.c +298 -0
  114. data/vendor/HAETAE/src/polymat.c +82 -0
  115. data/vendor/HAETAE/src/polyvec.c +534 -0
  116. data/vendor/HAETAE/src/reduce.c +96 -0
  117. data/vendor/HAETAE/src/sampler.c +310 -0
  118. data/vendor/HAETAE/src/sign.c +558 -0
  119. data/vendor/HAETAE/src/symmetric-shake.c +50 -0
  120. data/vendor/NTRUplus/LICENSE +21 -0
  121. data/vendor/NTRUplus/NTRU+1152/api.h +24 -0
  122. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +878 -0
  123. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +166 -0
  124. data/vendor/NTRUplus/NTRU+1152/kem.c +286 -0
  125. data/vendor/NTRUplus/NTRU+1152/ntt.c +394 -0
  126. data/vendor/NTRUplus/NTRU+1152/ntt.h +16 -0
  127. data/vendor/NTRUplus/NTRU+1152/params.h +18 -0
  128. data/vendor/NTRUplus/NTRU+1152/poly.c +318 -0
  129. data/vendor/NTRUplus/NTRU+1152/poly.h +31 -0
  130. data/vendor/NTRUplus/NTRU+1152/randombytes.h +9 -0
  131. data/vendor/NTRUplus/NTRU+1152/symmetric.c +39 -0
  132. data/vendor/NTRUplus/NTRU+1152/symmetric.h +12 -0
  133. data/vendor/NTRUplus/NTRU+768/api.h +24 -0
  134. data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +878 -0
  135. data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +166 -0
  136. data/vendor/NTRUplus/NTRU+768/kem.c +286 -0
  137. data/vendor/NTRUplus/NTRU+768/ntt.c +379 -0
  138. data/vendor/NTRUplus/NTRU+768/ntt.h +16 -0
  139. data/vendor/NTRUplus/NTRU+768/params.h +18 -0
  140. data/vendor/NTRUplus/NTRU+768/poly.c +320 -0
  141. data/vendor/NTRUplus/NTRU+768/poly.h +31 -0
  142. data/vendor/NTRUplus/NTRU+768/randombytes.h +9 -0
  143. data/vendor/NTRUplus/NTRU+768/symmetric.c +39 -0
  144. data/vendor/NTRUplus/NTRU+768/symmetric.h +12 -0
  145. data/vendor/NTRUplus/NTRU+864/api.h +24 -0
  146. data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +878 -0
  147. data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +166 -0
  148. data/vendor/NTRUplus/NTRU+864/kem.c +286 -0
  149. data/vendor/NTRUplus/NTRU+864/ntt.c +383 -0
  150. data/vendor/NTRUplus/NTRU+864/ntt.h +16 -0
  151. data/vendor/NTRUplus/NTRU+864/params.h +18 -0
  152. data/vendor/NTRUplus/NTRU+864/poly.c +314 -0
  153. data/vendor/NTRUplus/NTRU+864/poly.h +31 -0
  154. data/vendor/NTRUplus/NTRU+864/randombytes.h +9 -0
  155. data/vendor/NTRUplus/NTRU+864/symmetric.c +39 -0
  156. data/vendor/NTRUplus/NTRU+864/symmetric.h +12 -0
  157. data/vendor/SMAUG-T/LICENSE +22 -0
  158. data/vendor/SMAUG-T/include/api.h +37 -0
  159. data/vendor/SMAUG-T/include/cbd.h +15 -0
  160. data/vendor/SMAUG-T/include/ciphertext.h +45 -0
  161. data/vendor/SMAUG-T/include/common.h +12 -0
  162. data/vendor/SMAUG-T/include/config.h +48 -0
  163. data/vendor/SMAUG-T/include/dg.h +28 -0
  164. data/vendor/SMAUG-T/include/fips202.h +41 -0
  165. data/vendor/SMAUG-T/include/hash.h +21 -0
  166. data/vendor/SMAUG-T/include/hwt.h +28 -0
  167. data/vendor/SMAUG-T/include/indcpa.h +33 -0
  168. data/vendor/SMAUG-T/include/key.h +34 -0
  169. data/vendor/SMAUG-T/include/pack.h +78 -0
  170. data/vendor/SMAUG-T/include/packring.h +50 -0
  171. data/vendor/SMAUG-T/include/params.h +84 -0
  172. data/vendor/SMAUG-T/include/poly.h +41 -0
  173. data/vendor/SMAUG-T/include/randombytes.h +11 -0
  174. data/vendor/SMAUG-T/include/toomcook.h +14 -0
  175. data/vendor/SMAUG-T/include/verify.h +16 -0
  176. data/vendor/SMAUG-T/src/cbd.c +159 -0
  177. data/vendor/SMAUG-T/src/ciphertext.c +95 -0
  178. data/vendor/SMAUG-T/src/dg.c +112 -0
  179. data/vendor/SMAUG-T/src/fips202.c +745 -0
  180. data/vendor/SMAUG-T/src/hash.c +15 -0
  181. data/vendor/SMAUG-T/src/hwt.c +121 -0
  182. data/vendor/SMAUG-T/src/indcpa.c +187 -0
  183. data/vendor/SMAUG-T/src/kem.c +194 -0
  184. data/vendor/SMAUG-T/src/key.c +102 -0
  185. data/vendor/SMAUG-T/src/pack.c +349 -0
  186. data/vendor/SMAUG-T/src/packring.c +503 -0
  187. data/vendor/SMAUG-T/src/poly.c +200 -0
  188. data/vendor/SMAUG-T/src/toomcook.c +256 -0
  189. data/vendor/SMAUG-T/src/verify.c +48 -0
  190. data/vendor/SOURCES.json +130 -0
  191. metadata +280 -0
@@ -0,0 +1,143 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "fixpoint.h"
4
+ #include "params.h"
5
+
6
+ #include <stdint.h>
7
+ #include <stdlib.h>
8
+
9
+ static void __cneg(fp96_76 *x, const uint8_t sign) {
10
+ x->limb48[0] ^= (-(int64_t)sign) & ((1ULL << 48) - 1);
11
+ x->limb48[1] ^= -(int64_t)sign;
12
+ x->limb48[0] += sign;
13
+ renormalize(x);
14
+ }
15
+
16
+ static void __copy_cneg(fp96_76 *y, const fp96_76 *x, const uint8_t sign) {
17
+ y->limb48[0] = ((-(int64_t)sign) & ((1ULL << 48) - 1)) ^ x->limb48[0];
18
+ ;
19
+ y->limb48[1] = x->limb48[1] ^ (-(int64_t)sign);
20
+ y->limb48[0] += sign;
21
+ renormalize(y);
22
+ }
23
+
24
+ static void fixpoint_mul(fp96_76 *xy, const fp96_76 *x, const fp96_76 *y) {
25
+ uint64_t tmp[2];
26
+ mul48(&xy->limb48[0], x->limb48[0], y->limb48[0]);
27
+
28
+ // shift right by 48, rounding
29
+ xy->limb48[0] = xy->limb48[1] + (((xy->limb48[0] >> 47) + 1) >> 1);
30
+
31
+ mul48(tmp, x->limb48[0], y->limb48[1]);
32
+ xy->limb48[0] += tmp[0];
33
+ xy->limb48[1] = tmp[1];
34
+ mulacc48(&xy->limb48[0], x->limb48[1], y->limb48[0]);
35
+
36
+ // shift right by 28, rounding
37
+ xy->limb48[0] += 1UL << 27;
38
+ xy->limb48[0] >>= 28;
39
+ xy->limb48[0] += (xy->limb48[1] << 20) & ((1ULL << 48) - 1);
40
+ xy->limb48[1] >>= 28;
41
+
42
+ mul64(tmp, x->limb48[1], y->limb48[1]);
43
+ xy->limb48[0] += (tmp[0] << 20) & ((1ULL << 48) - 1);
44
+ xy->limb48[1] += (tmp[0] >> 28) + (tmp[1] << 36);
45
+
46
+ renormalize(xy);
47
+ }
48
+
49
+ static void fixpoint_unsigned_signed_mul(fp96_76 *xy, const fp96_76 *y) {
50
+ fp96_76 x, z;
51
+ uint8_t sign = (y->limb48[1] >> 63) & 1;
52
+ __copy_cneg(&x, y, sign);
53
+ fixpoint_mul(&z, &x, xy);
54
+ __copy_cneg(xy, &z, sign);
55
+ }
56
+
57
+ static void fixpoint_sub(fp96_76 *xminy, const fp96_76 *x, const fp96_76 *y) {
58
+ fp96_76 yneg;
59
+ __copy_cneg(&yneg, y, 1);
60
+ fixpoint_add(xminy, x, &yneg);
61
+ }
62
+
63
+ static void fixpoint_sub_from_threehalves(fp96_76 *x) {
64
+ __cneg(x, 1);
65
+ x->limb48[1] += 3ULL << 27; // left shift by 28 would be "3"
66
+ renormalize(x);
67
+ }
68
+
69
+ void fixpoint_square(fp96_76 *sqx, const fp96_76 *x) {
70
+ uint64_t tmp[2];
71
+ sq48(&sqx->limb48[0], x->limb48[0]);
72
+
73
+ // shift right by 48, rounding
74
+ // sqx->limb48[0] += 1ULL << 47;
75
+ sqx->limb48[0] >>= 48;
76
+ sqx->limb48[0] += sqx->limb48[1];
77
+
78
+ // mul
79
+ mul48(tmp, x->limb48[0], x->limb48[1]);
80
+ sqx->limb48[0] += tmp[0] << 1;
81
+ sqx->limb48[1] = tmp[1] << 1;
82
+
83
+ // shift right by 28, rounding
84
+ // sqx->limb48[0] += 1ULL << 27;
85
+ sqx->limb48[0] >>= 28;
86
+ sqx->limb48[0] += (sqx->limb48[1] << 20) & ((1ULL << 48) - 1);
87
+ sqx->limb48[1] >>= 28;
88
+
89
+ sq64(tmp, x->limb48[1]);
90
+ sqx->limb48[0] += (tmp[0] << 20) & ((1ULL << 48) - 1);
91
+ sqx->limb48[1] += (tmp[0] >> 28) + (tmp[1] << 36);
92
+
93
+ renormalize(sqx);
94
+ }
95
+
96
+ // start_cube = hex(round(2^64/(sqrt((K + L)*N + 2)^3)))
97
+ // start_times_threehalfs = hex(round(2^64 * 2/(3 * sqrt((K + L)*N + 2))))
98
+ #if HAETAE_MODE == HAETAE_MODE2
99
+ const fp96_76 start_cube = {.limb48 = {0x770077e2e41aULL, 0x1162ULL}};
100
+ const fp96_76 start_times_threehalves = {
101
+ .limb48 = {0x693861ad937bULL, 0x9caa56ULL}};
102
+ #elif HAETAE_MODE == HAETAE_MODE3
103
+ const fp96_76 start_cube = {.limb48 = {0x1a2935cfae68ULL, 0x978ULL}};
104
+ const fp96_76 start_times_threehalves = {
105
+ .limb48 = {0x7ad215218533ULL, 0x7ff1c9ULL}};
106
+ #elif HAETAE_MODE == HAETAE_MODE5
107
+ const fp96_76 start_cube = {.limb48 = {0x700ff3e8890dULL, 0x702ULL}};
108
+ const fp96_76 start_times_threehalves = {
109
+ .limb48 = {0x5768588eed31ULL, 0x73bd40ULL}};
110
+ #endif
111
+
112
+ // implements Newton's method
113
+ void fixpoint_newton_invsqrt(fp96_76 *invsqrtx, const fp96_76 *xhalf) {
114
+ fp96_76 tmp, tmp2;
115
+ fixpoint_mul(&tmp, xhalf, &start_cube); // definitely two positive values
116
+ fixpoint_sub(invsqrtx, &start_times_threehalves,
117
+ &tmp); // first Newton iteration done, might be negative (very
118
+ // improbable)
119
+
120
+ for (int i = 0; i < 6; i++) // 6 more iterations
121
+ {
122
+ fixpoint_square(&tmp, invsqrtx); // tmp = y^2, never negative
123
+ fixpoint_mul(&tmp2, xhalf, &tmp); // tmp2 = x/2 * y^2, never negative
124
+ fixpoint_sub_from_threehalves(&tmp2); // tmp = 3/2 - x/2 * y^2
125
+ fixpoint_unsigned_signed_mul(invsqrtx, &tmp2); // y * (3/2 - x/2 * y^2)
126
+ }
127
+ }
128
+
129
+ int32_t fixpoint_mul_rnd13(const uint64_t x, const fp96_76 *y,
130
+ const uint8_t sign) {
131
+ int64_t res;
132
+ fp96_76 tmp, xx;
133
+ xx.limb48[1] = x >> 32;
134
+ xx.limb48[0] = (x & ((1ULL << 32) - 1)) << 16;
135
+ fixpoint_mul(&tmp, &xx, y);
136
+ res = (tmp.limb48[1] + (1UL << 14)) >> 15; // rounding
137
+ return (1 - 2 * (int32_t)sign) * res;
138
+ }
139
+
140
+ void fixpoint_add(fp96_76 *xy, const fp96_76 *x, const fp96_76 *y) {
141
+ xy->limb48[0] = x->limb48[0] + y->limb48[0];
142
+ xy->limb48[1] = x->limb48[1] + y->limb48[1];
143
+ }
@@ -0,0 +1,98 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "ntt.h"
4
+ #include "params.h"
5
+ #include "reduce.h"
6
+
7
+ #include <stdint.h>
8
+
9
+ static const int32_t zetas[HAETAE_N] = {
10
+ 0, 26964, -16505, 22229, 30746, 20243, 19064, -31218, 9395,
11
+ -30985, 22859, -8851, 32144, 13744, 21408, 17599, -16039, -22946,
12
+ 6241, -19553, 10681, 22935, 22431, -29104, 28147, -27527, -29133,
13
+ -20035, 20143, -11361, 30820, 25252, -22562, -6789, -10049, 9383,
14
+ 16304, -12296, 16446, 18239, -1296, -19725, -32076, 11782, -17941,
15
+ 29643, -8577, 7893, -21464, -19646, -15130, -2391, 30608, -23970,
16
+ -16608, 19616, -7941, 26533, -19129, 27690, 7597, -11459, 10615,
17
+ -9430, 11591, 7814, 12697, 32114, -3761, -9604, 19813, 20353,
18
+ 17456, -16267, -19555, 598, -29942, 4538, 835, 15546, 3970,
19
+ -27685, 1488, 8311, -12442, 31352, -17631, 1806, -5342, 9790,
20
+ 29068, 16507, -29051, 22131, 6759, 15510, -14941, 28710, 1160,
21
+ -31327, 24985, 11261, -10623, -27727, 21502, 18731, -16186, -4127,
22
+ -18832, 12050, -14501, 7929, 29563, -31064, 5913, 5322, -16405,
23
+ 2844, 29439, 5876, -9522, -18586, -9874, 23844, 30362, -21442,
24
+ 9560, 17671, -27989, 3350, 787, -13857, 1657, -21224, -7374,
25
+ -9190, 2464, 25555, -3529, -28772, 16588, -15739, 23475, 13666,
26
+ 5764, 30980, 13633, -7401, -30317, 28847, 7682, -11808, -8796,
27
+ 14864, -24162, -19194, 689, -1311, -31332, -16319, 1025, 10971,
28
+ -23016, -2648, -21900, -12543, -25921, 28254, 28521, -16160, 12380,
29
+ -12882, -30332, -16630, 23439, 7742, 17182, 17494, 5920, 13642,
30
+ 7382, -18166, 21422, -30274, -28190, 13283, -20316, -9939, 10672,
31
+ 21454, 6080, -17374, -29735, -25912, -10170, 3808, 10639, -26985,
32
+ -10865, 25636, 17261, -26851, -8253, -3304, 18282, -2202, -31368,
33
+ -22243, 13882, 12069, -11242, -7729, -10226, 1761, -27298, -4800,
34
+ -17737, -22805, -3528, 65, 10770, 8908, -23751, 26934, 21921,
35
+ -27010, -21944, 8889, -1035, 23224, -9488, -5823, -994, -20206,
36
+ 7655, -16251, -22820, -27740, 15822, 23078, 13803, -8099, 2931,
37
+ 9217, -21126, -14203, 25492, -12831, 7947, 17463, -12979, 29003,
38
+ 31612, 26554, 8241, -20175}; // q = 64513
39
+
40
+ /*************************************************
41
+ * Name: ntt
42
+ *
43
+ * Description: Forward NTT, in-place. No modular reduction is performed after
44
+ * additions or subtractions. Output vector is in bitreversed
45
+ * order.
46
+ *
47
+ * Arguments: - uint32_t p[HAETAE_N]: input/output coefficient array
48
+ **************************************************/
49
+ void ntt(int32_t a[HAETAE_N]) {
50
+ unsigned int len, start, j, k;
51
+ int32_t zeta, t;
52
+
53
+ k = 0;
54
+ for (len = 128; len > 0; len >>= 1) {
55
+ for (start = 0; start < HAETAE_N; start = j + len) {
56
+ zeta = zetas[++k];
57
+ for (j = start; j < start + len; ++j) {
58
+ t = montgomery_reduce((int64_t)zeta * a[j + len]);
59
+ a[j + len] = a[j] - t;
60
+ a[j] = a[j] + t;
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ /*************************************************
67
+ * Name: invntt_tomont
68
+ *
69
+ * Description: Inverse NTT and multiplication by Montgomery factor 2^32.
70
+ * In-place. No modular reductions after additions or
71
+ * subtractions; input coefficients need to be smaller than
72
+ * HAETAE_Q in absolute value. Output coefficient are smaller than
73
+ * HAETAE_Q in absolute value.
74
+ *
75
+ * Arguments: - uint32_t p[HAETAE_N]: input/output coefficient array
76
+ **************************************************/
77
+ void invntt_tomont(int32_t a[HAETAE_N]) {
78
+ unsigned int start, len, j, k;
79
+ int32_t t, zeta;
80
+ const int32_t f = -29720; // mont^2/256
81
+
82
+ k = 256;
83
+ for (len = 1; len < HAETAE_N; len <<= 1) {
84
+ for (start = 0; start < HAETAE_N; start = j + len) {
85
+ zeta = -zetas[--k];
86
+ for (j = start; j < start + len; ++j) {
87
+ t = a[j];
88
+ a[j] = t + a[j + len];
89
+ a[j + len] = t - a[j + len];
90
+ a[j + len] = montgomery_reduce((int64_t)zeta * a[j + len]);
91
+ }
92
+ }
93
+ }
94
+
95
+ for (j = 0; j < HAETAE_N; ++j) {
96
+ a[j] = montgomery_reduce((int64_t)f * a[j]);
97
+ }
98
+ }