kpqc 0.1.0 → 0.2.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Gemfile +4 -0
  4. data/README.md +9 -6
  5. data/THIRD_PARTY_NOTICES.md +14 -47
  6. data/ext/kpqc/extconf_helper.rb +6 -3
  7. data/ext/kpqc/secure_clear.c +8 -0
  8. data/kpqc.gemspec +4 -5
  9. data/lib/kpqc/aimer.rb +6 -6
  10. data/lib/kpqc/version.rb +1 -2
  11. data/test/kat/aimer128f.rsp +4 -4
  12. data/test/kat/aimer128s.rsp +4 -4
  13. data/test/kat/aimer192f.rsp +4 -4
  14. data/test/kat/aimer192s.rsp +4 -4
  15. data/test/kat/aimer256f.rsp +4 -4
  16. data/test/kat/aimer256s.rsp +4 -4
  17. data/test/kat/haetae2.rsp +1 -1
  18. data/test/kat/haetae3.rsp +1 -1
  19. data/test/kat/haetae5.rsp +1 -1
  20. data/vendor/AIMer/LICENSE +1 -1
  21. data/vendor/AIMer/aim3.c +227 -0
  22. data/vendor/AIMer/aim3.h +63 -0
  23. data/vendor/AIMer/field.h +12 -4
  24. data/vendor/AIMer/field128.c +24 -381
  25. data/vendor/AIMer/field192.c +24 -400
  26. data/vendor/AIMer/field256.c +28 -447
  27. data/vendor/AIMer/field_common.c +98 -0
  28. data/vendor/AIMer/field_internal.h +218 -0
  29. data/vendor/AIMer/params/params-aimer-128f.h +8 -8
  30. data/vendor/AIMer/params/params-aimer-128s.h +8 -8
  31. data/vendor/AIMer/params/params-aimer-192f.h +8 -8
  32. data/vendor/AIMer/params/params-aimer-192s.h +8 -8
  33. data/vendor/AIMer/params/params-aimer-256f.h +8 -8
  34. data/vendor/AIMer/params/params-aimer-256s.h +8 -8
  35. data/vendor/AIMer/params.h +5 -0
  36. data/vendor/AIMer/sign.c +246 -167
  37. data/vendor/AIMer/sign.h +6 -6
  38. data/vendor/AIMer/tree.c +10 -4
  39. data/vendor/AIMer/tree.h +1 -1
  40. data/vendor/HAETAE/include/fixpoint.h +14 -14
  41. data/vendor/HAETAE/include/rans_byte.h +10 -9
  42. data/vendor/HAETAE/src/decompose.c +8 -4
  43. data/vendor/HAETAE/src/encoding.c +5 -5
  44. data/vendor/HAETAE/src/fft.c +1 -1
  45. data/vendor/HAETAE/src/fips202.c +26 -14
  46. data/vendor/HAETAE/src/fixpoint.c +21 -18
  47. data/vendor/HAETAE/src/ntt.c +2 -0
  48. data/vendor/HAETAE/src/packing.c +15 -15
  49. data/vendor/HAETAE/src/poly.c +30 -3
  50. data/vendor/HAETAE/src/polyfix.c +2 -2
  51. data/vendor/HAETAE/src/polymat.c +2 -2
  52. data/vendor/HAETAE/src/polyvec.c +7 -5
  53. data/vendor/HAETAE/src/reduce.c +2 -0
  54. data/vendor/HAETAE/src/sampler.c +231 -47
  55. data/vendor/HAETAE/src/sign.c +11 -10
  56. data/vendor/NTRUplus/NTRU+1152/api.h +27 -8
  57. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +12 -269
  58. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +4 -113
  59. data/vendor/NTRUplus/NTRU+1152/kem.c +110 -40
  60. data/vendor/NTRUplus/NTRU+1152/ntt.c +50 -54
  61. data/vendor/NTRUplus/NTRU+1152/poly.c +21 -13
  62. data/vendor/NTRUplus/NTRU+1152/poly.h +3 -3
  63. data/vendor/NTRUplus/NTRU+1152/randombytes.h +1 -0
  64. data/vendor/NTRUplus/NTRU+1152/symmetric.c +3 -9
  65. data/vendor/NTRUplus/NTRU+1152/symmetric.h +13 -3
  66. data/vendor/NTRUplus/NTRU+1152/util.h +15 -0
  67. data/vendor/NTRUplus/NTRU+768/api.h +27 -8
  68. data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +12 -269
  69. data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +4 -113
  70. data/vendor/NTRUplus/NTRU+768/kem.c +110 -40
  71. data/vendor/NTRUplus/NTRU+768/ntt.c +50 -54
  72. data/vendor/NTRUplus/NTRU+768/poly.c +23 -13
  73. data/vendor/NTRUplus/NTRU+768/poly.h +3 -3
  74. data/vendor/NTRUplus/NTRU+768/randombytes.h +1 -0
  75. data/vendor/NTRUplus/NTRU+768/symmetric.c +3 -9
  76. data/vendor/NTRUplus/NTRU+768/symmetric.h +13 -3
  77. data/vendor/NTRUplus/NTRU+768/util.h +15 -0
  78. data/vendor/NTRUplus/NTRU+864/api.h +27 -8
  79. data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +12 -269
  80. data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +4 -113
  81. data/vendor/NTRUplus/NTRU+864/kem.c +110 -40
  82. data/vendor/NTRUplus/NTRU+864/ntt.c +24 -28
  83. data/vendor/NTRUplus/NTRU+864/poly.c +26 -12
  84. data/vendor/NTRUplus/NTRU+864/poly.h +3 -3
  85. data/vendor/NTRUplus/NTRU+864/randombytes.h +1 -0
  86. data/vendor/NTRUplus/NTRU+864/symmetric.c +3 -9
  87. data/vendor/NTRUplus/NTRU+864/symmetric.h +13 -3
  88. data/vendor/NTRUplus/NTRU+864/util.h +15 -0
  89. data/vendor/SMAUG-T/src/cbd.c +4 -4
  90. data/vendor/SMAUG-T/src/ciphertext.c +2 -2
  91. data/vendor/SMAUG-T/src/dg.c +2 -2
  92. data/vendor/SMAUG-T/src/hwt.c +4 -4
  93. data/vendor/SMAUG-T/src/indcpa.c +5 -5
  94. data/vendor/SMAUG-T/src/kem.c +9 -7
  95. data/vendor/SMAUG-T/src/key.c +2 -2
  96. data/vendor/SMAUG-T/src/pack.c +8 -8
  97. metadata +17 -42
  98. data/vendor/AIMer/aim2.c +0 -163
  99. data/vendor/AIMer/aim2.h +0 -36
  100. data/vendor/AIMer/aim2_constant.h +0 -74
  101. data/vendor/SOURCES.json +0 -130
