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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +104 -0
- data/LICENSE +14 -0
- data/LICENSE-APACHE +185 -0
- data/LICENSE-MIT +21 -0
- data/README.md +234 -0
- data/ext/ml_dsa/extconf.rb +47 -0
- data/ext/ml_dsa/fips202.c +933 -0
- data/ext/ml_dsa/fips202.h +166 -0
- data/ext/ml_dsa/ml-dsa-44/clean/api.h +52 -0
- data/ext/ml_dsa/ml-dsa-44/clean/ntt.c +98 -0
- data/ext/ml_dsa/ml-dsa-44/clean/ntt.h +10 -0
- data/ext/ml_dsa/ml-dsa-44/clean/packing.c +261 -0
- data/ext/ml_dsa/ml-dsa-44/clean/packing.h +31 -0
- data/ext/ml_dsa/ml-dsa-44/clean/params.h +44 -0
- data/ext/ml_dsa/ml-dsa-44/clean/poly.c +848 -0
- data/ext/ml_dsa/ml-dsa-44/clean/poly.h +52 -0
- data/ext/ml_dsa/ml-dsa-44/clean/polyvec.c +415 -0
- data/ext/ml_dsa/ml-dsa-44/clean/polyvec.h +65 -0
- data/ext/ml_dsa/ml-dsa-44/clean/reduce.c +69 -0
- data/ext/ml_dsa/ml-dsa-44/clean/reduce.h +17 -0
- data/ext/ml_dsa/ml-dsa-44/clean/rounding.c +98 -0
- data/ext/ml_dsa/ml-dsa-44/clean/rounding.h +14 -0
- data/ext/ml_dsa/ml-dsa-44/clean/sign.c +417 -0
- data/ext/ml_dsa/ml-dsa-44/clean/sign.h +49 -0
- data/ext/ml_dsa/ml-dsa-44/clean/symmetric-shake.c +26 -0
- data/ext/ml_dsa/ml-dsa-44/clean/symmetric.h +34 -0
- data/ext/ml_dsa/ml-dsa-65/clean/api.h +52 -0
- data/ext/ml_dsa/ml-dsa-65/clean/ntt.c +98 -0
- data/ext/ml_dsa/ml-dsa-65/clean/ntt.h +10 -0
- data/ext/ml_dsa/ml-dsa-65/clean/packing.c +261 -0
- data/ext/ml_dsa/ml-dsa-65/clean/packing.h +31 -0
- data/ext/ml_dsa/ml-dsa-65/clean/params.h +44 -0
- data/ext/ml_dsa/ml-dsa-65/clean/poly.c +799 -0
- data/ext/ml_dsa/ml-dsa-65/clean/poly.h +52 -0
- data/ext/ml_dsa/ml-dsa-65/clean/polyvec.c +415 -0
- data/ext/ml_dsa/ml-dsa-65/clean/polyvec.h +65 -0
- data/ext/ml_dsa/ml-dsa-65/clean/reduce.c +69 -0
- data/ext/ml_dsa/ml-dsa-65/clean/reduce.h +17 -0
- data/ext/ml_dsa/ml-dsa-65/clean/rounding.c +92 -0
- data/ext/ml_dsa/ml-dsa-65/clean/rounding.h +14 -0
- data/ext/ml_dsa/ml-dsa-65/clean/sign.c +415 -0
- data/ext/ml_dsa/ml-dsa-65/clean/sign.h +49 -0
- data/ext/ml_dsa/ml-dsa-65/clean/symmetric-shake.c +26 -0
- data/ext/ml_dsa/ml-dsa-65/clean/symmetric.h +34 -0
- data/ext/ml_dsa/ml-dsa-87/clean/api.h +52 -0
- data/ext/ml_dsa/ml-dsa-87/clean/ntt.c +98 -0
- data/ext/ml_dsa/ml-dsa-87/clean/ntt.h +10 -0
- data/ext/ml_dsa/ml-dsa-87/clean/packing.c +261 -0
- data/ext/ml_dsa/ml-dsa-87/clean/packing.h +31 -0
- data/ext/ml_dsa/ml-dsa-87/clean/params.h +44 -0
- data/ext/ml_dsa/ml-dsa-87/clean/poly.c +823 -0
- data/ext/ml_dsa/ml-dsa-87/clean/poly.h +52 -0
- data/ext/ml_dsa/ml-dsa-87/clean/polyvec.c +415 -0
- data/ext/ml_dsa/ml-dsa-87/clean/polyvec.h +65 -0
- data/ext/ml_dsa/ml-dsa-87/clean/reduce.c +69 -0
- data/ext/ml_dsa/ml-dsa-87/clean/reduce.h +17 -0
- data/ext/ml_dsa/ml-dsa-87/clean/rounding.c +92 -0
- data/ext/ml_dsa/ml-dsa-87/clean/rounding.h +14 -0
- data/ext/ml_dsa/ml-dsa-87/clean/sign.c +415 -0
- data/ext/ml_dsa/ml-dsa-87/clean/sign.h +49 -0
- data/ext/ml_dsa/ml-dsa-87/clean/symmetric-shake.c +26 -0
- data/ext/ml_dsa/ml-dsa-87/clean/symmetric.h +34 -0
- data/ext/ml_dsa/ml_dsa_44_impl.c +10 -0
- data/ext/ml_dsa/ml_dsa_65_impl.c +10 -0
- data/ext/ml_dsa/ml_dsa_87_impl.c +10 -0
- data/ext/ml_dsa/ml_dsa_ext.c +1360 -0
- data/ext/ml_dsa/ml_dsa_impl_template.h +35 -0
- data/ext/ml_dsa/ml_dsa_internal.h +188 -0
- data/ext/ml_dsa/randombytes.c +48 -0
- data/ext/ml_dsa/randombytes.h +15 -0
- data/lib/ml_dsa/batch_builder.rb +57 -0
- data/lib/ml_dsa/config.rb +69 -0
- data/lib/ml_dsa/internal.rb +76 -0
- data/lib/ml_dsa/key_pair.rb +39 -0
- data/lib/ml_dsa/parameter_set.rb +89 -0
- data/lib/ml_dsa/public_key.rb +180 -0
- data/lib/ml_dsa/requests.rb +96 -0
- data/lib/ml_dsa/secret_key.rb +221 -0
- data/lib/ml_dsa/version.rb +5 -0
- data/lib/ml_dsa.rb +277 -0
- data/patches/README.md +55 -0
- data/patches/pqclean-explicit-rnd.patch +64 -0
- data/sig/ml_dsa.rbs +178 -0
- data/test/fixtures/kat_vectors.yaml +16 -0
- metadata +194 -0
|
@@ -0,0 +1,823 @@
|
|
|
1
|
+
#include "ntt.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "poly.h"
|
|
4
|
+
#include "reduce.h"
|
|
5
|
+
#include "rounding.h"
|
|
6
|
+
#include "symmetric.h"
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
#define DBENCH_START()
|
|
10
|
+
#define DBENCH_STOP(t)
|
|
11
|
+
|
|
12
|
+
/*************************************************
|
|
13
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_reduce
|
|
14
|
+
*
|
|
15
|
+
* Description: Inplace reduction of all coefficients of polynomial to
|
|
16
|
+
* representative in [-6283008,6283008].
|
|
17
|
+
*
|
|
18
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
19
|
+
**************************************************/
|
|
20
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_reduce(poly *a) {
|
|
21
|
+
unsigned int i;
|
|
22
|
+
DBENCH_START();
|
|
23
|
+
|
|
24
|
+
for (i = 0; i < N; ++i) {
|
|
25
|
+
a->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_reduce32(a->coeffs[i]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
DBENCH_STOP(*tred);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*************************************************
|
|
32
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_caddq
|
|
33
|
+
*
|
|
34
|
+
* Description: For all coefficients of in/out polynomial add Q if
|
|
35
|
+
* coefficient is negative.
|
|
36
|
+
*
|
|
37
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
38
|
+
**************************************************/
|
|
39
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_caddq(poly *a) {
|
|
40
|
+
unsigned int i;
|
|
41
|
+
DBENCH_START();
|
|
42
|
+
|
|
43
|
+
for (i = 0; i < N; ++i) {
|
|
44
|
+
a->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_caddq(a->coeffs[i]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
DBENCH_STOP(*tred);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/*************************************************
|
|
51
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_add
|
|
52
|
+
*
|
|
53
|
+
* Description: Add polynomials. No modular reduction is performed.
|
|
54
|
+
*
|
|
55
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
56
|
+
* - const poly *a: pointer to first summand
|
|
57
|
+
* - const poly *b: pointer to second summand
|
|
58
|
+
**************************************************/
|
|
59
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_add(poly *c, const poly *a, const poly *b) {
|
|
60
|
+
unsigned int i;
|
|
61
|
+
DBENCH_START();
|
|
62
|
+
|
|
63
|
+
for (i = 0; i < N; ++i) {
|
|
64
|
+
c->coeffs[i] = a->coeffs[i] + b->coeffs[i];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
DBENCH_STOP(*tadd);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/*************************************************
|
|
71
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_sub
|
|
72
|
+
*
|
|
73
|
+
* Description: Subtract polynomials. No modular reduction is
|
|
74
|
+
* performed.
|
|
75
|
+
*
|
|
76
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
77
|
+
* - const poly *a: pointer to first input polynomial
|
|
78
|
+
* - const poly *b: pointer to second input polynomial to be
|
|
79
|
+
* subtraced from first input polynomial
|
|
80
|
+
**************************************************/
|
|
81
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_sub(poly *c, const poly *a, const poly *b) {
|
|
82
|
+
unsigned int i;
|
|
83
|
+
DBENCH_START();
|
|
84
|
+
|
|
85
|
+
for (i = 0; i < N; ++i) {
|
|
86
|
+
c->coeffs[i] = a->coeffs[i] - b->coeffs[i];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
DBENCH_STOP(*tadd);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/*************************************************
|
|
93
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_shiftl
|
|
94
|
+
*
|
|
95
|
+
* Description: Multiply polynomial by 2^D without modular reduction. Assumes
|
|
96
|
+
* input coefficients to be less than 2^{31-D} in absolute value.
|
|
97
|
+
*
|
|
98
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
99
|
+
**************************************************/
|
|
100
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_shiftl(poly *a) {
|
|
101
|
+
unsigned int i;
|
|
102
|
+
DBENCH_START();
|
|
103
|
+
|
|
104
|
+
for (i = 0; i < N; ++i) {
|
|
105
|
+
a->coeffs[i] <<= D;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
DBENCH_STOP(*tmul);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*************************************************
|
|
112
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_ntt
|
|
113
|
+
*
|
|
114
|
+
* Description: Inplace forward NTT. Coefficients can grow by
|
|
115
|
+
* 8*Q in absolute value.
|
|
116
|
+
*
|
|
117
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
118
|
+
**************************************************/
|
|
119
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_ntt(poly *a) {
|
|
120
|
+
DBENCH_START();
|
|
121
|
+
|
|
122
|
+
PQCLEAN_MLDSA87_CLEAN_ntt(a->coeffs);
|
|
123
|
+
|
|
124
|
+
DBENCH_STOP(*tmul);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/*************************************************
|
|
128
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_invntt_tomont
|
|
129
|
+
*
|
|
130
|
+
* Description: Inplace inverse NTT and multiplication by 2^{32}.
|
|
131
|
+
* Input coefficients need to be less than Q in absolute
|
|
132
|
+
* value and output coefficients are again bounded by Q.
|
|
133
|
+
*
|
|
134
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
135
|
+
**************************************************/
|
|
136
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_invntt_tomont(poly *a) {
|
|
137
|
+
DBENCH_START();
|
|
138
|
+
|
|
139
|
+
PQCLEAN_MLDSA87_CLEAN_invntt_tomont(a->coeffs);
|
|
140
|
+
|
|
141
|
+
DBENCH_STOP(*tmul);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/*************************************************
|
|
145
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery
|
|
146
|
+
*
|
|
147
|
+
* Description: Pointwise multiplication of polynomials in NTT domain
|
|
148
|
+
* representation and multiplication of resulting polynomial
|
|
149
|
+
* by 2^{-32}.
|
|
150
|
+
*
|
|
151
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
152
|
+
* - const poly *a: pointer to first input polynomial
|
|
153
|
+
* - const poly *b: pointer to second input polynomial
|
|
154
|
+
**************************************************/
|
|
155
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_pointwise_montgomery(poly *c, const poly *a, const poly *b) {
|
|
156
|
+
unsigned int i;
|
|
157
|
+
DBENCH_START();
|
|
158
|
+
|
|
159
|
+
for (i = 0; i < N; ++i) {
|
|
160
|
+
c->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
DBENCH_STOP(*tmul);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/*************************************************
|
|
167
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_power2round
|
|
168
|
+
*
|
|
169
|
+
* Description: For all coefficients c of the input polynomial,
|
|
170
|
+
* compute c0, c1 such that c mod Q = c1*2^D + c0
|
|
171
|
+
* with -2^{D-1} < c0 <= 2^{D-1}. Assumes coefficients to be
|
|
172
|
+
* standard representatives.
|
|
173
|
+
*
|
|
174
|
+
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
|
|
175
|
+
* - poly *a0: pointer to output polynomial with coefficients c0
|
|
176
|
+
* - const poly *a: pointer to input polynomial
|
|
177
|
+
**************************************************/
|
|
178
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_power2round(poly *a1, poly *a0, const poly *a) {
|
|
179
|
+
unsigned int i;
|
|
180
|
+
DBENCH_START();
|
|
181
|
+
|
|
182
|
+
for (i = 0; i < N; ++i) {
|
|
183
|
+
a1->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_power2round(&a0->coeffs[i], a->coeffs[i]);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
DBENCH_STOP(*tround);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/*************************************************
|
|
190
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_decompose
|
|
191
|
+
*
|
|
192
|
+
* Description: For all coefficients c of the input polynomial,
|
|
193
|
+
* compute high and low bits c0, c1 such c mod Q = c1*ALPHA + c0
|
|
194
|
+
* with -ALPHA/2 < c0 <= ALPHA/2 except c1 = (Q-1)/ALPHA where we
|
|
195
|
+
* set c1 = 0 and -ALPHA/2 <= c0 = c mod Q - Q < 0.
|
|
196
|
+
* Assumes coefficients to be standard representatives.
|
|
197
|
+
*
|
|
198
|
+
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
|
|
199
|
+
* - poly *a0: pointer to output polynomial with coefficients c0
|
|
200
|
+
* - const poly *a: pointer to input polynomial
|
|
201
|
+
**************************************************/
|
|
202
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_decompose(poly *a1, poly *a0, const poly *a) {
|
|
203
|
+
unsigned int i;
|
|
204
|
+
DBENCH_START();
|
|
205
|
+
|
|
206
|
+
for (i = 0; i < N; ++i) {
|
|
207
|
+
a1->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_decompose(&a0->coeffs[i], a->coeffs[i]);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
DBENCH_STOP(*tround);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/*************************************************
|
|
214
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_make_hint
|
|
215
|
+
*
|
|
216
|
+
* Description: Compute hint polynomial. The coefficients of which indicate
|
|
217
|
+
* whether the low bits of the corresponding coefficient of
|
|
218
|
+
* the input polynomial overflow into the high bits.
|
|
219
|
+
*
|
|
220
|
+
* Arguments: - poly *h: pointer to output hint polynomial
|
|
221
|
+
* - const poly *a0: pointer to low part of input polynomial
|
|
222
|
+
* - const poly *a1: pointer to high part of input polynomial
|
|
223
|
+
*
|
|
224
|
+
* Returns number of 1 bits.
|
|
225
|
+
**************************************************/
|
|
226
|
+
unsigned int PQCLEAN_MLDSA87_CLEAN_poly_make_hint(poly *h, const poly *a0, const poly *a1) {
|
|
227
|
+
unsigned int i, s = 0;
|
|
228
|
+
DBENCH_START();
|
|
229
|
+
|
|
230
|
+
for (i = 0; i < N; ++i) {
|
|
231
|
+
h->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_make_hint(a0->coeffs[i], a1->coeffs[i]);
|
|
232
|
+
s += h->coeffs[i];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
DBENCH_STOP(*tround);
|
|
236
|
+
return s;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/*************************************************
|
|
240
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_use_hint
|
|
241
|
+
*
|
|
242
|
+
* Description: Use hint polynomial to correct the high bits of a polynomial.
|
|
243
|
+
*
|
|
244
|
+
* Arguments: - poly *b: pointer to output polynomial with corrected high bits
|
|
245
|
+
* - const poly *a: pointer to input polynomial
|
|
246
|
+
* - const poly *h: pointer to input hint polynomial
|
|
247
|
+
**************************************************/
|
|
248
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_use_hint(poly *b, const poly *a, const poly *h) {
|
|
249
|
+
unsigned int i;
|
|
250
|
+
DBENCH_START();
|
|
251
|
+
|
|
252
|
+
for (i = 0; i < N; ++i) {
|
|
253
|
+
b->coeffs[i] = PQCLEAN_MLDSA87_CLEAN_use_hint(a->coeffs[i], h->coeffs[i]);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
DBENCH_STOP(*tround);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*************************************************
|
|
260
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_chknorm
|
|
261
|
+
*
|
|
262
|
+
* Description: Check infinity norm of polynomial against given bound.
|
|
263
|
+
* Assumes input coefficients were reduced by PQCLEAN_MLDSA87_CLEAN_reduce32().
|
|
264
|
+
*
|
|
265
|
+
* Arguments: - const poly *a: pointer to polynomial
|
|
266
|
+
* - int32_t B: norm bound
|
|
267
|
+
*
|
|
268
|
+
* Returns 0 if norm is strictly smaller than B <= (Q-1)/8 and 1 otherwise.
|
|
269
|
+
**************************************************/
|
|
270
|
+
int PQCLEAN_MLDSA87_CLEAN_poly_chknorm(const poly *a, int32_t B) {
|
|
271
|
+
unsigned int i;
|
|
272
|
+
int32_t t;
|
|
273
|
+
DBENCH_START();
|
|
274
|
+
|
|
275
|
+
if (B > (Q - 1) / 8) {
|
|
276
|
+
return 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* It is ok to leak which coefficient violates the bound since
|
|
280
|
+
the probability for each coefficient is independent of secret
|
|
281
|
+
data but we must not leak the sign of the centralized representative. */
|
|
282
|
+
for (i = 0; i < N; ++i) {
|
|
283
|
+
/* Absolute value */
|
|
284
|
+
t = a->coeffs[i] >> 31;
|
|
285
|
+
t = a->coeffs[i] - (t & 2 * a->coeffs[i]);
|
|
286
|
+
|
|
287
|
+
if (t >= B) {
|
|
288
|
+
DBENCH_STOP(*tsample);
|
|
289
|
+
return 1;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
DBENCH_STOP(*tsample);
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/*************************************************
|
|
298
|
+
* Name: rej_uniform
|
|
299
|
+
*
|
|
300
|
+
* Description: Sample uniformly random coefficients in [0, Q-1] by
|
|
301
|
+
* performing rejection sampling on array of random bytes.
|
|
302
|
+
*
|
|
303
|
+
* Arguments: - int32_t *a: pointer to output array (allocated)
|
|
304
|
+
* - unsigned int len: number of coefficients to be sampled
|
|
305
|
+
* - const uint8_t *buf: array of random bytes
|
|
306
|
+
* - unsigned int buflen: length of array of random bytes
|
|
307
|
+
*
|
|
308
|
+
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
|
309
|
+
* random bytes were given.
|
|
310
|
+
**************************************************/
|
|
311
|
+
static unsigned int rej_uniform(int32_t *a,
|
|
312
|
+
unsigned int len,
|
|
313
|
+
const uint8_t *buf,
|
|
314
|
+
unsigned int buflen) {
|
|
315
|
+
unsigned int ctr, pos;
|
|
316
|
+
uint32_t t;
|
|
317
|
+
DBENCH_START();
|
|
318
|
+
|
|
319
|
+
ctr = pos = 0;
|
|
320
|
+
while (ctr < len && pos + 3 <= buflen) {
|
|
321
|
+
t = buf[pos++];
|
|
322
|
+
t |= (uint32_t)buf[pos++] << 8;
|
|
323
|
+
t |= (uint32_t)buf[pos++] << 16;
|
|
324
|
+
t &= 0x7FFFFF;
|
|
325
|
+
|
|
326
|
+
if (t < Q) {
|
|
327
|
+
a[ctr++] = t;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
DBENCH_STOP(*tsample);
|
|
332
|
+
return ctr;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/*************************************************
|
|
336
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_uniform
|
|
337
|
+
*
|
|
338
|
+
* Description: Sample polynomial with uniformly random coefficients
|
|
339
|
+
* in [0,Q-1] by performing rejection sampling on the
|
|
340
|
+
* output stream of SHAKE128(seed|nonce)
|
|
341
|
+
*
|
|
342
|
+
* Arguments: - poly *a: pointer to output polynomial
|
|
343
|
+
* - const uint8_t seed[]: byte array with seed of length SEEDBYTES
|
|
344
|
+
* - uint16_t nonce: 2-byte nonce
|
|
345
|
+
**************************************************/
|
|
346
|
+
#define POLY_UNIFORM_NBLOCKS ((768 + STREAM128_BLOCKBYTES - 1)/STREAM128_BLOCKBYTES)
|
|
347
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_uniform(poly *a,
|
|
348
|
+
const uint8_t seed[SEEDBYTES],
|
|
349
|
+
uint16_t nonce) {
|
|
350
|
+
unsigned int i, ctr, off;
|
|
351
|
+
unsigned int buflen = POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES;
|
|
352
|
+
uint8_t buf[POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES + 2];
|
|
353
|
+
stream128_state state;
|
|
354
|
+
|
|
355
|
+
stream128_init(&state, seed, nonce);
|
|
356
|
+
stream128_squeezeblocks(buf, POLY_UNIFORM_NBLOCKS, &state);
|
|
357
|
+
|
|
358
|
+
ctr = rej_uniform(a->coeffs, N, buf, buflen);
|
|
359
|
+
|
|
360
|
+
while (ctr < N) {
|
|
361
|
+
off = buflen % 3;
|
|
362
|
+
for (i = 0; i < off; ++i) {
|
|
363
|
+
buf[i] = buf[buflen - off + i];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
stream128_squeezeblocks(buf + off, 1, &state);
|
|
367
|
+
buflen = STREAM128_BLOCKBYTES + off;
|
|
368
|
+
ctr += rej_uniform(a->coeffs + ctr, N - ctr, buf, buflen);
|
|
369
|
+
}
|
|
370
|
+
stream128_release(&state);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/*************************************************
|
|
374
|
+
* Name: rej_eta
|
|
375
|
+
*
|
|
376
|
+
* Description: Sample uniformly random coefficients in [-ETA, ETA] by
|
|
377
|
+
* performing rejection sampling on array of random bytes.
|
|
378
|
+
*
|
|
379
|
+
* Arguments: - int32_t *a: pointer to output array (allocated)
|
|
380
|
+
* - unsigned int len: number of coefficients to be sampled
|
|
381
|
+
* - const uint8_t *buf: array of random bytes
|
|
382
|
+
* - unsigned int buflen: length of array of random bytes
|
|
383
|
+
*
|
|
384
|
+
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
|
385
|
+
* random bytes were given.
|
|
386
|
+
**************************************************/
|
|
387
|
+
static unsigned int rej_eta(int32_t *a,
|
|
388
|
+
unsigned int len,
|
|
389
|
+
const uint8_t *buf,
|
|
390
|
+
unsigned int buflen) {
|
|
391
|
+
unsigned int ctr, pos;
|
|
392
|
+
uint32_t t0, t1;
|
|
393
|
+
DBENCH_START();
|
|
394
|
+
|
|
395
|
+
ctr = pos = 0;
|
|
396
|
+
while (ctr < len && pos < buflen) {
|
|
397
|
+
t0 = buf[pos] & 0x0F;
|
|
398
|
+
t1 = buf[pos++] >> 4;
|
|
399
|
+
|
|
400
|
+
if (t0 < 15) {
|
|
401
|
+
t0 = t0 - (205 * t0 >> 10) * 5;
|
|
402
|
+
a[ctr++] = 2 - t0;
|
|
403
|
+
}
|
|
404
|
+
if (t1 < 15 && ctr < len) {
|
|
405
|
+
t1 = t1 - (205 * t1 >> 10) * 5;
|
|
406
|
+
a[ctr++] = 2 - t1;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
DBENCH_STOP(*tsample);
|
|
411
|
+
return ctr;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/*************************************************
|
|
415
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_poly_uniform_eta
|
|
416
|
+
*
|
|
417
|
+
* Description: Sample polynomial with uniformly random coefficients
|
|
418
|
+
* in [-ETA,ETA] by performing rejection sampling on the
|
|
419
|
+
* output stream from SHAKE256(seed|nonce)
|
|
420
|
+
*
|
|
421
|
+
* Arguments: - poly *a: pointer to output polynomial
|
|
422
|
+
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
|
|
423
|
+
* - uint16_t nonce: 2-byte nonce
|
|
424
|
+
**************************************************/
|
|
425
|
+
#define POLY_UNIFORM_ETA_NBLOCKS ((136 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
|
|
426
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_uniform_eta(poly *a,
|
|
427
|
+
const uint8_t seed[CRHBYTES],
|
|
428
|
+
uint16_t nonce) {
|
|
429
|
+
unsigned int ctr;
|
|
430
|
+
unsigned int buflen = POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES;
|
|
431
|
+
uint8_t buf[POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES];
|
|
432
|
+
stream256_state state;
|
|
433
|
+
|
|
434
|
+
stream256_init(&state, seed, nonce);
|
|
435
|
+
stream256_squeezeblocks(buf, POLY_UNIFORM_ETA_NBLOCKS, &state);
|
|
436
|
+
|
|
437
|
+
ctr = rej_eta(a->coeffs, N, buf, buflen);
|
|
438
|
+
|
|
439
|
+
while (ctr < N) {
|
|
440
|
+
stream256_squeezeblocks(buf, 1, &state);
|
|
441
|
+
ctr += rej_eta(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
|
|
442
|
+
}
|
|
443
|
+
stream256_release(&state);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/*************************************************
|
|
447
|
+
* Name: poly_uniform_gamma1m1
|
|
448
|
+
*
|
|
449
|
+
* Description: Sample polynomial with uniformly random coefficients
|
|
450
|
+
* in [-(GAMMA1 - 1), GAMMA1] by unpacking output stream
|
|
451
|
+
* of SHAKE256(seed|nonce)
|
|
452
|
+
*
|
|
453
|
+
* Arguments: - poly *a: pointer to output polynomial
|
|
454
|
+
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
|
|
455
|
+
* - uint16_t nonce: 16-bit nonce
|
|
456
|
+
**************************************************/
|
|
457
|
+
#define POLY_UNIFORM_GAMMA1_NBLOCKS ((POLYZ_PACKEDBYTES + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
|
|
458
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_uniform_gamma1(poly *a,
|
|
459
|
+
const uint8_t seed[CRHBYTES],
|
|
460
|
+
uint16_t nonce) {
|
|
461
|
+
uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS * STREAM256_BLOCKBYTES];
|
|
462
|
+
stream256_state state;
|
|
463
|
+
|
|
464
|
+
stream256_init(&state, seed, nonce);
|
|
465
|
+
stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
|
|
466
|
+
stream256_release(&state);
|
|
467
|
+
PQCLEAN_MLDSA87_CLEAN_polyz_unpack(a, buf);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/*************************************************
|
|
471
|
+
* Name: challenge
|
|
472
|
+
*
|
|
473
|
+
* Description: Implementation of H. Samples polynomial with TAU nonzero
|
|
474
|
+
* coefficients in {-1,1} using the output stream of
|
|
475
|
+
* SHAKE256(seed).
|
|
476
|
+
*
|
|
477
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
478
|
+
* - const uint8_t mu[]: byte array containing seed of length CTILDEBYTES
|
|
479
|
+
**************************************************/
|
|
480
|
+
void PQCLEAN_MLDSA87_CLEAN_poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]) {
|
|
481
|
+
unsigned int i, b, pos;
|
|
482
|
+
uint64_t signs;
|
|
483
|
+
uint8_t buf[SHAKE256_RATE];
|
|
484
|
+
shake256incctx state;
|
|
485
|
+
|
|
486
|
+
shake256_inc_init(&state);
|
|
487
|
+
shake256_inc_absorb(&state, seed, CTILDEBYTES);
|
|
488
|
+
shake256_inc_finalize(&state);
|
|
489
|
+
shake256_inc_squeeze(buf, sizeof buf, &state);
|
|
490
|
+
|
|
491
|
+
signs = 0;
|
|
492
|
+
for (i = 0; i < 8; ++i) {
|
|
493
|
+
signs |= (uint64_t)buf[i] << 8 * i;
|
|
494
|
+
}
|
|
495
|
+
pos = 8;
|
|
496
|
+
|
|
497
|
+
for (i = 0; i < N; ++i) {
|
|
498
|
+
c->coeffs[i] = 0;
|
|
499
|
+
}
|
|
500
|
+
for (i = N - TAU; i < N; ++i) {
|
|
501
|
+
do {
|
|
502
|
+
if (pos >= SHAKE256_RATE) {
|
|
503
|
+
shake256_inc_squeeze(buf, sizeof buf, &state);
|
|
504
|
+
pos = 0;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
b = buf[pos++];
|
|
508
|
+
} while (b > i);
|
|
509
|
+
|
|
510
|
+
c->coeffs[i] = c->coeffs[b];
|
|
511
|
+
c->coeffs[b] = 1 - 2 * (signs & 1);
|
|
512
|
+
signs >>= 1;
|
|
513
|
+
}
|
|
514
|
+
shake256_inc_ctx_release(&state);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/*************************************************
|
|
518
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyeta_pack
|
|
519
|
+
*
|
|
520
|
+
* Description: Bit-pack polynomial with coefficients in [-ETA,ETA].
|
|
521
|
+
*
|
|
522
|
+
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
|
523
|
+
* POLYETA_PACKEDBYTES bytes
|
|
524
|
+
* - const poly *a: pointer to input polynomial
|
|
525
|
+
**************************************************/
|
|
526
|
+
void PQCLEAN_MLDSA87_CLEAN_polyeta_pack(uint8_t *r, const poly *a) {
|
|
527
|
+
unsigned int i;
|
|
528
|
+
uint8_t t[8];
|
|
529
|
+
DBENCH_START();
|
|
530
|
+
|
|
531
|
+
for (i = 0; i < N / 8; ++i) {
|
|
532
|
+
t[0] = (uint8_t) (ETA - a->coeffs[8 * i + 0]);
|
|
533
|
+
t[1] = (uint8_t) (ETA - a->coeffs[8 * i + 1]);
|
|
534
|
+
t[2] = (uint8_t) (ETA - a->coeffs[8 * i + 2]);
|
|
535
|
+
t[3] = (uint8_t) (ETA - a->coeffs[8 * i + 3]);
|
|
536
|
+
t[4] = (uint8_t) (ETA - a->coeffs[8 * i + 4]);
|
|
537
|
+
t[5] = (uint8_t) (ETA - a->coeffs[8 * i + 5]);
|
|
538
|
+
t[6] = (uint8_t) (ETA - a->coeffs[8 * i + 6]);
|
|
539
|
+
t[7] = (uint8_t) (ETA - a->coeffs[8 * i + 7]);
|
|
540
|
+
|
|
541
|
+
r[3 * i + 0] = (t[0] >> 0) | (t[1] << 3) | (t[2] << 6);
|
|
542
|
+
r[3 * i + 1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
|
|
543
|
+
r[3 * i + 2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
DBENCH_STOP(*tpack);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/*************************************************
|
|
550
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyeta_unpack
|
|
551
|
+
*
|
|
552
|
+
* Description: Unpack polynomial with coefficients in [-ETA,ETA].
|
|
553
|
+
*
|
|
554
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
555
|
+
* - const uint8_t *a: byte array with bit-packed polynomial
|
|
556
|
+
**************************************************/
|
|
557
|
+
void PQCLEAN_MLDSA87_CLEAN_polyeta_unpack(poly *r, const uint8_t *a) {
|
|
558
|
+
unsigned int i;
|
|
559
|
+
DBENCH_START();
|
|
560
|
+
|
|
561
|
+
for (i = 0; i < N / 8; ++i) {
|
|
562
|
+
r->coeffs[8 * i + 0] = (a[3 * i + 0] >> 0) & 7;
|
|
563
|
+
r->coeffs[8 * i + 1] = (a[3 * i + 0] >> 3) & 7;
|
|
564
|
+
r->coeffs[8 * i + 2] = ((a[3 * i + 0] >> 6) | (a[3 * i + 1] << 2)) & 7;
|
|
565
|
+
r->coeffs[8 * i + 3] = (a[3 * i + 1] >> 1) & 7;
|
|
566
|
+
r->coeffs[8 * i + 4] = (a[3 * i + 1] >> 4) & 7;
|
|
567
|
+
r->coeffs[8 * i + 5] = ((a[3 * i + 1] >> 7) | (a[3 * i + 2] << 1)) & 7;
|
|
568
|
+
r->coeffs[8 * i + 6] = (a[3 * i + 2] >> 2) & 7;
|
|
569
|
+
r->coeffs[8 * i + 7] = (a[3 * i + 2] >> 5) & 7;
|
|
570
|
+
|
|
571
|
+
r->coeffs[8 * i + 0] = ETA - r->coeffs[8 * i + 0];
|
|
572
|
+
r->coeffs[8 * i + 1] = ETA - r->coeffs[8 * i + 1];
|
|
573
|
+
r->coeffs[8 * i + 2] = ETA - r->coeffs[8 * i + 2];
|
|
574
|
+
r->coeffs[8 * i + 3] = ETA - r->coeffs[8 * i + 3];
|
|
575
|
+
r->coeffs[8 * i + 4] = ETA - r->coeffs[8 * i + 4];
|
|
576
|
+
r->coeffs[8 * i + 5] = ETA - r->coeffs[8 * i + 5];
|
|
577
|
+
r->coeffs[8 * i + 6] = ETA - r->coeffs[8 * i + 6];
|
|
578
|
+
r->coeffs[8 * i + 7] = ETA - r->coeffs[8 * i + 7];
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
DBENCH_STOP(*tpack);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/*************************************************
|
|
585
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyt1_pack
|
|
586
|
+
*
|
|
587
|
+
* Description: Bit-pack polynomial t1 with coefficients fitting in 10 bits.
|
|
588
|
+
* Input coefficients are assumed to be standard representatives.
|
|
589
|
+
*
|
|
590
|
+
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
|
591
|
+
* POLYT1_PACKEDBYTES bytes
|
|
592
|
+
* - const poly *a: pointer to input polynomial
|
|
593
|
+
**************************************************/
|
|
594
|
+
void PQCLEAN_MLDSA87_CLEAN_polyt1_pack(uint8_t *r, const poly *a) {
|
|
595
|
+
unsigned int i;
|
|
596
|
+
DBENCH_START();
|
|
597
|
+
|
|
598
|
+
for (i = 0; i < N / 4; ++i) {
|
|
599
|
+
r[5 * i + 0] = (uint8_t) (a->coeffs[4 * i + 0] >> 0);
|
|
600
|
+
r[5 * i + 1] = (uint8_t) ((a->coeffs[4 * i + 0] >> 8) | (a->coeffs[4 * i + 1] << 2));
|
|
601
|
+
r[5 * i + 2] = (uint8_t) ((a->coeffs[4 * i + 1] >> 6) | (a->coeffs[4 * i + 2] << 4));
|
|
602
|
+
r[5 * i + 3] = (uint8_t) ((a->coeffs[4 * i + 2] >> 4) | (a->coeffs[4 * i + 3] << 6));
|
|
603
|
+
r[5 * i + 4] = (uint8_t) (a->coeffs[4 * i + 3] >> 2);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
DBENCH_STOP(*tpack);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/*************************************************
|
|
610
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyt1_unpack
|
|
611
|
+
*
|
|
612
|
+
* Description: Unpack polynomial t1 with 10-bit coefficients.
|
|
613
|
+
* Output coefficients are standard representatives.
|
|
614
|
+
*
|
|
615
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
616
|
+
* - const uint8_t *a: byte array with bit-packed polynomial
|
|
617
|
+
**************************************************/
|
|
618
|
+
void PQCLEAN_MLDSA87_CLEAN_polyt1_unpack(poly *r, const uint8_t *a) {
|
|
619
|
+
unsigned int i;
|
|
620
|
+
DBENCH_START();
|
|
621
|
+
|
|
622
|
+
for (i = 0; i < N / 4; ++i) {
|
|
623
|
+
r->coeffs[4 * i + 0] = ((a[5 * i + 0] >> 0) | ((uint32_t)a[5 * i + 1] << 8)) & 0x3FF;
|
|
624
|
+
r->coeffs[4 * i + 1] = ((a[5 * i + 1] >> 2) | ((uint32_t)a[5 * i + 2] << 6)) & 0x3FF;
|
|
625
|
+
r->coeffs[4 * i + 2] = ((a[5 * i + 2] >> 4) | ((uint32_t)a[5 * i + 3] << 4)) & 0x3FF;
|
|
626
|
+
r->coeffs[4 * i + 3] = ((a[5 * i + 3] >> 6) | ((uint32_t)a[5 * i + 4] << 2)) & 0x3FF;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
DBENCH_STOP(*tpack);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/*************************************************
|
|
633
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyt0_pack
|
|
634
|
+
*
|
|
635
|
+
* Description: Bit-pack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
|
|
636
|
+
*
|
|
637
|
+
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
|
638
|
+
* POLYT0_PACKEDBYTES bytes
|
|
639
|
+
* - const poly *a: pointer to input polynomial
|
|
640
|
+
**************************************************/
|
|
641
|
+
void PQCLEAN_MLDSA87_CLEAN_polyt0_pack(uint8_t *r, const poly *a) {
|
|
642
|
+
unsigned int i;
|
|
643
|
+
uint32_t t[8];
|
|
644
|
+
DBENCH_START();
|
|
645
|
+
|
|
646
|
+
for (i = 0; i < N / 8; ++i) {
|
|
647
|
+
t[0] = (1 << (D - 1)) - a->coeffs[8 * i + 0];
|
|
648
|
+
t[1] = (1 << (D - 1)) - a->coeffs[8 * i + 1];
|
|
649
|
+
t[2] = (1 << (D - 1)) - a->coeffs[8 * i + 2];
|
|
650
|
+
t[3] = (1 << (D - 1)) - a->coeffs[8 * i + 3];
|
|
651
|
+
t[4] = (1 << (D - 1)) - a->coeffs[8 * i + 4];
|
|
652
|
+
t[5] = (1 << (D - 1)) - a->coeffs[8 * i + 5];
|
|
653
|
+
t[6] = (1 << (D - 1)) - a->coeffs[8 * i + 6];
|
|
654
|
+
t[7] = (1 << (D - 1)) - a->coeffs[8 * i + 7];
|
|
655
|
+
|
|
656
|
+
r[13 * i + 0] = (uint8_t) t[0];
|
|
657
|
+
r[13 * i + 1] = (uint8_t) (t[0] >> 8);
|
|
658
|
+
r[13 * i + 1] |= (uint8_t) (t[1] << 5);
|
|
659
|
+
r[13 * i + 2] = (uint8_t) (t[1] >> 3);
|
|
660
|
+
r[13 * i + 3] = (uint8_t) (t[1] >> 11);
|
|
661
|
+
r[13 * i + 3] |= (uint8_t) (t[2] << 2);
|
|
662
|
+
r[13 * i + 4] = (uint8_t) (t[2] >> 6);
|
|
663
|
+
r[13 * i + 4] |= (uint8_t) (t[3] << 7);
|
|
664
|
+
r[13 * i + 5] = (uint8_t) (t[3] >> 1);
|
|
665
|
+
r[13 * i + 6] = (uint8_t) (t[3] >> 9);
|
|
666
|
+
r[13 * i + 6] |= (uint8_t) (t[4] << 4);
|
|
667
|
+
r[13 * i + 7] = (uint8_t) (t[4] >> 4);
|
|
668
|
+
r[13 * i + 8] = (uint8_t) (t[4] >> 12);
|
|
669
|
+
r[13 * i + 8] |= (uint8_t) (t[5] << 1);
|
|
670
|
+
r[13 * i + 9] = (uint8_t) (t[5] >> 7);
|
|
671
|
+
r[13 * i + 9] |= (uint8_t) (t[6] << 6);
|
|
672
|
+
r[13 * i + 10] = (uint8_t) (t[6] >> 2);
|
|
673
|
+
r[13 * i + 11] = (uint8_t) (t[6] >> 10);
|
|
674
|
+
r[13 * i + 11] |= (uint8_t) (t[7] << 3);
|
|
675
|
+
r[13 * i + 12] = (uint8_t) (t[7] >> 5);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
DBENCH_STOP(*tpack);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/*************************************************
|
|
682
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyt0_unpack
|
|
683
|
+
*
|
|
684
|
+
* Description: Unpack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
|
|
685
|
+
*
|
|
686
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
687
|
+
* - const uint8_t *a: byte array with bit-packed polynomial
|
|
688
|
+
**************************************************/
|
|
689
|
+
void PQCLEAN_MLDSA87_CLEAN_polyt0_unpack(poly *r, const uint8_t *a) {
|
|
690
|
+
unsigned int i;
|
|
691
|
+
DBENCH_START();
|
|
692
|
+
|
|
693
|
+
for (i = 0; i < N / 8; ++i) {
|
|
694
|
+
r->coeffs[8 * i + 0] = a[13 * i + 0];
|
|
695
|
+
r->coeffs[8 * i + 0] |= (uint32_t)a[13 * i + 1] << 8;
|
|
696
|
+
r->coeffs[8 * i + 0] &= 0x1FFF;
|
|
697
|
+
|
|
698
|
+
r->coeffs[8 * i + 1] = a[13 * i + 1] >> 5;
|
|
699
|
+
r->coeffs[8 * i + 1] |= (uint32_t)a[13 * i + 2] << 3;
|
|
700
|
+
r->coeffs[8 * i + 1] |= (uint32_t)a[13 * i + 3] << 11;
|
|
701
|
+
r->coeffs[8 * i + 1] &= 0x1FFF;
|
|
702
|
+
|
|
703
|
+
r->coeffs[8 * i + 2] = a[13 * i + 3] >> 2;
|
|
704
|
+
r->coeffs[8 * i + 2] |= (uint32_t)a[13 * i + 4] << 6;
|
|
705
|
+
r->coeffs[8 * i + 2] &= 0x1FFF;
|
|
706
|
+
|
|
707
|
+
r->coeffs[8 * i + 3] = a[13 * i + 4] >> 7;
|
|
708
|
+
r->coeffs[8 * i + 3] |= (uint32_t)a[13 * i + 5] << 1;
|
|
709
|
+
r->coeffs[8 * i + 3] |= (uint32_t)a[13 * i + 6] << 9;
|
|
710
|
+
r->coeffs[8 * i + 3] &= 0x1FFF;
|
|
711
|
+
|
|
712
|
+
r->coeffs[8 * i + 4] = a[13 * i + 6] >> 4;
|
|
713
|
+
r->coeffs[8 * i + 4] |= (uint32_t)a[13 * i + 7] << 4;
|
|
714
|
+
r->coeffs[8 * i + 4] |= (uint32_t)a[13 * i + 8] << 12;
|
|
715
|
+
r->coeffs[8 * i + 4] &= 0x1FFF;
|
|
716
|
+
|
|
717
|
+
r->coeffs[8 * i + 5] = a[13 * i + 8] >> 1;
|
|
718
|
+
r->coeffs[8 * i + 5] |= (uint32_t)a[13 * i + 9] << 7;
|
|
719
|
+
r->coeffs[8 * i + 5] &= 0x1FFF;
|
|
720
|
+
|
|
721
|
+
r->coeffs[8 * i + 6] = a[13 * i + 9] >> 6;
|
|
722
|
+
r->coeffs[8 * i + 6] |= (uint32_t)a[13 * i + 10] << 2;
|
|
723
|
+
r->coeffs[8 * i + 6] |= (uint32_t)a[13 * i + 11] << 10;
|
|
724
|
+
r->coeffs[8 * i + 6] &= 0x1FFF;
|
|
725
|
+
|
|
726
|
+
r->coeffs[8 * i + 7] = a[13 * i + 11] >> 3;
|
|
727
|
+
r->coeffs[8 * i + 7] |= (uint32_t)a[13 * i + 12] << 5;
|
|
728
|
+
r->coeffs[8 * i + 7] &= 0x1FFF;
|
|
729
|
+
|
|
730
|
+
r->coeffs[8 * i + 0] = (1 << (D - 1)) - r->coeffs[8 * i + 0];
|
|
731
|
+
r->coeffs[8 * i + 1] = (1 << (D - 1)) - r->coeffs[8 * i + 1];
|
|
732
|
+
r->coeffs[8 * i + 2] = (1 << (D - 1)) - r->coeffs[8 * i + 2];
|
|
733
|
+
r->coeffs[8 * i + 3] = (1 << (D - 1)) - r->coeffs[8 * i + 3];
|
|
734
|
+
r->coeffs[8 * i + 4] = (1 << (D - 1)) - r->coeffs[8 * i + 4];
|
|
735
|
+
r->coeffs[8 * i + 5] = (1 << (D - 1)) - r->coeffs[8 * i + 5];
|
|
736
|
+
r->coeffs[8 * i + 6] = (1 << (D - 1)) - r->coeffs[8 * i + 6];
|
|
737
|
+
r->coeffs[8 * i + 7] = (1 << (D - 1)) - r->coeffs[8 * i + 7];
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
DBENCH_STOP(*tpack);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/*************************************************
|
|
744
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyz_pack
|
|
745
|
+
*
|
|
746
|
+
* Description: Bit-pack polynomial with coefficients
|
|
747
|
+
* in [-(GAMMA1 - 1), GAMMA1].
|
|
748
|
+
*
|
|
749
|
+
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
|
750
|
+
* POLYZ_PACKEDBYTES bytes
|
|
751
|
+
* - const poly *a: pointer to input polynomial
|
|
752
|
+
**************************************************/
|
|
753
|
+
void PQCLEAN_MLDSA87_CLEAN_polyz_pack(uint8_t *r, const poly *a) {
|
|
754
|
+
unsigned int i;
|
|
755
|
+
uint32_t t[4];
|
|
756
|
+
DBENCH_START();
|
|
757
|
+
|
|
758
|
+
for (i = 0; i < N / 2; ++i) {
|
|
759
|
+
t[0] = GAMMA1 - a->coeffs[2 * i + 0];
|
|
760
|
+
t[1] = GAMMA1 - a->coeffs[2 * i + 1];
|
|
761
|
+
|
|
762
|
+
r[5 * i + 0] = (uint8_t) (t[0]);
|
|
763
|
+
r[5 * i + 1] = (uint8_t) (t[0] >> 8);
|
|
764
|
+
r[5 * i + 2] = (uint8_t) (t[0] >> 16);
|
|
765
|
+
r[5 * i + 2] |= (uint8_t) (t[1] << 4);
|
|
766
|
+
r[5 * i + 3] = (uint8_t) (t[1] >> 4);
|
|
767
|
+
r[5 * i + 4] = (uint8_t) (t[1] >> 12);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
DBENCH_STOP(*tpack);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/*************************************************
|
|
774
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyz_unpack
|
|
775
|
+
*
|
|
776
|
+
* Description: Unpack polynomial z with coefficients
|
|
777
|
+
* in [-(GAMMA1 - 1), GAMMA1].
|
|
778
|
+
*
|
|
779
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
780
|
+
* - const uint8_t *a: byte array with bit-packed polynomial
|
|
781
|
+
**************************************************/
|
|
782
|
+
void PQCLEAN_MLDSA87_CLEAN_polyz_unpack(poly *r, const uint8_t *a) {
|
|
783
|
+
unsigned int i;
|
|
784
|
+
DBENCH_START();
|
|
785
|
+
|
|
786
|
+
for (i = 0; i < N / 2; ++i) {
|
|
787
|
+
r->coeffs[2 * i + 0] = a[5 * i + 0];
|
|
788
|
+
r->coeffs[2 * i + 0] |= (uint32_t)a[5 * i + 1] << 8;
|
|
789
|
+
r->coeffs[2 * i + 0] |= (uint32_t)a[5 * i + 2] << 16;
|
|
790
|
+
r->coeffs[2 * i + 0] &= 0xFFFFF;
|
|
791
|
+
|
|
792
|
+
r->coeffs[2 * i + 1] = a[5 * i + 2] >> 4;
|
|
793
|
+
r->coeffs[2 * i + 1] |= (uint32_t)a[5 * i + 3] << 4;
|
|
794
|
+
r->coeffs[2 * i + 1] |= (uint32_t)a[5 * i + 4] << 12;
|
|
795
|
+
/* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20 bits */
|
|
796
|
+
|
|
797
|
+
r->coeffs[2 * i + 0] = GAMMA1 - r->coeffs[2 * i + 0];
|
|
798
|
+
r->coeffs[2 * i + 1] = GAMMA1 - r->coeffs[2 * i + 1];
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
DBENCH_STOP(*tpack);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/*************************************************
|
|
805
|
+
* Name: PQCLEAN_MLDSA87_CLEAN_polyw1_pack
|
|
806
|
+
*
|
|
807
|
+
* Description: Bit-pack polynomial w1 with coefficients in [0,15] or [0,43].
|
|
808
|
+
* Input coefficients are assumed to be standard representatives.
|
|
809
|
+
*
|
|
810
|
+
* Arguments: - uint8_t *r: pointer to output byte array with at least
|
|
811
|
+
* POLYW1_PACKEDBYTES bytes
|
|
812
|
+
* - const poly *a: pointer to input polynomial
|
|
813
|
+
**************************************************/
|
|
814
|
+
void PQCLEAN_MLDSA87_CLEAN_polyw1_pack(uint8_t *r, const poly *a) {
|
|
815
|
+
unsigned int i;
|
|
816
|
+
DBENCH_START();
|
|
817
|
+
|
|
818
|
+
for (i = 0; i < N / 2; ++i) {
|
|
819
|
+
r[i] = (uint8_t) (a->coeffs[2 * i + 0] | (a->coeffs[2 * i + 1] << 4));
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
DBENCH_STOP(*tpack);
|
|
823
|
+
}
|