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,310 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "sampler.h"
4
+ #include "fixpoint.h"
5
+ #include "symmetric.h"
6
+
7
+ #include <stdint.h>
8
+
9
+ /*************************************************
10
+ * Name: rej_uniform
11
+ *
12
+ * Description: Sample uniformly random coefficients in [0, HAETAE_Q-1] by
13
+ * performing rejection sampling on array of random bytes.
14
+ *
15
+ * Arguments: - int32_t *a: pointer to output array (allocated)
16
+ * - unsigned int len: number of coefficients to be sampled
17
+ * - const uint8_t *buf: array of random bytes
18
+ * - unsigned int buflen: length of array of random bytes
19
+ *
20
+ * Returns number of sampled coefficients. Can be smaller than len if not enough
21
+ * random bytes were given.
22
+ *
23
+ * Specification: Implements Algorithm 7, RejUniform.
24
+ **************************************************/
25
+ unsigned int rej_uniform(int32_t *a, unsigned int len, const uint8_t *buf,
26
+ unsigned int buflen) {
27
+ unsigned int ctr, pos;
28
+ uint32_t t;
29
+
30
+ ctr = pos = 0;
31
+ while (ctr < len && pos + 2 <= buflen) {
32
+ t = buf[pos++];
33
+ t |= (uint32_t)buf[pos++] << 8;
34
+
35
+ if (t < HAETAE_Q)
36
+ a[ctr++] = t;
37
+ }
38
+ return ctr;
39
+ }
40
+
41
+ /*************************************************
42
+ * Name: rej_eta
43
+ *
44
+ * Description: Sample uniformly random coefficients in [-HAETAE_ETA,
45
+ * HAETAE_ETA] by performing rejection sampling on array
46
+ * of random bytes.
47
+ *
48
+ * Arguments: - int32_t *a: pointer to output array (allocated)
49
+ * - unsigned int len: number of coefficients to be sampled
50
+ * - const uint8_t *buf: array of random bytes
51
+ * - unsigned int buflen: length of array of random bytes
52
+ *
53
+ * Returns number of sampled coefficients. Can be smaller than len if not enough
54
+ * random bytes were given.
55
+ *
56
+ * Specification: Implements Algorithm 10, RejEta.
57
+ **************************************************/
58
+ static int32_t mod3(uint8_t t) {
59
+ int32_t r;
60
+ r = (t >> 4) + (t & 0xf);
61
+ r = (r >> 2) + (r & 3);
62
+ r = (r >> 2) + (r & 3);
63
+ r = (r >> 2) + (r & 3);
64
+ return r - (3 * (r >> 1));
65
+ }
66
+ static int32_t mod3_leq26(uint8_t t) {
67
+ int32_t r;
68
+ r = (t >> 4) + (t & 0xf);
69
+ r = (r >> 2) + (r & 3);
70
+ r = (r >> 2) + (r & 3);
71
+ return r - (3 * (r >> 1));
72
+ }
73
+ static int32_t mod3_leq8(uint8_t t) {
74
+ int32_t r;
75
+ r = (t >> 2) + (t & 3);
76
+ r = (r >> 2) + (r & 3);
77
+ return r - (3 * (r >> 1));
78
+ }
79
+ unsigned int rej_eta(int32_t *a, unsigned int len, const uint8_t *buf,
80
+ unsigned int buflen) {
81
+ unsigned int ctr, pos;
82
+
83
+ ctr = pos = 0;
84
+ while (ctr < len && pos < buflen) {
85
+ uint32_t t = buf[pos++];
86
+ if (t < 243) {
87
+ // reduce mod 3
88
+ a[ctr++] = mod3(t);
89
+
90
+ if (ctr >= len)
91
+ break;
92
+
93
+ t *= 171; // 171*3 = 1 mod 256
94
+ t >>= 9;
95
+ a[ctr++] = mod3(t);
96
+
97
+ if (ctr >= len)
98
+ break;
99
+
100
+ t *= 171;
101
+ t >>= 9;
102
+ a[ctr++] = mod3_leq26(t);
103
+
104
+ if (ctr >= len)
105
+ break;
106
+
107
+ t *= 171;
108
+ t >>= 9;
109
+ a[ctr++] = mod3_leq8(t);
110
+
111
+ if (ctr >= len)
112
+ break;
113
+
114
+ t *= 171;
115
+ t >>= 9;
116
+ a[ctr++] = (int32_t)t - (int32_t)3 * (t >> 1);
117
+ }
118
+ }
119
+ return ctr;
120
+ }
121
+
122
+ static uint64_t approx_exp(const uint64_t x) {
123
+ int64_t result;
124
+ result = -0x0000B6C6340925AELL;
125
+ result = ((smulh48(result, x) + (1LL << 2)) >> 3) + 0x0000B4BD4DF85227LL;
126
+ result = ((smulh48(result, x) + (1LL << 2)) >> 3) - 0x0000887F727491E2LL;
127
+ result = ((smulh48(result, x) + (1LL << 1)) >> 2) + 0x0000AAAA643C7E8DLL;
128
+ result = ((smulh48(result, x) + (1LL << 1)) >> 2) - 0x0000AAAAA98179E6LL;
129
+ result = ((smulh48(result, x) + 1LL) >> 1) + 0x0000FFFFFFFB2E7ALL;
130
+ result = ((smulh48(result, x) + 1LL) >> 1) - 0x0000FFFFFFFFF85FLL;
131
+ result = ((smulh48(result, x))) + 0x0000FFFFFFFFFFFCLL;
132
+ return result;
133
+ }
134
+
135
+ #define CDTLEN 64
136
+ static const uint32_t CDT[CDTLEN] = {
137
+ 3266, 6520, 9748, 12938, 16079, 19159, 22168, 25096, 27934, 30674, 33309,
138
+ 35833, 38241, 40531, 42698, 44742, 46663, 48460, 50135, 51690, 53128, 54454,
139
+ 55670, 56781, 57794, 58712, 59541, 60287, 60956, 61554, 62085, 62556, 62972,
140
+ 63337, 63657, 63936, 64178, 64388, 64569, 64724, 64857, 64970, 65066, 65148,
141
+ 65216, 65273, 65321, 65361, 65394, 65422, 65444, 65463, 65478, 65490, 65500,
142
+ 65508, 65514, 65519, 65523, 65527, 65529, 65531, 65533, 65534};
143
+
144
+ /*************************************************
145
+ * Name: sample_gauss16
146
+ *
147
+ * Description: sample gauss using 16 bits integer
148
+ *
149
+ * Arguments: - const uint64_t rand16: input 16 bits integer
150
+ *
151
+ * Specification: Implements Algorithm 15, SampleGauss16.
152
+ **************************************************/
153
+ static uint64_t sample_gauss16(const uint64_t rand16) {
154
+ unsigned int i;
155
+ uint64_t r = 0;
156
+ for (i = 0; i < CDTLEN; i++) {
157
+ r += (((uint64_t)CDT[i] - rand16) >> 63) & 1;
158
+ }
159
+ return r;
160
+ }
161
+
162
+ /*************************************************
163
+ * Name: sample_gauss_sigma76
164
+ *
165
+ * Description: sample gauss with sigma 76
166
+ *
167
+ * Arguments: - uint64_t *r: pointer to output integer
168
+ * - fp96_76 *sqr: pointer to output fixed point
169
+ * - const uint8_t rand[]: pointer to input integer
170
+ *
171
+ * Specification: Implements Algorithm 14, SampleGaussSigma76.
172
+ **************************************************/
173
+ #define GAUSS_RAND (72 + 16 + 48)
174
+ #define GAUSS_RAND_BYTES ((GAUSS_RAND + 7) / 8) // 17
175
+ static int sample_gauss_sigma76(uint64_t *r, fp96_76 *sqr,
176
+ const uint8_t rand[GAUSS_RAND_BYTES]) {
177
+ const uint64_t rand_gauss16 = rand[0] | (((uint64_t)rand[1]) << 8);
178
+ const uint64_t rand_rej =
179
+ rand[2] | (((uint64_t)rand[3]) << 8) | (((uint64_t)rand[4]) << 16) |
180
+ (((uint64_t)rand[5]) << 24) | (((uint64_t)rand[6]) << 32) |
181
+ (((uint64_t)rand[7]) << 40);
182
+ uint64_t x, exp_in;
183
+ fp96_76 y;
184
+
185
+ // sample x
186
+ x = sample_gauss16(rand_gauss16);
187
+
188
+ // y := append x to y
189
+ // leave 16 bit for carries
190
+ y.limb48[0] = rand[8] | ((uint64_t)rand[9] << 8) |
191
+ ((uint64_t)rand[10] << 16) | ((uint64_t)rand[11] << 24) |
192
+ ((uint64_t)rand[12] << 32) | ((uint64_t)rand[13] << 40);
193
+ y.limb48[1] = rand[14] | ((uint64_t)rand[15] << 8) |
194
+ ((uint64_t)rand[16] << 16) | (x << 24);
195
+
196
+ // r := round y
197
+ *r = (y.limb48[0] >> 15) ^ (y.limb48[1] << 33);
198
+ *r += 1; // rounding
199
+ *r >>= 1;
200
+
201
+ // sqr := y*y
202
+ fixpoint_square(sqr, &y);
203
+
204
+ // sqr[1] = y^2 >> (76+48) // 34 bit
205
+ // sqr[0] = (y^2 >> 76) & ((1UL<<48)-1) // 48 bit
206
+ // exp_in := sqr - ((x*x) << 68)
207
+ exp_in = sqr->limb48[1] - ((x * x) << (68 - 48));
208
+ exp_in <<= 20;
209
+ exp_in |= sqr->limb48[0] >> 28;
210
+ exp_in += 1; // rounding
211
+ exp_in >>= 1;
212
+
213
+ return ((((int64_t)(rand_rej ^
214
+ (rand_rej & 1)) // set lowest bit to zero in order to
215
+ // use it for rejection if sample==0
216
+ - (int64_t)approx_exp(exp_in)) >>
217
+ 63) // reject with prob 1-approx_exp(exp_in)
218
+ & (((*r | -*r) >> 63) | rand_rej)) &
219
+ 1; // if the sample is zero, clear the return value with prob 1/2
220
+ }
221
+
222
+ /*************************************************
223
+ * Name: sample_gauss
224
+ *
225
+ * Description: sample gauss using smaple_gauss_sigma76
226
+ *
227
+ * Arguments: - uint64_t *r: pointer to output integer array
228
+ * - fp96_76 *sqsum: pointer to output fixed point
229
+ * - const uint8_t *buf: pointer to input byte array
230
+ * - size_t buflen: length of input byte array
231
+ * - size_t len: max length of samples
232
+ * - int dont_write_last: flag
233
+ *
234
+ * Specification: Implements Algorithm 13, SampleGauss.
235
+ **************************************************/
236
+ int sample_gauss(uint64_t *r, fp96_76 *sqsum, const uint8_t *buf, size_t buflen,
237
+ size_t len, int dont_write_last) {
238
+ const uint8_t *pos = buf;
239
+ fp96_76 sqr;
240
+ size_t bytecnt = buflen, coefcnt = 0;
241
+ int accepted;
242
+ uint64_t dummy;
243
+
244
+ while (coefcnt < len) {
245
+ if (bytecnt < GAUSS_RAND_BYTES) {
246
+ renormalize(sqsum);
247
+ return coefcnt;
248
+ }
249
+
250
+ if (dont_write_last && coefcnt == len - 1) {
251
+ accepted = sample_gauss_sigma76(&dummy, &sqr, pos);
252
+ } else {
253
+ accepted = sample_gauss_sigma76(&r[coefcnt], &sqr, pos);
254
+ }
255
+ coefcnt += accepted;
256
+ pos += GAUSS_RAND_BYTES;
257
+ bytecnt -= GAUSS_RAND_BYTES;
258
+
259
+ sqsum->limb48[0] += sqr.limb48[0] & -(int64_t)accepted;
260
+ sqsum->limb48[1] += sqr.limb48[1] & -(int64_t)accepted;
261
+ }
262
+
263
+ renormalize(sqsum);
264
+ return len;
265
+ }
266
+
267
+ /*************************************************
268
+ * Name: sample_gauss_N
269
+ *
270
+ * Description: sample gauss
271
+ *
272
+ * Arguments: - uint64_t *r: pointer to output integer array
273
+ * - uint8_t *signs: pointer to output byte array
274
+ * - fp96_76 *sqsum: pointer to output fixed point
275
+ * - const uint8_t seed[]: pointer to input seed
276
+ * - uint16_t nonce: input nonce
277
+ * - size_t len: number of samples
278
+ *
279
+ * Specification: Implements Algorithm 12, SampleGaussN.
280
+ **************************************************/
281
+ #define POLY_HYPERBALL_BUFLEN (GAUSS_RAND_BYTES * HAETAE_N)
282
+ #define POLY_HYPERBALL_NBLOCKS \
283
+ ((POLY_HYPERBALL_BUFLEN + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES)
284
+ void sample_gauss_N(uint64_t *r, uint8_t *signs, fp96_76 *sqsum,
285
+ const uint8_t seed[HAETAE_CRHBYTES], uint16_t nonce,
286
+ size_t len) {
287
+ uint8_t buf[POLY_HYPERBALL_NBLOCKS * STREAM256_BLOCKBYTES];
288
+ size_t bytecnt, coefcnt, firstflag = 1;
289
+ stream256_state state;
290
+ stream256_init(&state, seed, nonce);
291
+
292
+ stream256_squeezeblocks(buf, POLY_HYPERBALL_NBLOCKS, &state);
293
+ for (size_t i = 0; i < len / 8; i++) {
294
+ signs[i] = buf[i];
295
+ }
296
+ bytecnt = POLY_HYPERBALL_NBLOCKS * STREAM256_BLOCKBYTES - len / 8;
297
+ coefcnt = sample_gauss(r, sqsum, buf + len / 8, bytecnt, len, len % HAETAE_N);
298
+ while (coefcnt < len) {
299
+ size_t off = bytecnt % GAUSS_RAND_BYTES;
300
+ for (size_t i = 0; i < off; i++) {
301
+ buf[i] = buf[bytecnt + len / 8 * firstflag - off + i];
302
+ }
303
+ stream256_squeezeblocks(buf + off, 1, &state);
304
+ bytecnt = STREAM256_BLOCKBYTES + off;
305
+
306
+ coefcnt += sample_gauss(r + coefcnt, sqsum, buf, bytecnt, len - coefcnt,
307
+ len % HAETAE_N);
308
+ firstflag = 0;
309
+ }
310
+ }