@@ -181,7 +181,7 @@ void poly_lsb(poly *a0, const poly *a) {
181
181
  * HAETAE_SEEDBYTES
182
182
  * - uint16_t nonce: 2-byte nonce
183
183
  *
184
- * Specification: Implements Algorithm 6, PolyUniform.
184
+ * Specification: Implements @[Algorithm 8, PolyUniform]
185
185
  **************************************************/
186
186
  #define POLY_UNIFORM_NBLOCKS \
187
187
  ((512 + STREAM128_BLOCKBYTES - 1) / STREAM128_BLOCKBYTES)
@@ -222,7 +222,7 @@ void poly_uniform(poly *a, const uint8_t seed[HAETAE_SEEDBYTES],
222
222
  * HAETAE_CRHBYTES
223
223
  * - uint16_t nonce: 2-byte nonce
224
224
  *
225
- * Specification: Implements Algorithm 9, PolyUniformEta.
225
+ * Specification: Implements @[Algorithm 11, PolyUniformEta]
226
226
  **************************************************/
227
227
  #define POLY_UNIFORM_ETA_NBLOCKS \
228
228
  ((136 + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES) // 1
@@ -263,7 +263,7 @@ uint8_t hammingWeight_8(uint8_t x) {
263
263
  * - const uint8_t highbits_lsb[]: packed highbits and lsb
264
264
  * - const uint8_t mu[]: hash of vk and message
265
265
  *
266
- * Specification: Implements Algorithm 16, SampleChallenge.
266
+ * Specification: Implements @[Algorithm 18, SampleChallenge]
267
267
  **************************************************/
268
268
  void poly_challenge(
269
269
  poly *c,
@@ -345,6 +345,20 @@ void poly_decomposed_unpack(poly *a, const uint8_t *buf) {
345
345
  }
346
346
  }
347
347
 
348
+ /*************************************************
349
+ * Name: poly_fromcrt
350
+ *
351
+ * Description: Compute coefficient-wise inverse CRT from the "mod q"
352
+ * polynomial u and the "mod 2" polynomial v: if the LSBs of the
353
+ * two coefficients agree, keep the "mod q" coefficient, otherwise
354
+ * add q. Output coefficients lie in [0, 2q-1].
355
+ *
356
+ * Arguments: - poly *w: pointer to output polynomial
357
+ * - const poly *u: pointer to input polynomial ("mod q")
358
+ * - const poly *v: pointer to input polynomial ("mod 2")
359
+ *
360
+ * Specification: Implements @[Algorithm 4, poly_fromcrt]
361
+ **************************************************/
348
362
  void poly_fromcrt(poly *w, const poly *u, const poly *v) {
349
363
  unsigned int i;
350
364
  int32_t xq, x2;
@@ -356,6 +370,19 @@ void poly_fromcrt(poly *w, const poly *u, const poly *v) {
356
370
  }
357
371
  }
358
372
 
373
+ /*************************************************
374
+ * Name: poly_fromcrt0
375
+ *
376
+ * Description: Compute coefficient-wise inverse CRT from the "mod q"
377
+ * polynomial u, assuming the "mod 2" polynomial is zero: if the
378
+ * LSB of a coefficient is zero, keep it, otherwise add q. Output
379
+ * coefficients lie in [0, 2q-1].
380
+ *
381
+ * Arguments: - poly *w: pointer to output polynomial
382
+ * - const poly *u: pointer to input polynomial ("mod q")
383
+ *
384
+ * Specification: Implements @[Algorithm 5, poly_fromcrt0]
385
+ **************************************************/
359
386
  void poly_fromcrt0(poly *w, const poly *u) {
360
387
  unsigned int i;
361
388
  int32_t xq;
@@ -234,7 +234,7 @@ uint64_t polyfixveclk_sqnorm2(const polyfixvecl *a, const polyfixveck *b) {
234
234
  * - uint8_t seed[HAETAE_CRHBYTES]: input seed bytes
235
235
  * - const uint16_t nonce: input nonce
236
236
  *
237
- * Specification: Implements Algorithm 11, SampleHyperBall.
237
+ * Specification: Implements @[Algorithm 13, SampleHyperball]
238
238
  **************************************************/
239
239
  uint16_t polyfixveclk_sample_hyperball(polyfixvecl *y1, polyfixveck *y2,
240
240
  uint8_t *b,
@@ -264,7 +264,7 @@ uint16_t polyfixveclk_sample_hyperball(polyfixvecl *y1, polyfixveck *y2,
264
264
  sqsum.limb48[0] += (sqsum.limb48[1] & 1) << 47;
265
265
  sqsum.limb48[1] >>= 1;
266
266
  sqsum.limb48[1] += sqsum.limb48[0] >> 48;
267
- sqsum.limb48[0] &= (1ULL << 48) - 1;
267
+ sqsum.limb48[0] &= (UINT64_C(1) << 48) - 1;
268
268
  fixpoint_newton_invsqrt(&invsqrt, &sqsum);
269
269
  fixpoint_mul_high(&sqsum, &invsqrt,
270
270
  (uint64_t)(HAETAE_B0 * HAETAE_LN + HAETAE_SQNM / 2)
@@ -18,7 +18,7 @@
18
18
  * Arguments: - polyvecm mat[HAETAE_K]: output matrix k \times m
19
19
  * - const uint8_t rho[]: byte array containing seed rho
20
20
  *
21
- * Specification: Implements Algorithm 4, ExpandMatA.
21
+ * Specification: Implements @[Algorithm 6, ExpandMatA]
22
22
  **************************************************/
23
23
  void polymatkl_expand_matA(polyvecl mat[HAETAE_K],
24
24
  const uint8_t rho[HAETAE_SEEDBYTES]) {
@@ -40,7 +40,7 @@ void polymatkl_expand_matA(polyvecl mat[HAETAE_K],
40
40
  * Arguments: - polyvecm mat[HAETAE_K]: output matrix k \times m
41
41
  * - const uint8_t rho[]: byte array containing seed rho
42
42
  *
43
- * Specification: Implements Algorithm 4, ExpandMatA.
43
+ * Specification: Implements @[Algorithm 6, ExpandMatA]
44
44
  **************************************************/
45
45
  void polymatkm_expand_matA(polyvecm mat[HAETAE_K],
46
46
  const uint8_t rho[HAETAE_SEEDBYTES]) {
@@ -117,7 +117,7 @@ void polyveck_freeze2q(polyveck *v) {
117
117
  * - const uint8_t seed[]: byte array with seed of length
118
118
  * HAETAE_SEEDBYTES
119
119
  *
120
- * Specification: Implements Algorithm 5, ExpandVec_a.
120
+ * Specification: Implements @[Algorithm 7, ExpandVeca]
121
121
  **************************************************/
122
122
  void polyveck_expand_vecA(polyveck *v, const uint8_t seed[HAETAE_SEEDBYTES]) {
123
123
  unsigned int i, nonce = (HAETAE_K << 8) + HAETAE_M;
@@ -138,7 +138,7 @@ void polyveck_expand_vecA(polyveck *v, const uint8_t seed[HAETAE_SEEDBYTES]) {
138
138
  * HAETAE_CRHBYTES
139
139
  * - uint16_t nonce: 2-byte nonce
140
140
  *
141
- * Specification: Implements Algorithm 8, ExpandS.
141
+ * Specification: Implements @[Algorithm 10, ExpandS]
142
142
  **************************************************/
143
143
  void polyvecmk_expand_S(polyvecm *u, polyveck *v,
144
144
  const uint8_t seed[HAETAE_CRHBYTES], uint16_t nonce) {
@@ -203,6 +203,8 @@ void polyveck_poly_pointwise_montgomery(polyveck *w, const polyveck *u,
203
203
  * - const polyveck *u: pointer to the input vector of polynomials
204
204
  * of length HAETAE_K
205
205
  * - const poly *v: pointer to the input polynomial ("mod 2")
206
+ *
207
+ * Specification: Implements @[Algorithm 3, iCRT]
206
208
  **************************************************/
207
209
  void polyveck_poly_fromcrt(polyveck *w, const polyveck *u, const poly *v) {
208
210
  unsigned int i;
@@ -451,7 +453,7 @@ void polyvecm_ntt(polyvecm *x) {
451
453
  * Arguments: - int32_t *x: pointer to first input/output integer
452
454
  * - int32_t *y: pointer to second input/output integer
453
455
  *
454
- * Specification: Implements Algorithm 44, minmax.
456
+ * Specification: Implements @[Algorithm 50, minmax]
455
457
  * **************************************************/
456
458
  static inline void minmax(int32_t *x, int32_t *y) // taken from djbsort
457
459
  {
@@ -475,7 +477,7 @@ static inline void minmax(int32_t *x, int32_t *y) // taken from djbsort
475
477
  *
476
478
  * Returns:
477
479
  *
478
- * Specification: Implements Algorithm 42, skSingularValue.
480
+ * Specification: Implements @[Algorithm 48, skSingularValue]
479
481
  **************************************************/
480
482
  int64_t polyvecmk_sk_singular_value(const polyvecm *s1, const polyveck *s2) {
481
483
  int32_t res = 0;
@@ -520,7 +522,7 @@ int64_t polyvecmk_sk_singular_value(const polyvecm *s1, const polyveck *s2) {
520
522
  for (size_t i = 0; i < HAETAE_N / HAETAE_TAU + 1; i++) {
521
523
  int32_t fac =
522
524
  ((min - bestm[i]) >>
523
- 31); // all-ones if bestm[i] != min
525
+ 31); // all-ones if bestm[i] != min (TODO: impl specific behaviour)
524
526
  fac = (fac & (HAETAE_TAU)) ^
525
527
  ((~fac) & (HAETAE_N % HAETAE_TAU)); // fac = HAETAE_TAU for all != min
526
528
  // and N%HAETAE_TAU for min
@@ -15,6 +15,8 @@
15
15
  * Arguments: - int64_t: finite field element a
16
16
  *
17
17
  * Returns r.
18
+ *
19
+ * Specification: Implements @[Algorithm 1, MontgomeryReduce]
18
20
  **************************************************/
19
21
  int32_t montgomery_reduce(int64_t a) {
20
22
  int32_t t;
@@ -20,7 +20,7 @@
20
20
  * Returns number of sampled coefficients. Can be smaller than len if not enough
21
21
  * random bytes were given.
22
22
  *
23
- * Specification: Implements Algorithm 7, RejUniform.
23
+ * Specification: Implements @[Algorithm 9, RejUniform]
24
24
  **************************************************/
25
25
  unsigned int rej_uniform(int32_t *a, unsigned int len, const uint8_t *buf,
26
26
  unsigned int buflen) {
@@ -53,7 +53,7 @@ unsigned int rej_uniform(int32_t *a, unsigned int len, const uint8_t *buf,
53
53
  * Returns number of sampled coefficients. Can be smaller than len if not enough
54
54
  * random bytes were given.
55
55
  *
56
- * Specification: Implements Algorithm 10, RejEta.
56
+ * Specification: Implements @[Algorithm 12, RejEta]
57
57
  **************************************************/
58
58
  static int32_t mod3(uint8_t t) {
59
59
  int32_t r;
@@ -119,43 +119,214 @@ unsigned int rej_eta(int32_t *a, unsigned int len, const uint8_t *buf,
119
119
  return ctr;
120
120
  }
121
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;
122
+ /*
123
+ * GALACTICS [Rossi23]: degree-10 polynomial P(z) for exp(-z), z = xi/2^48.
124
+ *
125
+ * The constant term c_0 is lifted by +1 unit (2^{-48}) to enforce the ceiling
126
+ * condition P_c(z) ≥ exp(-z) everywhere.
127
+ *
128
+ * GALACTICS rational coefficients c_k = integer * 2^{exponent}:
129
+ * c_0 = 1 * 2^0 (= 1 exactly)
130
+ * c_1 = -140737488355325 * 2^{-47}
131
+ * c_2 = 140737488354861 * 2^{-48}
132
+ * c_3 = -5864062013275 * 2^{-45}
133
+ * c_4 = 93824990983603 * 2^{-51}
134
+ * c_5 = -75059957176683 * 2^{-53}
135
+ * c_6 = 50039335827767 * 2^{-55}
136
+ * c_7 = -114346678051053 * 2^{-59}
137
+ * c_8 = 56962476261175 * 2^{-61}
138
+ * c_9 = -24365119391573 * 2^{-63}
139
+ * c_10 = 14645656383309 * 2^{-66}
140
+ *
141
+ * Integer coefficients c_k^int = ceil(c_k * 2^48):
142
+ * c_0^int = 281474976710657 [GALACTICS-C: 2^48+1; lifted by +1]
143
+ * c_1^int =-281474976710650 [exact]
144
+ * c_2^int = 140737488354861 [exact]
145
+ * c_3^int = -46912496106200 [exact]
146
+ * c_4^int = 11728123872951 [ceil(11728123872950.375)]
147
+ * c_5^int = -2345623661771 [ceil(-2345623661771.344)]
148
+ * c_6^int = 390932311155 [ceil(390932311154.430)]
149
+ * c_7^int = -55833338892 [ceil(-55833338892.116)]
150
+ * c_8^int = 6953427278 [ceil(6953427277.975)]
151
+ * c_9^int = -743564434 [ceil(-743564434.557)]
152
+ * c_10^int = 55868746 [ceil(55868745.359)]
153
+ */
154
+ static uint64_t approx_exp(const uint64_t xi) {
155
+ int64_t r = INT64_C(55868746); /* c_10^int */
156
+ r = smulh48(r, xi) - INT64_C(743564434); /* c_9^int */
157
+ r = smulh48(r, xi) + INT64_C(6953427278); /* c_8^int */
158
+ r = smulh48(r, xi) - INT64_C(55833338892); /* c_7^int */
159
+ r = smulh48(r, xi) + INT64_C(390932311155); /* c_6^int */
160
+ r = smulh48(r, xi) - INT64_C(2345623661771); /* c_5^int */
161
+ r = smulh48(r, xi) + INT64_C(11728123872951); /* c_4^int */
162
+ r = smulh48(r, xi) - INT64_C(46912496106200); /* c_3^int */
163
+ r = smulh48(r, xi) + INT64_C(140737488354861); /* c_2^int */
164
+ r = smulh48(r, xi) - INT64_C(281474976710650); /* c_1^int */
165
+ r = smulh48(r, xi) + INT64_C(281474976710657); /* c_0^int */
166
+ return (uint64_t)r;
133
167
  }
134
168
 
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};
169
+ #define CDTLEN 166
170
+ #define CDTHILEN 76
171
+
172
+ /*
173
+ * 83-bit CDT for D_{Z,16} half-Gaussian: rho(k) = exp(-k^2/512), k >= 0
174
+ * CDT83[k] = floor(CDF(k) * 2^83) where CDF(k) = sum_{j=0}^{k} rho(j)/Z_half
175
+ * Z_half = sum_{k=0}^{inf} exp(-k^2/512) = 20.5530...
176
+ * Split: CDT83_HI[k] = CDT83[k] >> 64 (upper 19 bits)
177
+ * CDT83_LO[k] = CDT83[k] & 0xFFFFFFFFFFFFFFFF (lower 64 bits)
178
+ */
179
+
180
+ static const uint32_t CDT83_HI[CDTHILEN] = {
181
+ UINT32_C(0x063a5), UINT32_C(0x0c718), UINT32_C(0x129f6), UINT32_C(0x18bdf),
182
+ UINT32_C(0x1ec73), UINT32_C(0x24b59), UINT32_C(0x2a83a), UINT32_C(0x302c6),
183
+ UINT32_C(0x35ab6), UINT32_C(0x3afc7), UINT32_C(0x401be), UINT32_C(0x4506a),
184
+ UINT32_C(0x49ba1), UINT32_C(0x4e343), UINT32_C(0x52736), UINT32_C(0x5676c),
185
+ UINT32_C(0x5a3dc), UINT32_C(0x5dc86), UINT32_C(0x61172), UINT32_C(0x642ad),
186
+ UINT32_C(0x6704c), UINT32_C(0x69a68), UINT32_C(0x6c120), UINT32_C(0x6e496),
187
+ UINT32_C(0x704ef), UINT32_C(0x72255), UINT32_C(0x73cf1), UINT32_C(0x754f0),
188
+ UINT32_C(0x76a7c), UINT32_C(0x77dc4), UINT32_C(0x78ef2), UINT32_C(0x79e32),
189
+ UINT32_C(0x7abaf), UINT32_C(0x7b78f), UINT32_C(0x7c1fb), UINT32_C(0x7cb17),
190
+ UINT32_C(0x7d304), UINT32_C(0x7d9e4), UINT32_C(0x7dfd4), UINT32_C(0x7e4f0),
191
+ UINT32_C(0x7e950), UINT32_C(0x7ed0d), UINT32_C(0x7f03b), UINT32_C(0x7f2ec),
192
+ UINT32_C(0x7f531), UINT32_C(0x7f71a), UINT32_C(0x7f8b3), UINT32_C(0x7fa08),
193
+ UINT32_C(0x7fb24), UINT32_C(0x7fc0e), UINT32_C(0x7fccf), UINT32_C(0x7fd6e),
194
+ UINT32_C(0x7fdf0), UINT32_C(0x7fe5a), UINT32_C(0x7feaf), UINT32_C(0x7fef5),
195
+ UINT32_C(0x7ff2c), UINT32_C(0x7ff59), UINT32_C(0x7ff7d), UINT32_C(0x7ff99),
196
+ UINT32_C(0x7ffb0), UINT32_C(0x7ffc2), UINT32_C(0x7ffd0), UINT32_C(0x7ffdb),
197
+ UINT32_C(0x7ffe3), UINT32_C(0x7ffea), UINT32_C(0x7ffef), UINT32_C(0x7fff3),
198
+ UINT32_C(0x7fff6), UINT32_C(0x7fff8), UINT32_C(0x7fffa), UINT32_C(0x7fffb),
199
+ UINT32_C(0x7fffd), UINT32_C(0x7fffd), UINT32_C(0x7fffe), UINT32_C(0x7fffe),
200
+ };
201
+
202
+ static const uint64_t CDT83_LO[CDTLEN] = {
203
+ UINT64_C(0x0aa572bc88db1e28), UINT64_C(0x4f3820e69064b2ee),
204
+ UINT64_C(0xd68dc44dd1418704), UINT64_C(0x6587a04d9b97b1dd),
205
+ UINT64_C(0x9b843ce0a65d0050), UINT64_C(0x02b62cb869003e7d),
206
+ UINT64_C(0x0d44f194f8bf43c6), UINT64_C(0xfaa0c7acb211b4db),
207
+ UINT64_C(0xa11387f7f524be80), UINT64_C(0x18526ca6f2ceb77f),
208
+ UINT64_C(0x42a01a906b7dad17), UINT64_C(0x32e5337a1966b9a7),
209
+ UINT64_C(0x6f00f7ac9735f58a), UINT64_C(0x0e6c48f40642ba60),
210
+ UINT64_C(0xb6192fa1afb5e4ec), UINT64_C(0x7339dba8ffc2fcf5),
211
+ UINT64_C(0x7746cbe1ac90c9eb), UINT64_C(0xb83004341d78466f),
212
+ UINT64_C(0x781dcca572bb3d8a), UINT64_C(0xb880376cc82a5384),
213
+ UINT64_C(0x9c68a5c477dfecb9), UINT64_C(0xbe45ceb02a25fef3),
214
+ UINT64_C(0x7d1a8ccd208dbaa1), UINT64_C(0x452c002b9085e7db),
215
+ UINT64_C(0xd7ef361c5551378d), UINT64_C(0x96b4ff49d9e5a8bb),
216
+ UINT64_C(0xd337c94ede732d83), UINT64_C(0x28c75b8d3fe83c38),
217
+ UINT64_C(0xe05d7bd130fe20e0), UINT64_C(0x6170e60b76d85108),
218
+ UINT64_C(0xb0e59892414901ff), UINT64_C(0xff05cf70b911f3de),
219
+ UINT64_C(0x4501460fdfd508c9), UINT64_C(0xf20b1303a2a54906),
220
+ UINT64_C(0xa7d3badbeb04b20c), UINT64_C(0x05ce666b741b666d),
221
+ UINT64_C(0x826e689fded20430), UINT64_C(0x5155d1354fcf6ff6),
222
+ UINT64_C(0x55469226a1d318f6), UINT64_C(0x1c8d3820cfa9cabc),
223
+ UINT64_C(0xe68d83bbf700fc40), UINT64_C(0xb1152d8944042803),
224
+ UINT64_C(0x4c1e741aabe53700), UINT64_C(0x72b94c56e0f9a967),
225
+ UINT64_C(0xe7e5a80a79e4539c), UINT64_C(0x9641c5d11feb4d12),
226
+ UINT64_C(0xb18b71598b73dde0), UINT64_C(0xd9112fb5a7904d7e),
227
+ UINT64_C(0x3a4f57cbefabc820), UINT64_C(0xb314025fd5022976),
228
+ UINT64_C(0xf2a2b228aab1981b), UINT64_C(0x996ce1e60378cd98),
229
+ UINT64_C(0x570ec64b38e3ca90), UINT64_C(0x0657269615dcd7c6),
230
+ UINT64_C(0xc7360038bdc85312), UINT64_C(0x167fa02a57a8ae1a),
231
+ UINT64_C(0xe380fab2ea9b2bef), UINT64_C(0xa36e6abd6509b5a2),
232
+ UINT64_C(0x62bfcf1d6ba81c37), UINT64_C(0xd4946e8bf96caa93),
233
+ UINT64_C(0x603e6262ea8cda2d), UINT64_C(0x2d18c8b333ae9203),
234
+ UINT64_C(0x2ccdedb5a7718d61), UINT64_C(0x24333ecab8497c0a),
235
+ UINT64_C(0xb2e06eb33bf2b7d9), UINT64_C(0x59a5f6c550dfe7e2),
236
+ UINT64_C(0x800548f3927f906e), UINT64_C(0x78cac146b573bc40),
237
+ UINT64_C(0x85e6dadec4b6aff1), UINT64_C(0xdba17dfa17def8ec),
238
+ UINT64_C(0xa33f84d06ce20a93), UINT64_C(0xfd2fe967c5186746),
239
+ UINT64_C(0x02d37ecd7e9b180f), UINT64_C(0xc7efafa8bd33f0bb),
240
+ UINT64_C(0x5bda826341e791cc), UINT64_C(0xca6c1c6ce045599f),
241
+ UINT64_C(0x1cc02c0faa9a526e), UINT64_C(0x59d002901a4a4e52),
242
+ UINT64_C(0x86ecbd139ce07540), UINT64_C(0xa81f9f15ffb47f4c),
243
+ UINT64_C(0xc075b17481687af0), UINT64_C(0xd23ad13e68301c65),
244
+ UINT64_C(0xdf27955fae1c84cb), UINT64_C(0xe884cdb07368c266),
245
+ UINT64_C(0xef46d4f897fc83f6), UINT64_C(0xf4227e46663ec049),
246
+ UINT64_C(0xf79d091c1b5aff07), UINT64_C(0xfa183c533c3890a6),
247
+ UINT64_C(0xfbdb8a602066b0f2), UINT64_C(0xfd1af06df3db86b7),
248
+ UINT64_C(0xfdfc1a818587e2aa), UINT64_C(0xfe9a37a348ac2a93),
249
+ UINT64_C(0xff08d0797970dbfe), UINT64_C(0xff55df73fd7a00bc),
250
+ UINT64_C(0xff8b5aa573bca5ce), UINT64_C(0xffb053c109f51681),
251
+ UINT64_C(0xffc9c9bd39a036ec), UINT64_C(0xffdb40bd4ee1f846),
252
+ UINT64_C(0xffe72fa859b20a4a), UINT64_C(0xffef4edda93d266d),
253
+ UINT64_C(0xfff4d07a9fb0d4e0), UINT64_C(0xfff88868ef31b1cc),
254
+ UINT64_C(0xfffb08c16a3f5f0c), UINT64_C(0xfffcb5d30be5cabf),
255
+ UINT64_C(0xfffdd43465d95fe6), UINT64_C(0xfffe929a538ad2fa),
256
+ UINT64_C(0xffff10b1c2119732), UINT64_C(0xffff63df8795a2c9),
257
+ UINT64_C(0xffff9a87a0a9f2af), UINT64_C(0xffffbe4df6f0f4a9),
258
+ UINT64_C(0xffffd5a10f204910), UINT64_C(0xffffe4c6f1668b32),
259
+ UINT64_C(0xffffee939680bfaf), UINT64_C(0xfffff4e4216290db),
260
+ UINT64_C(0xfffff8f1c044613e), UINT64_C(0xfffffb892dc2b174),
261
+ UINT64_C(0xfffffd2fb4188608), UINT64_C(0xfffffe3bc0a56eba),
262
+ UINT64_C(0xfffffee523b218c6), UINT64_C(0xffffff4fc31097e3),
263
+ UINT64_C(0xffffff929d76dbeb), UINT64_C(0xffffffbc5e7c0350),
264
+ UINT64_C(0xffffffd6586c6684), UINT64_C(0xffffffe6716865f7),
265
+ UINT64_C(0xfffffff0613c76e2), UINT64_C(0xfffffff67d62ab64),
266
+ UINT64_C(0xfffffffa3b6664c0), UINT64_C(0xfffffffc83e13d66),
267
+ UINT64_C(0xfffffffde713ef71), UINT64_C(0xfffffffebe18936f),
268
+ UINT64_C(0xffffffff3fbfc997), UINT64_C(0xffffffff8d9fa29a),
269
+ UINT64_C(0xffffffffbc372590), UINT64_C(0xffffffffd7fb7dfd),
270
+ UINT64_C(0xffffffffe87747f9), UINT64_C(0xfffffffff2368b89),
271
+ UINT64_C(0xfffffffff7f44d88), UINT64_C(0xfffffffffb52a49b),
272
+ UINT64_C(0xfffffffffd4a9ffb), UINT64_C(0xfffffffffe700579),
273
+ UINT64_C(0xffffffffff1a287f), UINT64_C(0xffffffffff7c6f06),
274
+ UINT64_C(0xffffffffffb4fa99), UINT64_C(0xffffffffffd56300),
275
+ UINT64_C(0xffffffffffe7e364), UINT64_C(0xfffffffffff268d7),
276
+ UINT64_C(0xfffffffffff85e8e), UINT64_C(0xfffffffffffbbb6f),
277
+ UINT64_C(0xfffffffffffd9f49), UINT64_C(0xfffffffffffeae2c),
278
+ UINT64_C(0xffffffffffff453d), UINT64_C(0xffffffffffff9928),
279
+ UINT64_C(0xffffffffffffc797), UINT64_C(0xffffffffffffe12f),
280
+ UINT64_C(0xffffffffffffef3c), UINT64_C(0xfffffffffffff6eb),
281
+ UINT64_C(0xfffffffffffffb1b), UINT64_C(0xfffffffffffffd60),
282
+ UINT64_C(0xfffffffffffffe9a), UINT64_C(0xffffffffffffff43),
283
+ UINT64_C(0xffffffffffffff9e), UINT64_C(0xffffffffffffffce),
284
+ UINT64_C(0xffffffffffffffe7), UINT64_C(0xfffffffffffffff4),
285
+ UINT64_C(0xfffffffffffffffb), UINT64_C(0xfffffffffffffffe),
286
+ };
143
287
 
144
288
  /*************************************************
145
- * Name: sample_gauss16
289
+ * Name: sample_gauss83
146
290
  *
147
- * Description: sample gauss using 16 bits integer
291
+ * Description: sample gauss using 83 bits integer (CDT with 83-bit precision)
148
292
  *
149
- * Arguments: - const uint64_t rand16: input 16 bits integer
293
+ * Arguments: - const uint64_t rand_lo: lower 64 bits of 83-bit random input
294
+ * - const uint32_t rand_hi: upper 19 bits of 83-bit random input
150
295
  *
151
- * Specification: Implements Algorithm 15, SampleGauss16.
296
+ * Returns: non-negative integer x sampled from D_{Z,16} half-distribution
297
+ *
298
+ * Specification: Implements @[Algorithm 17, SampleGauss83]
152
299
  **************************************************/
153
- static uint64_t sample_gauss16(const uint64_t rand16) {
300
+ static uint64_t sample_gauss83(const uint64_t rand_lo, const uint32_t rand_hi) {
154
301
  unsigned int i;
155
302
  uint64_t r = 0;
156
- for (i = 0; i < CDTLEN; i++) {
157
- r += (((uint64_t)CDT[i] - rand16) >> 63) & 1;
303
+
304
+ for (i = 0; i < CDTHILEN; i++) {
305
+ #ifdef __SIZEOF_INT128__
306
+ uint128 cdt = ((uint128)CDT83_HI[i] << 64) | CDT83_LO[i];
307
+ uint128 rnd = ((uint128)rand_hi << 64) | rand_lo;
308
+ r += (uint64_t)((cdt - rnd) >> 127);
309
+ #else
310
+ uint64_t borrow = (rand_lo > CDT83_LO[i]);
311
+ uint64_t hi_diff = (uint64_t)CDT83_HI[i] - rand_hi - borrow;
312
+ r += hi_diff >> 63;
313
+ #endif
158
314
  }
315
+
316
+ #ifdef __SIZEOF_INT128__
317
+ uint128 rnd = ((uint128)rand_hi << 64) | rand_lo;
318
+ for (i = CDTHILEN; i < CDTLEN; i++) {
319
+ uint128 cdt = ((uint128)UINT64_C(0x7ffff) << 64) | CDT83_LO[i];
320
+ r += (uint64_t)((cdt - rnd) >> 127);
321
+ }
322
+ #else
323
+ for (i = CDTHILEN; i < CDTLEN; i++) {
324
+ uint64_t borrow = (rand_lo > CDT83_LO[i]);
325
+ uint64_t hi_diff = (uint64_t)UINT64_C(0x7ffff) - rand_hi - borrow;
326
+ r += hi_diff >> 63;
327
+ }
328
+ #endif
329
+
159
330
  return r;
160
331
  }
161
332
 
@@ -168,41 +339,54 @@ static uint64_t sample_gauss16(const uint64_t rand16) {
168
339
  * - fp96_76 *sqr: pointer to output fixed point
169
340
  * - const uint8_t rand[]: pointer to input integer
170
341
  *
171
- * Specification: Implements Algorithm 14, SampleGaussSigma76.
342
+ * Specification: Implements @[Algorithm 16, SampleGaussSigma76]
172
343
  **************************************************/
173
- #define GAUSS_RAND (72 + 16 + 48)
174
- #define GAUSS_RAND_BYTES ((GAUSS_RAND + 7) / 8) // 17
344
+ #define GAUSS_RAND (72 + 83 + 48)
345
+ #define GAUSS_RAND_BYTES ((GAUSS_RAND + 7) / 8) // 26
175
346
  static int sample_gauss_sigma76(uint64_t *r, fp96_76 *sqr,
176
347
  const uint8_t rand[GAUSS_RAND_BYTES]) {
177
- const uint64_t rand_gauss16 = rand[0] | (((uint64_t)rand[1]) << 8);
348
+ // rand[0..10]: 83-bit CDT random (rand_gauss83)
349
+ // rand[11..16]: 48-bit rejection random (rand_rej)
350
+ // rand[17..25]: 72-bit y noise
351
+ const uint64_t rand_gauss83_lo =
352
+ rand[0] | (((uint64_t)rand[1]) << 8) | (((uint64_t)rand[2]) << 16) |
353
+ (((uint64_t)rand[3]) << 24) | (((uint64_t)rand[4]) << 32) |
354
+ (((uint64_t)rand[5]) << 40) | (((uint64_t)rand[6]) << 48) |
355
+ (((uint64_t)rand[7]) << 56);
356
+ const uint32_t rand_gauss83_hi =
357
+ (rand[8] | (((uint32_t)rand[9]) << 8) | (((uint32_t)rand[10]) << 16)) &
358
+ UINT32_C(0x7FFFF); // mask to 19 bits
178
359
  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);
360
+ rand[11] | (((uint64_t)rand[12]) << 8) | (((uint64_t)rand[13]) << 16) |
361
+ (((uint64_t)rand[14]) << 24) | (((uint64_t)rand[15]) << 32) |
362
+ (((uint64_t)rand[16]) << 40);
182
363
  uint64_t x, exp_in;
183
364
  fp96_76 y;
184
365
 
185
366
  // sample x
186
- x = sample_gauss16(rand_gauss16);
367
+ x = sample_gauss83(rand_gauss83_lo, rand_gauss83_hi);
187
368
 
188
369
  // y := append x to y
189
370
  // 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);
371
+ y.limb48[0] = rand[17] | ((uint64_t)rand[18] << 8) |
372
+ ((uint64_t)rand[19] << 16) | ((uint64_t)rand[20] << 24) |
373
+ ((uint64_t)rand[21] << 32) | ((uint64_t)rand[22] << 40);
374
+ y.limb48[1] = rand[23] | ((uint64_t)rand[24] << 8) |
375
+ ((uint64_t)rand[25] << 16) | (x << 24);
195
376
 
196
377
  // r := round y
197
- *r = (y.limb48[0] >> 15) ^ (y.limb48[1] << 33);
198
- *r += 1; // rounding
199
- *r >>= 1;
378
+ // y.limb48[1] can be up to 166*2^24 < 2^32 (for x <= 165), so << 33 would
379
+ // overflow uint64_t for x >= 128. Split: lower bits round separately, then
380
+ // add upper bits via << 32 (safe since y.limb48[1] * 2^32 <= 166*2^56 <
381
+ // 2^64).
382
+ *r = ((y.limb48[0] >> 15) + 1) >> 1;
383
+ *r += y.limb48[1] << 32;
200
384
 
201
385
  // sqr := y*y
202
386
  fixpoint_square(sqr, &y);
203
387
 
204
388
  // sqr[1] = y^2 >> (76+48) // 34 bit
205
- // sqr[0] = (y^2 >> 76) & ((1UL<<48)-1) // 48 bit
389
+ // sqr[0] = (y^2 >> 76) & ((UINT64_C(1)<<48)-1) // 48 bit
206
390
  // exp_in := sqr - ((x*x) << 68)
207
391
  exp_in = sqr->limb48[1] - ((x * x) << (68 - 48));
208
392
  exp_in <<= 20;
@@ -231,7 +415,7 @@ static int sample_gauss_sigma76(uint64_t *r, fp96_76 *sqr,
231
415
  * - size_t len: max length of samples
232
416
  * - int dont_write_last: flag
233
417
  *
234
- * Specification: Implements Algorithm 13, SampleGauss.
418
+ * Specification: Implements @[Algorithm 15, SampleGauss]
235
419
  **************************************************/
236
420
  int sample_gauss(uint64_t *r, fp96_76 *sqsum, const uint8_t *buf, size_t buflen,
237
421
  size_t len, int dont_write_last) {
@@ -276,7 +460,7 @@ int sample_gauss(uint64_t *r, fp96_76 *sqsum, const uint8_t *buf, size_t buflen,
276
460
  * - uint16_t nonce: input nonce
277
461
  * - size_t len: number of samples
278
462
  *
279
- * Specification: Implements Algorithm 12, SampleGaussN.
463
+ * Specification: Implements @[Algorithm 14, SampleGaussN]
280
464
  **************************************************/
281
465
  #define POLY_HYPERBALL_BUFLEN (GAUSS_RAND_BYTES * HAETAE_N)
282
466
  #define POLY_HYPERBALL_NBLOCKS \
@@ -1,4 +1,3 @@
1
- /* kpqc-py: propagate OS entropy failures (2026-09-06). */
2
1
  // SPDX-License-Identifier: MIT
3
2
 
4
3
  #include "api.h"
@@ -29,7 +28,7 @@
29
28
  *
30
29
  * Returns 0 (success)
31
30
  *
32
- * Specification: Implements Algorithm 48, KeyGenInternal.
31
+ * Specification: Implements @[Algorithm 54, KeyGenInternal]
33
32
  **************************************************/
34
33
 
35
34
  int crypto_sign_keypair_internal(uint8_t *vk, uint8_t *sk,
@@ -135,13 +134,14 @@ reject:
135
134
  *
136
135
  * Returns 0 (success)
137
136
  *
138
- * Specification: Implements Algorithm 45, KeyGen.
137
+ * Specification: Implements @[Algorithm 51, KeyGen]
139
138
  **************************************************/
140
139
  int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
141
140
  int ret = 0;
142
141
  uint8_t seed[HAETAE_SEEDBYTES] = {0};
143
142
 
144
- if (randombytes(seed, HAETAE_SEEDBYTES) != 0) return -1;
143
+ if (randombytes(seed, HAETAE_SEEDBYTES) != 0)
144
+ return -1;
145
145
 
146
146
  ret = crypto_sign_keypair_internal(pk, sk, seed);
147
147
 
@@ -165,7 +165,7 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
165
165
  *
166
166
  * Returns 0 (success)
167
167
  *
168
- * Specification: Implements Algorithm 49, SignInternal.
168
+ * Specification: Implements @[Algorithm 55, SignInternal]
169
169
  **************************************************/
170
170
  int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
171
171
  const uint8_t *m, size_t mlen,
@@ -302,7 +302,7 @@ reject:
302
302
  polyveck_caddDQ2ALPHA(&h);
303
303
 
304
304
  /*------------------ Decompose(z1) and Pack signature -------------------*/
305
- polyvecl_lowbits(&lb_z1, &z1rnd);
305
+ polyvecl_lowbits(&lb_z1, &z1rnd); // TODO do this in one function together!
306
306
  polyvecl_highbits(&hb_z1, &z1rnd);
307
307
 
308
308
  if (pack_sig(sig, &c, &lb_z1, &hb_z1,
@@ -330,7 +330,7 @@ reject:
330
330
  *
331
331
  * Returns 0 (success)
332
332
  *
333
- * Specification: Implements Algorithm 46, Sign.
333
+ * Specification: Implements @[Algorithm 52, Sign]
334
334
  **************************************************/
335
335
  int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m,
336
336
  size_t mlen, const uint8_t *ctx, size_t ctxlen,
@@ -345,7 +345,8 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m,
345
345
  pre[0] = ctxlen;
346
346
  memcpy(pre + 1, ctx, ctxlen);
347
347
 
348
- if (randombytes(rnd, HAETAE_SEEDBYTES) != 0) return -1;
348
+ if (randombytes(rnd, HAETAE_SEEDBYTES) != 0)
349
+ return -1;
349
350
 
350
351
  return crypto_sign_signature_internal(sig, siglen, m, mlen, pre, 1 + ctxlen,
351
352
  rnd, sk);
@@ -396,7 +397,7 @@ int crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen,
396
397
  *
397
398
  * Returns 0 if signature could be verified correctly and -1 otherwise
398
399
  *
399
- * Specification: Implements Algorithm 50, VerifyInternal.
400
+ * Specification: Implements @[Algorithm 56, VerifyInternal]
400
401
  **************************************************/
401
402
  int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
402
403
  const uint8_t *m, size_t mlen,
@@ -500,7 +501,7 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
500
501
  *
501
502
  * Returns 0 if signature could be verified correctly and -1 otherwise
502
503
  *
503
- * Specification: Implements Algorithm 47, Verify.
504
+ * Specification: Implements @[Algorithm 53, Verify]
504
505
  **************************************************/
505
506
  int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m,
506
507
  size_t mlen, const uint8_t *ctx, size_t ctxlen,
@@ -3,6 +3,25 @@
3
3
 
4
4
  #include "params.h"
5
5
 
6
+ #ifndef NTRUPLUS_ABI_H
7
+ #define NTRUPLUS_ABI_H
8
+
9
+ #if defined(_MSC_VER)
10
+ #define NTRUPLUS_INTERNAL
11
+ #define NTRUPLUS_EXTERNAL
12
+ #define NTRUPLUS_SYSV
13
+ #elif defined(__MINGW32__) || defined(__MINGW64__)
14
+ #define NTRUPLUS_INTERNAL
15
+ #define NTRUPLUS_EXTERNAL __declspec(dllexport)
16
+ #define NTRUPLUS_SYSV __attribute__((sysv_abi))
17
+ #else
18
+ #define NTRUPLUS_INTERNAL __attribute__((visibility("hidden")))
19
+ #define NTRUPLUS_EXTERNAL __attribute__((visibility("default")))
20
+ #define NTRUPLUS_SYSV
21
+ #endif
22
+
23
+ #endif
24
+
6
25
  #define CRYPTO_SECRETKEYBYTES NTRUPLUS_SECRETKEYBYTES
7
26
  #define CRYPTO_PUBLICKEYBYTES NTRUPLUS_PUBLICKEYBYTES
8
27
  #define CRYPTO_CIPHERTEXTBYTES NTRUPLUS_CIPHERTEXTBYTES
@@ -10,15 +29,15 @@
10
29
 
11
30
  #define CRYPTO_ALGNAME NTRUPLUS_ALGNAME
12
31
 
13
- int crypto_kem_keypair(unsigned char *pk,
14
- unsigned char *sk);
32
+ NTRUPLUS_EXTERNAL int crypto_kem_keypair(unsigned char *pk,
33
+ unsigned char *sk);
15
34
 
16
- int crypto_kem_enc(unsigned char *ct,
17
- unsigned char *ss,
18
- const unsigned char *pk);
35
+ NTRUPLUS_EXTERNAL int crypto_kem_enc(unsigned char *ct,
36
+ unsigned char *ss,
37
+ const unsigned char *pk);
19
38
 
20
- int crypto_kem_dec(unsigned char *ss,
21
- const unsigned char *ct,
22
- const unsigned char *sk);
39
+ NTRUPLUS_EXTERNAL int crypto_kem_dec(unsigned char *ss,
40
+ const unsigned char *ct,
41
+ const unsigned char *sk);
23
42
 
24
43
  #endif