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,52 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA65_CLEAN_POLY_H
|
|
2
|
+
#define PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_poly_reduce(poly *a);
|
|
11
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_caddq(poly *a);
|
|
12
|
+
|
|
13
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_add(poly *c, const poly *a, const poly *b);
|
|
14
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_sub(poly *c, const poly *a, const poly *b);
|
|
15
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_shiftl(poly *a);
|
|
16
|
+
|
|
17
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_ntt(poly *a);
|
|
18
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_invntt_tomont(poly *a);
|
|
19
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_pointwise_montgomery(poly *c, const poly *a, const poly *b);
|
|
20
|
+
|
|
21
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_power2round(poly *a1, poly *a0, const poly *a);
|
|
22
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_decompose(poly *a1, poly *a0, const poly *a);
|
|
23
|
+
unsigned int PQCLEAN_MLDSA65_CLEAN_poly_make_hint(poly *h, const poly *a0, const poly *a1);
|
|
24
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_use_hint(poly *b, const poly *a, const poly *h);
|
|
25
|
+
|
|
26
|
+
int PQCLEAN_MLDSA65_CLEAN_poly_chknorm(const poly *a, int32_t B);
|
|
27
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_uniform(poly *a,
|
|
28
|
+
const uint8_t seed[SEEDBYTES],
|
|
29
|
+
uint16_t nonce);
|
|
30
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_uniform_eta(poly *a,
|
|
31
|
+
const uint8_t seed[CRHBYTES],
|
|
32
|
+
uint16_t nonce);
|
|
33
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_uniform_gamma1(poly *a,
|
|
34
|
+
const uint8_t seed[CRHBYTES],
|
|
35
|
+
uint16_t nonce);
|
|
36
|
+
void PQCLEAN_MLDSA65_CLEAN_poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]);
|
|
37
|
+
|
|
38
|
+
void PQCLEAN_MLDSA65_CLEAN_polyeta_pack(uint8_t *r, const poly *a);
|
|
39
|
+
void PQCLEAN_MLDSA65_CLEAN_polyeta_unpack(poly *r, const uint8_t *a);
|
|
40
|
+
|
|
41
|
+
void PQCLEAN_MLDSA65_CLEAN_polyt1_pack(uint8_t *r, const poly *a);
|
|
42
|
+
void PQCLEAN_MLDSA65_CLEAN_polyt1_unpack(poly *r, const uint8_t *a);
|
|
43
|
+
|
|
44
|
+
void PQCLEAN_MLDSA65_CLEAN_polyt0_pack(uint8_t *r, const poly *a);
|
|
45
|
+
void PQCLEAN_MLDSA65_CLEAN_polyt0_unpack(poly *r, const uint8_t *a);
|
|
46
|
+
|
|
47
|
+
void PQCLEAN_MLDSA65_CLEAN_polyz_pack(uint8_t *r, const poly *a);
|
|
48
|
+
void PQCLEAN_MLDSA65_CLEAN_polyz_unpack(poly *r, const uint8_t *a);
|
|
49
|
+
|
|
50
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_uniform(&mat[i].vec[j], rho, (uint16_t) ((i << 8) + j));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_uniform_eta(&v->vec[i], seed, nonce++);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_poly_uniform_gamma1(&v->vec[i], seed, (uint16_t) (L * nonce + i));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_reduce(polyvecl *v) {
|
|
55
|
+
unsigned int i;
|
|
56
|
+
|
|
57
|
+
for (i = 0; i < L; ++i) {
|
|
58
|
+
PQCLEAN_MLDSA65_CLEAN_poly_reduce(&v->vec[i]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/*************************************************
|
|
63
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/*************************************************
|
|
81
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyvecl_ntt(polyvecl *v) {
|
|
89
|
+
unsigned int i;
|
|
90
|
+
|
|
91
|
+
for (i = 0; i < L; ++i) {
|
|
92
|
+
PQCLEAN_MLDSA65_CLEAN_poly_ntt(&v->vec[i]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_invntt_tomont(polyvecl *v) {
|
|
97
|
+
unsigned int i;
|
|
98
|
+
|
|
99
|
+
for (i = 0; i < L; ++i) {
|
|
100
|
+
PQCLEAN_MLDSA65_CLEAN_poly_invntt_tomont(&v->vec[i]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*************************************************
|
|
113
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
|
|
130
|
+
for (i = 1; i < L; ++i) {
|
|
131
|
+
PQCLEAN_MLDSA65_CLEAN_poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
|
|
132
|
+
PQCLEAN_MLDSA65_CLEAN_poly_add(w, w, &t);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*************************************************
|
|
137
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_polyvecl_chknorm(const polyvecl *v, int32_t bound) {
|
|
149
|
+
unsigned int i;
|
|
150
|
+
|
|
151
|
+
for (i = 0; i < L; ++i) {
|
|
152
|
+
if (PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_uniform_eta(&v->vec[i], seed, nonce++);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/*************************************************
|
|
173
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_reduce(polyveck *v) {
|
|
181
|
+
unsigned int i;
|
|
182
|
+
|
|
183
|
+
for (i = 0; i < K; ++i) {
|
|
184
|
+
PQCLEAN_MLDSA65_CLEAN_poly_reduce(&v->vec[i]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/*************************************************
|
|
189
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_caddq(polyveck *v) {
|
|
197
|
+
unsigned int i;
|
|
198
|
+
|
|
199
|
+
for (i = 0; i < K; ++i) {
|
|
200
|
+
PQCLEAN_MLDSA65_CLEAN_poly_caddq(&v->vec[i]);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/*************************************************
|
|
205
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/*************************************************
|
|
223
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/*************************************************
|
|
242
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_shiftl(polyveck *v) {
|
|
250
|
+
unsigned int i;
|
|
251
|
+
|
|
252
|
+
for (i = 0; i < K; ++i) {
|
|
253
|
+
PQCLEAN_MLDSA65_CLEAN_poly_shiftl(&v->vec[i]);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/*************************************************
|
|
258
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_ntt(polyveck *v) {
|
|
266
|
+
unsigned int i;
|
|
267
|
+
|
|
268
|
+
for (i = 0; i < K; ++i) {
|
|
269
|
+
PQCLEAN_MLDSA65_CLEAN_poly_ntt(&v->vec[i]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/*************************************************
|
|
274
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_invntt_tomont(polyveck *v) {
|
|
283
|
+
unsigned int i;
|
|
284
|
+
|
|
285
|
+
for (i = 0; i < K; ++i) {
|
|
286
|
+
PQCLEAN_MLDSA65_CLEAN_poly_invntt_tomont(&v->vec[i]);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
/*************************************************
|
|
300
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_polyveck_chknorm(const polyveck *v, int32_t bound) {
|
|
312
|
+
unsigned int i;
|
|
313
|
+
|
|
314
|
+
for (i = 0; i < K; ++i) {
|
|
315
|
+
if (PQCLEAN_MLDSA65_CLEAN_poly_chknorm(&v->vec[i], bound)) {
|
|
316
|
+
return 1;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/*************************************************
|
|
324
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
|
|
338
|
+
unsigned int i;
|
|
339
|
+
|
|
340
|
+
for (i = 0; i < K; ++i) {
|
|
341
|
+
PQCLEAN_MLDSA65_CLEAN_poly_power2round(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/*************************************************
|
|
346
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
|
|
361
|
+
unsigned int i;
|
|
362
|
+
|
|
363
|
+
for (i = 0; i < K; ++i) {
|
|
364
|
+
PQCLEAN_MLDSA65_CLEAN_poly_decompose(&v1->vec[i], &v0->vec[i], &v->vec[i]);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/*************************************************
|
|
369
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_make_hint(&h->vec[i], &v0->vec[i], &v1->vec[i]);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return s;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/*************************************************
|
|
392
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_poly_use_hint(&w->vec[i], &v->vec[i], &h->vec[i]);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyw1_pack(&r[i * POLYW1_PACKEDBYTES], &w1->vec[i]);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA65_CLEAN_POLYVEC_H
|
|
2
|
+
#define PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
|
13
|
+
|
|
14
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
|
15
|
+
|
|
16
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_reduce(polyvecl *v);
|
|
17
|
+
|
|
18
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v);
|
|
19
|
+
|
|
20
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_ntt(polyvecl *v);
|
|
21
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_invntt_tomont(polyvecl *v);
|
|
22
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v);
|
|
23
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvecl_pointwise_acc_montgomery(poly *w,
|
|
24
|
+
const polyvecl *u,
|
|
25
|
+
const polyvecl *v);
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
int PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce);
|
|
38
|
+
|
|
39
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_reduce(polyveck *v);
|
|
40
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_caddq(polyveck *v);
|
|
41
|
+
|
|
42
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
|
|
43
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
|
|
44
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_shiftl(polyveck *v);
|
|
45
|
+
|
|
46
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_ntt(polyveck *v);
|
|
47
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_invntt_tomont(polyveck *v);
|
|
48
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v);
|
|
49
|
+
|
|
50
|
+
int PQCLEAN_MLDSA65_CLEAN_polyveck_chknorm(const polyveck *v, int32_t B);
|
|
51
|
+
|
|
52
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v);
|
|
53
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v);
|
|
54
|
+
unsigned int PQCLEAN_MLDSA65_CLEAN_polyveck_make_hint(polyveck *h,
|
|
55
|
+
const polyveck *v0,
|
|
56
|
+
const polyveck *v1);
|
|
57
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_use_hint(polyveck *w, const polyveck *v, const polyveck *h);
|
|
58
|
+
|
|
59
|
+
void PQCLEAN_MLDSA65_CLEAN_polyveck_pack_w1(uint8_t r[K * POLYW1_PACKEDBYTES], const polyveck *w1);
|
|
60
|
+
|
|
61
|
+
void PQCLEAN_MLDSA65_CLEAN_polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]);
|
|
62
|
+
|
|
63
|
+
void PQCLEAN_MLDSA65_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_MLDSA65_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_MLDSA65_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_MLDSA65_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_MLDSA65_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_MLDSA65_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_MLDSA65_CLEAN_caddq(int32_t a) {
|
|
51
|
+
a += (a >> 31) & Q;
|
|
52
|
+
return a;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/*************************************************
|
|
56
|
+
* Name: PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_freeze(int32_t a) {
|
|
66
|
+
a = PQCLEAN_MLDSA65_CLEAN_reduce32(a);
|
|
67
|
+
a = PQCLEAN_MLDSA65_CLEAN_caddq(a);
|
|
68
|
+
return a;
|
|
69
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA65_CLEAN_REDUCE_H
|
|
2
|
+
#define PQCLEAN_MLDSA65_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_MLDSA65_CLEAN_montgomery_reduce(int64_t a);
|
|
10
|
+
|
|
11
|
+
int32_t PQCLEAN_MLDSA65_CLEAN_reduce32(int32_t a);
|
|
12
|
+
|
|
13
|
+
int32_t PQCLEAN_MLDSA65_CLEAN_caddq(int32_t a);
|
|
14
|
+
|
|
15
|
+
int32_t PQCLEAN_MLDSA65_CLEAN_freeze(int32_t a);
|
|
16
|
+
|
|
17
|
+
#endif
|