ml_dsa 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 (86) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +104 -0
  3. data/LICENSE +14 -0
  4. data/LICENSE-APACHE +185 -0
  5. data/LICENSE-MIT +21 -0
  6. data/README.md +234 -0
  7. data/ext/ml_dsa/extconf.rb +47 -0
  8. data/ext/ml_dsa/fips202.c +933 -0
  9. data/ext/ml_dsa/fips202.h +166 -0
  10. data/ext/ml_dsa/ml-dsa-44/clean/api.h +52 -0
  11. data/ext/ml_dsa/ml-dsa-44/clean/ntt.c +98 -0
  12. data/ext/ml_dsa/ml-dsa-44/clean/ntt.h +10 -0
  13. data/ext/ml_dsa/ml-dsa-44/clean/packing.c +261 -0
  14. data/ext/ml_dsa/ml-dsa-44/clean/packing.h +31 -0
  15. data/ext/ml_dsa/ml-dsa-44/clean/params.h +44 -0
  16. data/ext/ml_dsa/ml-dsa-44/clean/poly.c +848 -0
  17. data/ext/ml_dsa/ml-dsa-44/clean/poly.h +52 -0
  18. data/ext/ml_dsa/ml-dsa-44/clean/polyvec.c +415 -0
  19. data/ext/ml_dsa/ml-dsa-44/clean/polyvec.h +65 -0
  20. data/ext/ml_dsa/ml-dsa-44/clean/reduce.c +69 -0
  21. data/ext/ml_dsa/ml-dsa-44/clean/reduce.h +17 -0
  22. data/ext/ml_dsa/ml-dsa-44/clean/rounding.c +98 -0
  23. data/ext/ml_dsa/ml-dsa-44/clean/rounding.h +14 -0
  24. data/ext/ml_dsa/ml-dsa-44/clean/sign.c +417 -0
  25. data/ext/ml_dsa/ml-dsa-44/clean/sign.h +49 -0
  26. data/ext/ml_dsa/ml-dsa-44/clean/symmetric-shake.c +26 -0
  27. data/ext/ml_dsa/ml-dsa-44/clean/symmetric.h +34 -0
  28. data/ext/ml_dsa/ml-dsa-65/clean/api.h +52 -0
  29. data/ext/ml_dsa/ml-dsa-65/clean/ntt.c +98 -0
  30. data/ext/ml_dsa/ml-dsa-65/clean/ntt.h +10 -0
  31. data/ext/ml_dsa/ml-dsa-65/clean/packing.c +261 -0
  32. data/ext/ml_dsa/ml-dsa-65/clean/packing.h +31 -0
  33. data/ext/ml_dsa/ml-dsa-65/clean/params.h +44 -0
  34. data/ext/ml_dsa/ml-dsa-65/clean/poly.c +799 -0
  35. data/ext/ml_dsa/ml-dsa-65/clean/poly.h +52 -0
  36. data/ext/ml_dsa/ml-dsa-65/clean/polyvec.c +415 -0
  37. data/ext/ml_dsa/ml-dsa-65/clean/polyvec.h +65 -0
  38. data/ext/ml_dsa/ml-dsa-65/clean/reduce.c +69 -0
  39. data/ext/ml_dsa/ml-dsa-65/clean/reduce.h +17 -0
  40. data/ext/ml_dsa/ml-dsa-65/clean/rounding.c +92 -0
  41. data/ext/ml_dsa/ml-dsa-65/clean/rounding.h +14 -0
  42. data/ext/ml_dsa/ml-dsa-65/clean/sign.c +415 -0
  43. data/ext/ml_dsa/ml-dsa-65/clean/sign.h +49 -0
  44. data/ext/ml_dsa/ml-dsa-65/clean/symmetric-shake.c +26 -0
  45. data/ext/ml_dsa/ml-dsa-65/clean/symmetric.h +34 -0
  46. data/ext/ml_dsa/ml-dsa-87/clean/api.h +52 -0
  47. data/ext/ml_dsa/ml-dsa-87/clean/ntt.c +98 -0
  48. data/ext/ml_dsa/ml-dsa-87/clean/ntt.h +10 -0
  49. data/ext/ml_dsa/ml-dsa-87/clean/packing.c +261 -0
  50. data/ext/ml_dsa/ml-dsa-87/clean/packing.h +31 -0
  51. data/ext/ml_dsa/ml-dsa-87/clean/params.h +44 -0
  52. data/ext/ml_dsa/ml-dsa-87/clean/poly.c +823 -0
  53. data/ext/ml_dsa/ml-dsa-87/clean/poly.h +52 -0
  54. data/ext/ml_dsa/ml-dsa-87/clean/polyvec.c +415 -0
  55. data/ext/ml_dsa/ml-dsa-87/clean/polyvec.h +65 -0
  56. data/ext/ml_dsa/ml-dsa-87/clean/reduce.c +69 -0
  57. data/ext/ml_dsa/ml-dsa-87/clean/reduce.h +17 -0
  58. data/ext/ml_dsa/ml-dsa-87/clean/rounding.c +92 -0
  59. data/ext/ml_dsa/ml-dsa-87/clean/rounding.h +14 -0
  60. data/ext/ml_dsa/ml-dsa-87/clean/sign.c +415 -0
  61. data/ext/ml_dsa/ml-dsa-87/clean/sign.h +49 -0
  62. data/ext/ml_dsa/ml-dsa-87/clean/symmetric-shake.c +26 -0
  63. data/ext/ml_dsa/ml-dsa-87/clean/symmetric.h +34 -0
  64. data/ext/ml_dsa/ml_dsa_44_impl.c +10 -0
  65. data/ext/ml_dsa/ml_dsa_65_impl.c +10 -0
  66. data/ext/ml_dsa/ml_dsa_87_impl.c +10 -0
  67. data/ext/ml_dsa/ml_dsa_ext.c +1360 -0
  68. data/ext/ml_dsa/ml_dsa_impl_template.h +35 -0
  69. data/ext/ml_dsa/ml_dsa_internal.h +188 -0
  70. data/ext/ml_dsa/randombytes.c +48 -0
  71. data/ext/ml_dsa/randombytes.h +15 -0
  72. data/lib/ml_dsa/batch_builder.rb +57 -0
  73. data/lib/ml_dsa/config.rb +69 -0
  74. data/lib/ml_dsa/internal.rb +76 -0
  75. data/lib/ml_dsa/key_pair.rb +39 -0
  76. data/lib/ml_dsa/parameter_set.rb +89 -0
  77. data/lib/ml_dsa/public_key.rb +180 -0
  78. data/lib/ml_dsa/requests.rb +96 -0
  79. data/lib/ml_dsa/secret_key.rb +221 -0
  80. data/lib/ml_dsa/version.rb +5 -0
  81. data/lib/ml_dsa.rb +277 -0
  82. data/patches/README.md +55 -0
  83. data/patches/pqclean-explicit-rnd.patch +64 -0
  84. data/sig/ml_dsa.rbs +178 -0
  85. data/test/fixtures/kat_vectors.yaml +16 -0
  86. metadata +194 -0
@@ -0,0 +1,52 @@
1
+ #ifndef PQCLEAN_MLDSA87_CLEAN_POLY_H
2
+ #define PQCLEAN_MLDSA87_CLEAN_POLY_H
3
+ #include "params.h"
4
+ #include <stdint.h>
5
+
6
+ typedef struct {
7
+ int32_t coeffs[N];
8
+ } poly;
9
+
10
+ void PQCLEAN_MLDSA87_CLEAN_poly_reduce(poly *a);
11
+ void PQCLEAN_MLDSA87_CLEAN_poly_caddq(poly *a);
12
+
13
+ void PQCLEAN_MLDSA87_CLEAN_poly_add(poly *c, const poly *a, const poly *b);
14
+ void PQCLEAN_MLDSA87_CLEAN_poly_sub(poly *c, const poly *a, const poly *b);
15
+ void PQCLEAN_MLDSA87_CLEAN_poly_shiftl(poly *a);
16
+
17
+ void PQCLEAN_MLDSA87_CLEAN_poly_ntt(poly *a);
18
+ void PQCLEAN_MLDSA87_CLEAN_poly_invntt_tomont(poly *a);
19
+ void PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(poly *c, const poly *a, const poly *b);
20
+
21
+ void PQCLEAN_MLDSA87_CLEAN_poly_power2round(poly *a1, poly *a0, const poly *a);
22
+ void PQCLEAN_MLDSA87_CLEAN_poly_decompose(poly *a1, poly *a0, const poly *a);
23
+ unsigned int PQCLEAN_MLDSA87_CLEAN_poly_make_hint(poly *h, const poly *a0, const poly *a1);
24
+ void PQCLEAN_MLDSA87_CLEAN_poly_use_hint(poly *b, const poly *a, const poly *h);
25
+
26
+ int PQCLEAN_MLDSA87_CLEAN_poly_chknorm(const poly *a, int32_t B);
27
+ void PQCLEAN_MLDSA87_CLEAN_poly_uniform(poly *a,
28
+ const uint8_t seed[SEEDBYTES],
29
+ uint16_t nonce);
30
+ void PQCLEAN_MLDSA87_CLEAN_poly_uniform_eta(poly *a,
31
+ const uint8_t seed[CRHBYTES],
32
+ uint16_t nonce);
33
+ void PQCLEAN_MLDSA87_CLEAN_poly_uniform_gamma1(poly *a,
34
+ const uint8_t seed[CRHBYTES],
35
+ uint16_t nonce);
36
+ void PQCLEAN_MLDSA87_CLEAN_poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]);
37
+
38
+ void PQCLEAN_MLDSA87_CLEAN_polyeta_pack(uint8_t *r, const poly *a);
39
+ void PQCLEAN_MLDSA87_CLEAN_polyeta_unpack(poly *r, const uint8_t *a);
40
+
41
+ void PQCLEAN_MLDSA87_CLEAN_polyt1_pack(uint8_t *r, const poly *a);
42
+ void PQCLEAN_MLDSA87_CLEAN_polyt1_unpack(poly *r, const uint8_t *a);
43
+
44
+ void PQCLEAN_MLDSA87_CLEAN_polyt0_pack(uint8_t *r, const poly *a);
45
+ void PQCLEAN_MLDSA87_CLEAN_polyt0_unpack(poly *r, const uint8_t *a);
46
+
47
+ void PQCLEAN_MLDSA87_CLEAN_polyz_pack(uint8_t *r, const poly *a);
48
+ void PQCLEAN_MLDSA87_CLEAN_polyz_unpack(poly *r, const uint8_t *a);
49
+
50
+ void PQCLEAN_MLDSA87_CLEAN_polyw1_pack(uint8_t *r, const poly *a);
51
+
52
+ #endif
@@ -0,0 +1,415 @@
1
+ #include "params.h"
2
+ #include "poly.h"
3
+ #include "polyvec.h"
4
+ #include <stdint.h>
5
+
6
+ /*************************************************
7
+ * Name: expand_mat
8
+ *
9
+ * Description: Implementation of ExpandA. Generates matrix A with uniformly
10
+ * random coefficients a_{i,j} by performing rejection
11
+ * sampling on the output stream of SHAKE128(rho|j|i)
12
+ *
13
+ * Arguments: - polyvecl mat[K]: output matrix
14
+ * - const uint8_t rho[]: byte array containing seed rho
15
+ **************************************************/
16
+ void PQCLEAN_MLDSA87_CLEAN_polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
17
+ unsigned int i, j;
18
+
19
+ for (i = 0; i < K; ++i) {
20
+ for (j = 0; j < L; ++j) {
21
+ PQCLEAN_MLDSA87_CLEAN_poly_uniform(&mat[i].vec[j], rho, (uint16_t) ((i << 8) + j));
22
+ }
23
+ }
24
+ }
25
+
26
+ void PQCLEAN_MLDSA87_CLEAN_polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v) {
27
+ unsigned int i;
28
+
29
+ for (i = 0; i < K; ++i) {
30
+ PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
31
+ }
32
+ }
33
+
34
+ /**************************************************************/
35
+ /************ Vectors of polynomials of length L **************/
36
+ /**************************************************************/
37
+
38
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
39
+ unsigned int i;
40
+
41
+ for (i = 0; i < L; ++i) {
42
+ PQCLEAN_MLDSA87_CLEAN_poly_uniform_eta(&v->vec[i], seed, nonce++);
43
+ }
44
+ }
45
+
46
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
47
+ unsigned int i;
48
+
49
+ for (i = 0; i < L; ++i) {
50
+ PQCLEAN_MLDSA87_CLEAN_poly_uniform_gamma1(&v->vec[i], seed, (uint16_t) (L * nonce + i));
51
+ }
52
+ }
53
+
54
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_reduce(polyvecl *v) {
55
+ unsigned int i;
56
+
57
+ for (i = 0; i < L; ++i) {
58
+ PQCLEAN_MLDSA87_CLEAN_poly_reduce(&v->vec[i]);
59
+ }
60
+ }
61
+
62
+ /*************************************************
63
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyvecl_add
64
+ *
65
+ * Description: Add vectors of polynomials of length L.
66
+ * No modular reduction is performed.
67
+ *
68
+ * Arguments: - polyvecl *w: pointer to output vector
69
+ * - const polyvecl *u: pointer to first summand
70
+ * - const polyvecl *v: pointer to second summand
71
+ **************************************************/
72
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) {
73
+ unsigned int i;
74
+
75
+ for (i = 0; i < L; ++i) {
76
+ PQCLEAN_MLDSA87_CLEAN_poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
77
+ }
78
+ }
79
+
80
+ /*************************************************
81
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyvecl_ntt
82
+ *
83
+ * Description: Forward NTT of all polynomials in vector of length L. Output
84
+ * coefficients can be up to 16*Q larger than input coefficients.
85
+ *
86
+ * Arguments: - polyvecl *v: pointer to input/output vector
87
+ **************************************************/
88
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_ntt(polyvecl *v) {
89
+ unsigned int i;
90
+
91
+ for (i = 0; i < L; ++i) {
92
+ PQCLEAN_MLDSA87_CLEAN_poly_ntt(&v->vec[i]);
93
+ }
94
+ }
95
+
96
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_invntt_tomont(polyvecl *v) {
97
+ unsigned int i;
98
+
99
+ for (i = 0; i < L; ++i) {
100
+ PQCLEAN_MLDSA87_CLEAN_poly_invntt_tomont(&v->vec[i]);
101
+ }
102
+ }
103
+
104
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v) {
105
+ unsigned int i;
106
+
107
+ for (i = 0; i < L; ++i) {
108
+ PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
109
+ }
110
+ }
111
+
112
+ /*************************************************
113
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_acc_montgomery
114
+ *
115
+ * Description: Pointwise multiply vectors of polynomials of length L, multiply
116
+ * resulting vector by 2^{-32} and add (accumulate) polynomials
117
+ * in it. Input/output vectors are in NTT domain representation.
118
+ *
119
+ * Arguments: - poly *w: output polynomial
120
+ * - const polyvecl *u: pointer to first input vector
121
+ * - const polyvecl *v: pointer to second input vector
122
+ **************************************************/
123
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_acc_montgomery(poly *w,
124
+ const polyvecl *u,
125
+ const polyvecl *v) {
126
+ unsigned int i;
127
+ poly t;
128
+
129
+ PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
130
+ for (i = 1; i < L; ++i) {
131
+ PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
132
+ PQCLEAN_MLDSA87_CLEAN_poly_add(w, w, &t);
133
+ }
134
+ }
135
+
136
+ /*************************************************
137
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyvecl_chknorm
138
+ *
139
+ * Description: Check infinity norm of polynomials in vector of length L.
140
+ * Assumes input polyvecl to be reduced by PQCLEAN_MLDSA87_CLEAN_polyvecl_reduce().
141
+ *
142
+ * Arguments: - const polyvecl *v: pointer to vector
143
+ * - int32_t B: norm bound
144
+ *
145
+ * Returns 0 if norm of all polynomials is strictly smaller than B <= (Q-1)/8
146
+ * and 1 otherwise.
147
+ **************************************************/
148
+ int PQCLEAN_MLDSA87_CLEAN_polyvecl_chknorm(const polyvecl *v, int32_t bound) {
149
+ unsigned int i;
150
+
151
+ for (i = 0; i < L; ++i) {
152
+ if (PQCLEAN_MLDSA87_CLEAN_poly_chknorm(&v->vec[i], bound)) {
153
+ return 1;
154
+ }
155
+ }
156
+
157
+ return 0;
158
+ }
159
+
160
+ /**************************************************************/
161
+ /************ Vectors of polynomials of length K **************/
162
+ /**************************************************************/
163
+
164
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
165
+ unsigned int i;
166
+
167
+ for (i = 0; i < K; ++i) {
168
+ PQCLEAN_MLDSA87_CLEAN_poly_uniform_eta(&v->vec[i], seed, nonce++);
169
+ }
170
+ }
171
+
172
+ /*************************************************
173
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_reduce
174
+ *
175
+ * Description: Reduce coefficients of polynomials in vector of length K
176
+ * to representatives in [-6283008,6283008].
177
+ *
178
+ * Arguments: - polyveck *v: pointer to input/output vector
179
+ **************************************************/
180
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_reduce(polyveck *v) {
181
+ unsigned int i;
182
+
183
+ for (i = 0; i < K; ++i) {
184
+ PQCLEAN_MLDSA87_CLEAN_poly_reduce(&v->vec[i]);
185
+ }
186
+ }
187
+
188
+ /*************************************************
189
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_caddq
190
+ *
191
+ * Description: For all coefficients of polynomials in vector of length K
192
+ * add Q if coefficient is negative.
193
+ *
194
+ * Arguments: - polyveck *v: pointer to input/output vector
195
+ **************************************************/
196
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_caddq(polyveck *v) {
197
+ unsigned int i;
198
+
199
+ for (i = 0; i < K; ++i) {
200
+ PQCLEAN_MLDSA87_CLEAN_poly_caddq(&v->vec[i]);
201
+ }
202
+ }
203
+
204
+ /*************************************************
205
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_add
206
+ *
207
+ * Description: Add vectors of polynomials of length K.
208
+ * No modular reduction is performed.
209
+ *
210
+ * Arguments: - polyveck *w: pointer to output vector
211
+ * - const polyveck *u: pointer to first summand
212
+ * - const polyveck *v: pointer to second summand
213
+ **************************************************/
214
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
215
+ unsigned int i;
216
+
217
+ for (i = 0; i < K; ++i) {
218
+ PQCLEAN_MLDSA87_CLEAN_poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
219
+ }
220
+ }
221
+
222
+ /*************************************************
223
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_sub
224
+ *
225
+ * Description: Subtract vectors of polynomials of length K.
226
+ * No modular reduction is performed.
227
+ *
228
+ * Arguments: - polyveck *w: pointer to output vector
229
+ * - const polyveck *u: pointer to first input vector
230
+ * - const polyveck *v: pointer to second input vector to be
231
+ * subtracted from first input vector
232
+ **************************************************/
233
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
234
+ unsigned int i;
235
+
236
+ for (i = 0; i < K; ++i) {
237
+ PQCLEAN_MLDSA87_CLEAN_poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
238
+ }
239
+ }
240
+
241
+ /*************************************************
242
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_shiftl
243
+ *
244
+ * Description: Multiply vector of polynomials of Length K by 2^D without modular
245
+ * reduction. Assumes input coefficients to be less than 2^{31-D}.
246
+ *
247
+ * Arguments: - polyveck *v: pointer to input/output vector
248
+ **************************************************/
249
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_shiftl(polyveck *v) {
250
+ unsigned int i;
251
+
252
+ for (i = 0; i < K; ++i) {
253
+ PQCLEAN_MLDSA87_CLEAN_poly_shiftl(&v->vec[i]);
254
+ }
255
+ }
256
+
257
+ /*************************************************
258
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_ntt
259
+ *
260
+ * Description: Forward NTT of all polynomials in vector of length K. Output
261
+ * coefficients can be up to 16*Q larger than input coefficients.
262
+ *
263
+ * Arguments: - polyveck *v: pointer to input/output vector
264
+ **************************************************/
265
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_ntt(polyveck *v) {
266
+ unsigned int i;
267
+
268
+ for (i = 0; i < K; ++i) {
269
+ PQCLEAN_MLDSA87_CLEAN_poly_ntt(&v->vec[i]);
270
+ }
271
+ }
272
+
273
+ /*************************************************
274
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_invntt_tomont
275
+ *
276
+ * Description: Inverse NTT and multiplication by 2^{32} of polynomials
277
+ * in vector of length K. Input coefficients need to be less
278
+ * than 2*Q.
279
+ *
280
+ * Arguments: - polyveck *v: pointer to input/output vector
281
+ **************************************************/
282
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_invntt_tomont(polyveck *v) {
283
+ unsigned int i;
284
+
285
+ for (i = 0; i < K; ++i) {
286
+ PQCLEAN_MLDSA87_CLEAN_poly_invntt_tomont(&v->vec[i]);
287
+ }
288
+ }
289
+
290
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v) {
291
+ unsigned int i;
292
+
293
+ for (i = 0; i < K; ++i) {
294
+ PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
295
+ }
296
+ }
297
+
298
+
299
+ /*************************************************
300
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_chknorm
301
+ *
302
+ * Description: Check infinity norm of polynomials in vector of length K.
303
+ * Assumes input polyveck to be reduced by PQCLEAN_MLDSA87_CLEAN_polyveck_reduce().
304
+ *
305
+ * Arguments: - const polyveck *v: pointer to vector
306
+ * - int32_t B: norm bound
307
+ *
308
+ * Returns 0 if norm of all polynomials are strictly smaller than B <= (Q-1)/8
309
+ * and 1 otherwise.
310
+ **************************************************/
311
+ int PQCLEAN_MLDSA87_CLEAN_polyveck_chknorm(const polyveck *v, int32_t bound) {
312
+ unsigned int i;
313
+
314
+ for (i = 0; i < K; ++i) {
315
+ if (PQCLEAN_MLDSA87_CLEAN_poly_chknorm(&v->vec[i], bound)) {
316
+ return 1;
317
+ }
318
+ }
319
+
320
+ return 0;
321
+ }
322
+
323
+ /*************************************************
324
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_power2round
325
+ *
326
+ * Description: For all coefficients a of polynomials in vector of length K,
327
+ * compute a0, a1 such that a mod^+ Q = a1*2^D + a0
328
+ * with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be
329
+ * standard representatives.
330
+ *
331
+ * Arguments: - polyveck *v1: pointer to output vector of polynomials with
332
+ * coefficients a1
333
+ * - polyveck *v0: pointer to output vector of polynomials with
334
+ * coefficients a0
335
+ * - const polyveck *v: pointer to input vector
336
+ **************************************************/
337
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
338
+ unsigned int i;
339
+
340
+ for (i = 0; i < K; ++i) {
341
+ PQCLEAN_MLDSA87_CLEAN_poly_power2round(&v1->vec[i], &v0->vec[i], &v->vec[i]);
342
+ }
343
+ }
344
+
345
+ /*************************************************
346
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_decompose
347
+ *
348
+ * Description: For all coefficients a of polynomials in vector of length K,
349
+ * compute high and low bits a0, a1 such a mod^+ Q = a1*ALPHA + a0
350
+ * with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we
351
+ * set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0.
352
+ * Assumes coefficients to be standard representatives.
353
+ *
354
+ * Arguments: - polyveck *v1: pointer to output vector of polynomials with
355
+ * coefficients a1
356
+ * - polyveck *v0: pointer to output vector of polynomials with
357
+ * coefficients a0
358
+ * - const polyveck *v: pointer to input vector
359
+ **************************************************/
360
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
361
+ unsigned int i;
362
+
363
+ for (i = 0; i < K; ++i) {
364
+ PQCLEAN_MLDSA87_CLEAN_poly_decompose(&v1->vec[i], &v0->vec[i], &v->vec[i]);
365
+ }
366
+ }
367
+
368
+ /*************************************************
369
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_make_hint
370
+ *
371
+ * Description: Compute hint vector.
372
+ *
373
+ * Arguments: - polyveck *h: pointer to output vector
374
+ * - const polyveck *v0: pointer to low part of input vector
375
+ * - const polyveck *v1: pointer to high part of input vector
376
+ *
377
+ * Returns number of 1 bits.
378
+ **************************************************/
379
+ unsigned int PQCLEAN_MLDSA87_CLEAN_polyveck_make_hint(polyveck *h,
380
+ const polyveck *v0,
381
+ const polyveck *v1) {
382
+ unsigned int i, s = 0;
383
+
384
+ for (i = 0; i < K; ++i) {
385
+ s += PQCLEAN_MLDSA87_CLEAN_poly_make_hint(&h->vec[i], &v0->vec[i], &v1->vec[i]);
386
+ }
387
+
388
+ return s;
389
+ }
390
+
391
+ /*************************************************
392
+ * Name: PQCLEAN_MLDSA87_CLEAN_polyveck_use_hint
393
+ *
394
+ * Description: Use hint vector to correct the high bits of input vector.
395
+ *
396
+ * Arguments: - polyveck *w: pointer to output vector of polynomials with
397
+ * corrected high bits
398
+ * - const polyveck *u: pointer to input vector
399
+ * - const polyveck *h: pointer to input hint vector
400
+ **************************************************/
401
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h) {
402
+ unsigned int i;
403
+
404
+ for (i = 0; i < K; ++i) {
405
+ PQCLEAN_MLDSA87_CLEAN_poly_use_hint(&w->vec[i], &v->vec[i], &h->vec[i]);
406
+ }
407
+ }
408
+
409
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_pack_w1(uint8_t r[K * POLYW1_PACKEDBYTES], const polyveck *w1) {
410
+ unsigned int i;
411
+
412
+ for (i = 0; i < K; ++i) {
413
+ PQCLEAN_MLDSA87_CLEAN_polyw1_pack(&r[i * POLYW1_PACKEDBYTES], &w1->vec[i]);
414
+ }
415
+ }
@@ -0,0 +1,65 @@
1
+ #ifndef PQCLEAN_MLDSA87_CLEAN_POLYVEC_H
2
+ #define PQCLEAN_MLDSA87_CLEAN_POLYVEC_H
3
+ #include "params.h"
4
+ #include "poly.h"
5
+ #include <stdint.h>
6
+
7
+ /* Vectors of polynomials of length L */
8
+ typedef struct {
9
+ poly vec[L];
10
+ } polyvecl;
11
+
12
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
13
+
14
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
15
+
16
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_reduce(polyvecl *v);
17
+
18
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v);
19
+
20
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_ntt(polyvecl *v);
21
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_invntt_tomont(polyvecl *v);
22
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v);
23
+ void PQCLEAN_MLDSA87_CLEAN_polyvecl_pointwise_acc_montgomery(poly *w,
24
+ const polyvecl *u,
25
+ const polyvecl *v);
26
+
27
+
28
+ int PQCLEAN_MLDSA87_CLEAN_polyvecl_chknorm(const polyvecl *v, int32_t B);
29
+
30
+
31
+
32
+ /* Vectors of polynomials of length K */
33
+ typedef struct {
34
+ poly vec[K];
35
+ } polyveck;
36
+
37
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
38
+
39
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_reduce(polyveck *v);
40
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_caddq(polyveck *v);
41
+
42
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
43
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
44
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_shiftl(polyveck *v);
45
+
46
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_ntt(polyveck *v);
47
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_invntt_tomont(polyveck *v);
48
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v);
49
+
50
+ int PQCLEAN_MLDSA87_CLEAN_polyveck_chknorm(const polyveck *v, int32_t B);
51
+
52
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v);
53
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v);
54
+ unsigned int PQCLEAN_MLDSA87_CLEAN_polyveck_make_hint(polyveck *h,
55
+ const polyveck *v0,
56
+ const polyveck *v1);
57
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h);
58
+
59
+ void PQCLEAN_MLDSA87_CLEAN_polyveck_pack_w1(uint8_t r[K * POLYW1_PACKEDBYTES], const polyveck *w1);
60
+
61
+ void PQCLEAN_MLDSA87_CLEAN_polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]);
62
+
63
+ void PQCLEAN_MLDSA87_CLEAN_polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v);
64
+
65
+ #endif
@@ -0,0 +1,69 @@
1
+ #include "params.h"
2
+ #include "reduce.h"
3
+ #include <stdint.h>
4
+
5
+ /*************************************************
6
+ * Name: PQCLEAN_MLDSA87_CLEAN_montgomery_reduce
7
+ *
8
+ * Description: For finite field element a with -2^{31}Q <= a <= Q*2^31,
9
+ * compute r \equiv a*2^{-32} (mod Q) such that -Q < r < Q.
10
+ *
11
+ * Arguments: - int64_t: finite field element a
12
+ *
13
+ * Returns r.
14
+ **************************************************/
15
+ int32_t PQCLEAN_MLDSA87_CLEAN_montgomery_reduce(int64_t a) {
16
+ int32_t t;
17
+
18
+ t = (int32_t)((uint64_t)a * (uint64_t)QINV);
19
+ t = (a - (int64_t)t * Q) >> 32;
20
+ return t;
21
+ }
22
+
23
+ /*************************************************
24
+ * Name: PQCLEAN_MLDSA87_CLEAN_reduce32
25
+ *
26
+ * Description: For finite field element a with a <= 2^{31} - 2^{22} - 1,
27
+ * compute r \equiv a (mod Q) such that -6283008 <= r <= 6283008.
28
+ *
29
+ * Arguments: - int32_t: finite field element a
30
+ *
31
+ * Returns r.
32
+ **************************************************/
33
+ int32_t PQCLEAN_MLDSA87_CLEAN_reduce32(int32_t a) {
34
+ int32_t t;
35
+
36
+ t = (a + (1 << 22)) >> 23;
37
+ t = a - t * Q;
38
+ return t;
39
+ }
40
+
41
+ /*************************************************
42
+ * Name: PQCLEAN_MLDSA87_CLEAN_caddq
43
+ *
44
+ * Description: Add Q if input coefficient is negative.
45
+ *
46
+ * Arguments: - int32_t: finite field element a
47
+ *
48
+ * Returns r.
49
+ **************************************************/
50
+ int32_t PQCLEAN_MLDSA87_CLEAN_caddq(int32_t a) {
51
+ a += (a >> 31) & Q;
52
+ return a;
53
+ }
54
+
55
+ /*************************************************
56
+ * Name: PQCLEAN_MLDSA87_CLEAN_freeze
57
+ *
58
+ * Description: For finite field element a, compute standard
59
+ * representative r = a mod^+ Q.
60
+ *
61
+ * Arguments: - int32_t: finite field element a
62
+ *
63
+ * Returns r.
64
+ **************************************************/
65
+ int32_t PQCLEAN_MLDSA87_CLEAN_freeze(int32_t a) {
66
+ a = PQCLEAN_MLDSA87_CLEAN_reduce32(a);
67
+ a = PQCLEAN_MLDSA87_CLEAN_caddq(a);
68
+ return a;
69
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef PQCLEAN_MLDSA87_CLEAN_REDUCE_H
2
+ #define PQCLEAN_MLDSA87_CLEAN_REDUCE_H
3
+ #include "params.h"
4
+ #include <stdint.h>
5
+
6
+ #define MONT (-4186625) // 2^32 % Q
7
+ #define QINV 58728449 // q^(-1) mod 2^32
8
+
9
+ int32_t PQCLEAN_MLDSA87_CLEAN_montgomery_reduce(int64_t a);
10
+
11
+ int32_t PQCLEAN_MLDSA87_CLEAN_reduce32(int32_t a);
12
+
13
+ int32_t PQCLEAN_MLDSA87_CLEAN_caddq(int32_t a);
14
+
15
+ int32_t PQCLEAN_MLDSA87_CLEAN_freeze(int32_t a);
16
+
17
+ #endif