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,166 @@
|
|
|
1
|
+
#ifndef FIPS202_H
|
|
2
|
+
#define FIPS202_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define SHAKE128_RATE 168
|
|
8
|
+
#define SHAKE256_RATE 136
|
|
9
|
+
#define SHA3_256_RATE 136
|
|
10
|
+
#define SHA3_384_RATE 104
|
|
11
|
+
#define SHA3_512_RATE 72
|
|
12
|
+
|
|
13
|
+
#define PQC_SHAKEINCCTX_BYTES (sizeof(uint64_t)*26)
|
|
14
|
+
#define PQC_SHAKECTX_BYTES (sizeof(uint64_t)*25)
|
|
15
|
+
|
|
16
|
+
// Context for incremental API
|
|
17
|
+
typedef struct {
|
|
18
|
+
uint64_t *ctx;
|
|
19
|
+
} shake128incctx;
|
|
20
|
+
|
|
21
|
+
// Context for non-incremental API
|
|
22
|
+
typedef struct {
|
|
23
|
+
uint64_t *ctx;
|
|
24
|
+
} shake128ctx;
|
|
25
|
+
|
|
26
|
+
// Context for incremental API
|
|
27
|
+
typedef struct {
|
|
28
|
+
uint64_t *ctx;
|
|
29
|
+
} shake256incctx;
|
|
30
|
+
|
|
31
|
+
// Context for non-incremental API
|
|
32
|
+
typedef struct {
|
|
33
|
+
uint64_t *ctx;
|
|
34
|
+
} shake256ctx;
|
|
35
|
+
|
|
36
|
+
// Context for incremental API
|
|
37
|
+
typedef struct {
|
|
38
|
+
uint64_t *ctx;
|
|
39
|
+
} sha3_256incctx;
|
|
40
|
+
|
|
41
|
+
// Context for incremental API
|
|
42
|
+
typedef struct {
|
|
43
|
+
uint64_t *ctx;
|
|
44
|
+
} sha3_384incctx;
|
|
45
|
+
|
|
46
|
+
// Context for incremental API
|
|
47
|
+
typedef struct {
|
|
48
|
+
uint64_t *ctx;
|
|
49
|
+
} sha3_512incctx;
|
|
50
|
+
|
|
51
|
+
/* Initialize the state and absorb the provided input.
|
|
52
|
+
*
|
|
53
|
+
* This function does not support being called multiple times
|
|
54
|
+
* with the same state.
|
|
55
|
+
*/
|
|
56
|
+
void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen);
|
|
57
|
+
/* Squeeze output out of the sponge.
|
|
58
|
+
*
|
|
59
|
+
* Supports being called multiple times
|
|
60
|
+
*/
|
|
61
|
+
void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state);
|
|
62
|
+
/* Free the state */
|
|
63
|
+
void shake128_ctx_release(shake128ctx *state);
|
|
64
|
+
/* Copy the state. */
|
|
65
|
+
void shake128_ctx_clone(shake128ctx *dest, const shake128ctx *src);
|
|
66
|
+
|
|
67
|
+
/* Initialize incremental hashing API */
|
|
68
|
+
void shake128_inc_init(shake128incctx *state);
|
|
69
|
+
/* Absorb more information into the XOF.
|
|
70
|
+
*
|
|
71
|
+
* Can be called multiple times.
|
|
72
|
+
*/
|
|
73
|
+
void shake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen);
|
|
74
|
+
/* Finalize the XOF for squeezing */
|
|
75
|
+
void shake128_inc_finalize(shake128incctx *state);
|
|
76
|
+
/* Squeeze output out of the sponge.
|
|
77
|
+
*
|
|
78
|
+
* Supports being called multiple times
|
|
79
|
+
*/
|
|
80
|
+
void shake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state);
|
|
81
|
+
/* Copy the context of the SHAKE128 XOF */
|
|
82
|
+
void shake128_inc_ctx_clone(shake128incctx *dest, const shake128incctx *src);
|
|
83
|
+
/* Free the context of the SHAKE128 XOF */
|
|
84
|
+
void shake128_inc_ctx_release(shake128incctx *state);
|
|
85
|
+
|
|
86
|
+
/* Initialize the state and absorb the provided input.
|
|
87
|
+
*
|
|
88
|
+
* This function does not support being called multiple times
|
|
89
|
+
* with the same state.
|
|
90
|
+
*/
|
|
91
|
+
void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen);
|
|
92
|
+
/* Squeeze output out of the sponge.
|
|
93
|
+
*
|
|
94
|
+
* Supports being called multiple times
|
|
95
|
+
*/
|
|
96
|
+
void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state);
|
|
97
|
+
/* Free the context held by this XOF */
|
|
98
|
+
void shake256_ctx_release(shake256ctx *state);
|
|
99
|
+
/* Copy the context held by this XOF */
|
|
100
|
+
void shake256_ctx_clone(shake256ctx *dest, const shake256ctx *src);
|
|
101
|
+
|
|
102
|
+
/* Initialize incremental hashing API */
|
|
103
|
+
void shake256_inc_init(shake256incctx *state);
|
|
104
|
+
void shake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen);
|
|
105
|
+
/* Prepares for squeeze phase */
|
|
106
|
+
void shake256_inc_finalize(shake256incctx *state);
|
|
107
|
+
/* Squeeze output out of the sponge.
|
|
108
|
+
*
|
|
109
|
+
* Supports being called multiple times
|
|
110
|
+
*/
|
|
111
|
+
void shake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state);
|
|
112
|
+
/* Copy the state */
|
|
113
|
+
void shake256_inc_ctx_clone(shake256incctx *dest, const shake256incctx *src);
|
|
114
|
+
/* Free the state */
|
|
115
|
+
void shake256_inc_ctx_release(shake256incctx *state);
|
|
116
|
+
|
|
117
|
+
/* One-stop SHAKE128 call */
|
|
118
|
+
void shake128(uint8_t *output, size_t outlen,
|
|
119
|
+
const uint8_t *input, size_t inlen);
|
|
120
|
+
|
|
121
|
+
/* One-stop SHAKE256 call */
|
|
122
|
+
void shake256(uint8_t *output, size_t outlen,
|
|
123
|
+
const uint8_t *input, size_t inlen);
|
|
124
|
+
|
|
125
|
+
/* Initialize the incremental hashing state */
|
|
126
|
+
void sha3_256_inc_init(sha3_256incctx *state);
|
|
127
|
+
/* Absorb blocks into SHA3 */
|
|
128
|
+
void sha3_256_inc_absorb(sha3_256incctx *state, const uint8_t *input, size_t inlen);
|
|
129
|
+
/* Obtain the output of the function and free `state` */
|
|
130
|
+
void sha3_256_inc_finalize(uint8_t *output, sha3_256incctx *state);
|
|
131
|
+
/* Copy the context */
|
|
132
|
+
void sha3_256_inc_ctx_clone(sha3_256incctx *dest, const sha3_256incctx *src);
|
|
133
|
+
/* Release the state, don't use if `_finalize` has been used */
|
|
134
|
+
void sha3_256_inc_ctx_release(sha3_256incctx *state);
|
|
135
|
+
|
|
136
|
+
void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen);
|
|
137
|
+
|
|
138
|
+
/* Initialize the incremental hashing state */
|
|
139
|
+
void sha3_384_inc_init(sha3_384incctx *state);
|
|
140
|
+
/* Absorb blocks into SHA3 */
|
|
141
|
+
void sha3_384_inc_absorb(sha3_384incctx *state, const uint8_t *input, size_t inlen);
|
|
142
|
+
/* Obtain the output of the function and free `state` */
|
|
143
|
+
void sha3_384_inc_finalize(uint8_t *output, sha3_384incctx *state);
|
|
144
|
+
/* Copy the context */
|
|
145
|
+
void sha3_384_inc_ctx_clone(sha3_384incctx *dest, const sha3_384incctx *src);
|
|
146
|
+
/* Release the state, don't use if `_finalize` has been used */
|
|
147
|
+
void sha3_384_inc_ctx_release(sha3_384incctx *state);
|
|
148
|
+
|
|
149
|
+
/* One-stop SHA3-384 shop */
|
|
150
|
+
void sha3_384(uint8_t *output, const uint8_t *input, size_t inlen);
|
|
151
|
+
|
|
152
|
+
/* Initialize the incremental hashing state */
|
|
153
|
+
void sha3_512_inc_init(sha3_512incctx *state);
|
|
154
|
+
/* Absorb blocks into SHA3 */
|
|
155
|
+
void sha3_512_inc_absorb(sha3_512incctx *state, const uint8_t *input, size_t inlen);
|
|
156
|
+
/* Obtain the output of the function and free `state` */
|
|
157
|
+
void sha3_512_inc_finalize(uint8_t *output, sha3_512incctx *state);
|
|
158
|
+
/* Copy the context */
|
|
159
|
+
void sha3_512_inc_ctx_clone(sha3_512incctx *dest, const sha3_512incctx *src);
|
|
160
|
+
/* Release the state, don't use if `_finalize` has been used */
|
|
161
|
+
void sha3_512_inc_ctx_release(sha3_512incctx *state);
|
|
162
|
+
|
|
163
|
+
/* One-stop SHA3-512 shop */
|
|
164
|
+
void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen);
|
|
165
|
+
|
|
166
|
+
#endif
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA44_CLEAN_API_H
|
|
2
|
+
#define PQCLEAN_MLDSA44_CLEAN_API_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES 1312
|
|
8
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES 2560
|
|
9
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES 2420
|
|
10
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_ALGNAME "ML-DSA-44"
|
|
11
|
+
|
|
12
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk,
|
|
13
|
+
const uint8_t *seed_in);
|
|
14
|
+
|
|
15
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_signature_ctx(uint8_t *sig, size_t *siglen,
|
|
16
|
+
const uint8_t *m, size_t mlen,
|
|
17
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
18
|
+
const uint8_t *sk,
|
|
19
|
+
const uint8_t *rnd_in);
|
|
20
|
+
|
|
21
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_ctx(uint8_t *sm, size_t *smlen,
|
|
22
|
+
const uint8_t *m, size_t mlen,
|
|
23
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
24
|
+
const uint8_t *sk);
|
|
25
|
+
|
|
26
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_verify_ctx(const uint8_t *sig, size_t siglen,
|
|
27
|
+
const uint8_t *m, size_t mlen,
|
|
28
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
29
|
+
const uint8_t *pk);
|
|
30
|
+
|
|
31
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_open_ctx(uint8_t *m, size_t *mlen,
|
|
32
|
+
const uint8_t *sm, size_t smlen,
|
|
33
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
34
|
+
const uint8_t *pk);
|
|
35
|
+
|
|
36
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_signature(uint8_t *sig, size_t *siglen,
|
|
37
|
+
const uint8_t *m, size_t mlen,
|
|
38
|
+
const uint8_t *sk);
|
|
39
|
+
|
|
40
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign(uint8_t *sm, size_t *smlen,
|
|
41
|
+
const uint8_t *m, size_t mlen,
|
|
42
|
+
const uint8_t *sk);
|
|
43
|
+
|
|
44
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_verify(const uint8_t *sig, size_t siglen,
|
|
45
|
+
const uint8_t *m, size_t mlen,
|
|
46
|
+
const uint8_t *pk);
|
|
47
|
+
|
|
48
|
+
int PQCLEAN_MLDSA44_CLEAN_crypto_sign_open(uint8_t *m, size_t *mlen,
|
|
49
|
+
const uint8_t *sm, size_t smlen,
|
|
50
|
+
const uint8_t *pk);
|
|
51
|
+
|
|
52
|
+
#endif
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#include "ntt.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "reduce.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
static const int32_t zetas[N] = {
|
|
7
|
+
0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
|
|
8
|
+
1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
|
|
9
|
+
2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
|
|
10
|
+
-2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
|
|
11
|
+
2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
|
|
12
|
+
-3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
|
|
13
|
+
-1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
|
|
14
|
+
811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
|
|
15
|
+
-3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
|
|
16
|
+
-1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
|
|
17
|
+
3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
|
|
18
|
+
-671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
|
|
19
|
+
-3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
|
|
20
|
+
-3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
|
|
21
|
+
189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
|
|
22
|
+
1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
|
|
23
|
+
2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
|
|
24
|
+
266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
|
|
25
|
+
900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
|
|
26
|
+
-655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
|
|
27
|
+
342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
|
|
28
|
+
2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
|
|
29
|
+
-3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
|
|
30
|
+
-1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
|
|
31
|
+
-1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
|
|
32
|
+
-542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
|
|
33
|
+
-2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
|
|
34
|
+
-3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
|
|
35
|
+
-3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
|
|
36
|
+
-426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
|
|
37
|
+
-2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
|
|
38
|
+
-554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/*************************************************
|
|
42
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_ntt
|
|
43
|
+
*
|
|
44
|
+
* Description: Forward NTT, in-place. No modular reduction is performed after
|
|
45
|
+
* additions or subtractions. Output vector is in bitreversed order.
|
|
46
|
+
*
|
|
47
|
+
* Arguments: - uint32_t p[N]: input/output coefficient array
|
|
48
|
+
**************************************************/
|
|
49
|
+
void PQCLEAN_MLDSA44_CLEAN_ntt(int32_t a[N]) {
|
|
50
|
+
unsigned int len, start, j, k;
|
|
51
|
+
int32_t zeta, t;
|
|
52
|
+
|
|
53
|
+
k = 0;
|
|
54
|
+
for (len = 128; len > 0; len >>= 1) {
|
|
55
|
+
for (start = 0; start < N; start = j + len) {
|
|
56
|
+
zeta = zetas[++k];
|
|
57
|
+
for (j = start; j < start + len; ++j) {
|
|
58
|
+
t = PQCLEAN_MLDSA44_CLEAN_montgomery_reduce((int64_t)zeta * a[j + len]);
|
|
59
|
+
a[j + len] = a[j] - t;
|
|
60
|
+
a[j] = a[j] + t;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*************************************************
|
|
67
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_invntt_tomont
|
|
68
|
+
*
|
|
69
|
+
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
|
|
70
|
+
* In-place. No modular reductions after additions or
|
|
71
|
+
* subtractions; input coefficients need to be smaller than
|
|
72
|
+
* Q in absolute value. Output coefficient are smaller than Q in
|
|
73
|
+
* absolute value.
|
|
74
|
+
*
|
|
75
|
+
* Arguments: - uint32_t p[N]: input/output coefficient array
|
|
76
|
+
**************************************************/
|
|
77
|
+
void PQCLEAN_MLDSA44_CLEAN_invntt_tomont(int32_t a[N]) {
|
|
78
|
+
unsigned int start, len, j, k;
|
|
79
|
+
int32_t t, zeta;
|
|
80
|
+
const int32_t f = 41978; // mont^2/256
|
|
81
|
+
|
|
82
|
+
k = 256;
|
|
83
|
+
for (len = 1; len < N; len <<= 1) {
|
|
84
|
+
for (start = 0; start < N; start = j + len) {
|
|
85
|
+
zeta = -zetas[--k];
|
|
86
|
+
for (j = start; j < start + len; ++j) {
|
|
87
|
+
t = a[j];
|
|
88
|
+
a[j] = t + a[j + len];
|
|
89
|
+
a[j + len] = t - a[j + len];
|
|
90
|
+
a[j + len] = PQCLEAN_MLDSA44_CLEAN_montgomery_reduce((int64_t)zeta * a[j + len]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (j = 0; j < N; ++j) {
|
|
96
|
+
a[j] = PQCLEAN_MLDSA44_CLEAN_montgomery_reduce((int64_t)f * a[j]);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#include "packing.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "poly.h"
|
|
4
|
+
#include "polyvec.h"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/*************************************************
|
|
8
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_pack_pk
|
|
9
|
+
*
|
|
10
|
+
* Description: Bit-pack public key pk = (rho, t1).
|
|
11
|
+
*
|
|
12
|
+
* Arguments: - uint8_t pk[]: output byte array
|
|
13
|
+
* - const uint8_t rho[]: byte array containing rho
|
|
14
|
+
* - const polyveck *t1: pointer to vector t1
|
|
15
|
+
**************************************************/
|
|
16
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_pk(uint8_t pk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES],
|
|
17
|
+
const uint8_t rho[SEEDBYTES],
|
|
18
|
+
const polyveck *t1) {
|
|
19
|
+
unsigned int i;
|
|
20
|
+
|
|
21
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
22
|
+
pk[i] = rho[i];
|
|
23
|
+
}
|
|
24
|
+
pk += SEEDBYTES;
|
|
25
|
+
|
|
26
|
+
for (i = 0; i < K; ++i) {
|
|
27
|
+
PQCLEAN_MLDSA44_CLEAN_polyt1_pack(pk + i * POLYT1_PACKEDBYTES, &t1->vec[i]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*************************************************
|
|
32
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_unpack_pk
|
|
33
|
+
*
|
|
34
|
+
* Description: Unpack public key pk = (rho, t1).
|
|
35
|
+
*
|
|
36
|
+
* Arguments: - const uint8_t rho[]: output byte array for rho
|
|
37
|
+
* - const polyveck *t1: pointer to output vector t1
|
|
38
|
+
* - uint8_t pk[]: byte array containing bit-packed pk
|
|
39
|
+
**************************************************/
|
|
40
|
+
void PQCLEAN_MLDSA44_CLEAN_unpack_pk(uint8_t rho[SEEDBYTES],
|
|
41
|
+
polyveck *t1,
|
|
42
|
+
const uint8_t pk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES]) {
|
|
43
|
+
unsigned int i;
|
|
44
|
+
|
|
45
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
46
|
+
rho[i] = pk[i];
|
|
47
|
+
}
|
|
48
|
+
pk += SEEDBYTES;
|
|
49
|
+
|
|
50
|
+
for (i = 0; i < K; ++i) {
|
|
51
|
+
PQCLEAN_MLDSA44_CLEAN_polyt1_unpack(&t1->vec[i], pk + i * POLYT1_PACKEDBYTES);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/*************************************************
|
|
56
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_pack_sk
|
|
57
|
+
*
|
|
58
|
+
* Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
|
|
59
|
+
*
|
|
60
|
+
* Arguments: - uint8_t sk[]: output byte array
|
|
61
|
+
* - const uint8_t rho[]: byte array containing rho
|
|
62
|
+
* - const uint8_t tr[]: byte array containing tr
|
|
63
|
+
* - const uint8_t key[]: byte array containing key
|
|
64
|
+
* - const polyveck *t0: pointer to vector t0
|
|
65
|
+
* - const polyvecl *s1: pointer to vector s1
|
|
66
|
+
* - const polyveck *s2: pointer to vector s2
|
|
67
|
+
**************************************************/
|
|
68
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_sk(uint8_t sk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES],
|
|
69
|
+
const uint8_t rho[SEEDBYTES],
|
|
70
|
+
const uint8_t tr[TRBYTES],
|
|
71
|
+
const uint8_t key[SEEDBYTES],
|
|
72
|
+
const polyveck *t0,
|
|
73
|
+
const polyvecl *s1,
|
|
74
|
+
const polyveck *s2) {
|
|
75
|
+
unsigned int i;
|
|
76
|
+
|
|
77
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
78
|
+
sk[i] = rho[i];
|
|
79
|
+
}
|
|
80
|
+
sk += SEEDBYTES;
|
|
81
|
+
|
|
82
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
83
|
+
sk[i] = key[i];
|
|
84
|
+
}
|
|
85
|
+
sk += SEEDBYTES;
|
|
86
|
+
|
|
87
|
+
for (i = 0; i < TRBYTES; ++i) {
|
|
88
|
+
sk[i] = tr[i];
|
|
89
|
+
}
|
|
90
|
+
sk += TRBYTES;
|
|
91
|
+
|
|
92
|
+
for (i = 0; i < L; ++i) {
|
|
93
|
+
PQCLEAN_MLDSA44_CLEAN_polyeta_pack(sk + i * POLYETA_PACKEDBYTES, &s1->vec[i]);
|
|
94
|
+
}
|
|
95
|
+
sk += L * POLYETA_PACKEDBYTES;
|
|
96
|
+
|
|
97
|
+
for (i = 0; i < K; ++i) {
|
|
98
|
+
PQCLEAN_MLDSA44_CLEAN_polyeta_pack(sk + i * POLYETA_PACKEDBYTES, &s2->vec[i]);
|
|
99
|
+
}
|
|
100
|
+
sk += K * POLYETA_PACKEDBYTES;
|
|
101
|
+
|
|
102
|
+
for (i = 0; i < K; ++i) {
|
|
103
|
+
PQCLEAN_MLDSA44_CLEAN_polyt0_pack(sk + i * POLYT0_PACKEDBYTES, &t0->vec[i]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/*************************************************
|
|
108
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_unpack_sk
|
|
109
|
+
*
|
|
110
|
+
* Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
|
|
111
|
+
*
|
|
112
|
+
* Arguments: - const uint8_t rho[]: output byte array for rho
|
|
113
|
+
* - const uint8_t tr[]: output byte array for tr
|
|
114
|
+
* - const uint8_t key[]: output byte array for key
|
|
115
|
+
* - const polyveck *t0: pointer to output vector t0
|
|
116
|
+
* - const polyvecl *s1: pointer to output vector s1
|
|
117
|
+
* - const polyveck *s2: pointer to output vector s2
|
|
118
|
+
* - uint8_t sk[]: byte array containing bit-packed sk
|
|
119
|
+
**************************************************/
|
|
120
|
+
void PQCLEAN_MLDSA44_CLEAN_unpack_sk(uint8_t rho[SEEDBYTES],
|
|
121
|
+
uint8_t tr[TRBYTES],
|
|
122
|
+
uint8_t key[SEEDBYTES],
|
|
123
|
+
polyveck *t0,
|
|
124
|
+
polyvecl *s1,
|
|
125
|
+
polyveck *s2,
|
|
126
|
+
const uint8_t sk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES]) {
|
|
127
|
+
unsigned int i;
|
|
128
|
+
|
|
129
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
130
|
+
rho[i] = sk[i];
|
|
131
|
+
}
|
|
132
|
+
sk += SEEDBYTES;
|
|
133
|
+
|
|
134
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
135
|
+
key[i] = sk[i];
|
|
136
|
+
}
|
|
137
|
+
sk += SEEDBYTES;
|
|
138
|
+
|
|
139
|
+
for (i = 0; i < TRBYTES; ++i) {
|
|
140
|
+
tr[i] = sk[i];
|
|
141
|
+
}
|
|
142
|
+
sk += TRBYTES;
|
|
143
|
+
|
|
144
|
+
for (i = 0; i < L; ++i) {
|
|
145
|
+
PQCLEAN_MLDSA44_CLEAN_polyeta_unpack(&s1->vec[i], sk + i * POLYETA_PACKEDBYTES);
|
|
146
|
+
}
|
|
147
|
+
sk += L * POLYETA_PACKEDBYTES;
|
|
148
|
+
|
|
149
|
+
for (i = 0; i < K; ++i) {
|
|
150
|
+
PQCLEAN_MLDSA44_CLEAN_polyeta_unpack(&s2->vec[i], sk + i * POLYETA_PACKEDBYTES);
|
|
151
|
+
}
|
|
152
|
+
sk += K * POLYETA_PACKEDBYTES;
|
|
153
|
+
|
|
154
|
+
for (i = 0; i < K; ++i) {
|
|
155
|
+
PQCLEAN_MLDSA44_CLEAN_polyt0_unpack(&t0->vec[i], sk + i * POLYT0_PACKEDBYTES);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*************************************************
|
|
160
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_pack_sig
|
|
161
|
+
*
|
|
162
|
+
* Description: Bit-pack signature sig = (c, z, h).
|
|
163
|
+
*
|
|
164
|
+
* Arguments: - uint8_t sig[]: output byte array
|
|
165
|
+
* - const uint8_t *c: pointer to challenge hash length SEEDBYTES
|
|
166
|
+
* - const polyvecl *z: pointer to vector z
|
|
167
|
+
* - const polyveck *h: pointer to hint vector h
|
|
168
|
+
**************************************************/
|
|
169
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_sig(uint8_t sig[PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES],
|
|
170
|
+
const uint8_t c[CTILDEBYTES],
|
|
171
|
+
const polyvecl *z,
|
|
172
|
+
const polyveck *h) {
|
|
173
|
+
unsigned int i, j, k;
|
|
174
|
+
|
|
175
|
+
for (i = 0; i < CTILDEBYTES; ++i) {
|
|
176
|
+
sig[i] = c[i];
|
|
177
|
+
}
|
|
178
|
+
sig += CTILDEBYTES;
|
|
179
|
+
|
|
180
|
+
for (i = 0; i < L; ++i) {
|
|
181
|
+
PQCLEAN_MLDSA44_CLEAN_polyz_pack(sig + i * POLYZ_PACKEDBYTES, &z->vec[i]);
|
|
182
|
+
}
|
|
183
|
+
sig += L * POLYZ_PACKEDBYTES;
|
|
184
|
+
|
|
185
|
+
/* Encode h */
|
|
186
|
+
for (i = 0; i < OMEGA + K; ++i) {
|
|
187
|
+
sig[i] = 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
k = 0;
|
|
191
|
+
for (i = 0; i < K; ++i) {
|
|
192
|
+
for (j = 0; j < N; ++j) {
|
|
193
|
+
if (h->vec[i].coeffs[j] != 0) {
|
|
194
|
+
sig[k++] = (uint8_t) j;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
sig[OMEGA + i] = (uint8_t) k;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/*************************************************
|
|
203
|
+
* Name: PQCLEAN_MLDSA44_CLEAN_unpack_sig
|
|
204
|
+
*
|
|
205
|
+
* Description: Unpack signature sig = (c, z, h).
|
|
206
|
+
*
|
|
207
|
+
* Arguments: - uint8_t *c: pointer to output challenge hash
|
|
208
|
+
* - polyvecl *z: pointer to output vector z
|
|
209
|
+
* - polyveck *h: pointer to output hint vector h
|
|
210
|
+
* - const uint8_t sig[]: byte array containing
|
|
211
|
+
* bit-packed signature
|
|
212
|
+
*
|
|
213
|
+
* Returns 1 in case of malformed signature; otherwise 0.
|
|
214
|
+
**************************************************/
|
|
215
|
+
int PQCLEAN_MLDSA44_CLEAN_unpack_sig(uint8_t c[CTILDEBYTES],
|
|
216
|
+
polyvecl *z,
|
|
217
|
+
polyveck *h,
|
|
218
|
+
const uint8_t sig[PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES]) {
|
|
219
|
+
unsigned int i, j, k;
|
|
220
|
+
|
|
221
|
+
for (i = 0; i < CTILDEBYTES; ++i) {
|
|
222
|
+
c[i] = sig[i];
|
|
223
|
+
}
|
|
224
|
+
sig += CTILDEBYTES;
|
|
225
|
+
|
|
226
|
+
for (i = 0; i < L; ++i) {
|
|
227
|
+
PQCLEAN_MLDSA44_CLEAN_polyz_unpack(&z->vec[i], sig + i * POLYZ_PACKEDBYTES);
|
|
228
|
+
}
|
|
229
|
+
sig += L * POLYZ_PACKEDBYTES;
|
|
230
|
+
|
|
231
|
+
/* Decode h */
|
|
232
|
+
k = 0;
|
|
233
|
+
for (i = 0; i < K; ++i) {
|
|
234
|
+
for (j = 0; j < N; ++j) {
|
|
235
|
+
h->vec[i].coeffs[j] = 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA) {
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for (j = k; j < sig[OMEGA + i]; ++j) {
|
|
243
|
+
/* Coefficients are ordered for strong unforgeability */
|
|
244
|
+
if (j > k && sig[j] <= sig[j - 1]) {
|
|
245
|
+
return 1;
|
|
246
|
+
}
|
|
247
|
+
h->vec[i].coeffs[sig[j]] = 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
k = sig[OMEGA + i];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Extra indices are zero for strong unforgeability */
|
|
254
|
+
for (j = k; j < OMEGA; ++j) {
|
|
255
|
+
if (sig[j]) {
|
|
256
|
+
return 1;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return 0;
|
|
261
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA44_CLEAN_PACKING_H
|
|
2
|
+
#define PQCLEAN_MLDSA44_CLEAN_PACKING_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include "polyvec.h"
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_pk(uint8_t pk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES], const uint8_t rho[SEEDBYTES], const polyveck *t1);
|
|
8
|
+
|
|
9
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_sk(uint8_t sk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES],
|
|
10
|
+
const uint8_t rho[SEEDBYTES],
|
|
11
|
+
const uint8_t tr[TRBYTES],
|
|
12
|
+
const uint8_t key[SEEDBYTES],
|
|
13
|
+
const polyveck *t0,
|
|
14
|
+
const polyvecl *s1,
|
|
15
|
+
const polyveck *s2);
|
|
16
|
+
|
|
17
|
+
void PQCLEAN_MLDSA44_CLEAN_pack_sig(uint8_t sig[PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES], const uint8_t c[CTILDEBYTES], const polyvecl *z, const polyveck *h);
|
|
18
|
+
|
|
19
|
+
void PQCLEAN_MLDSA44_CLEAN_unpack_pk(uint8_t rho[SEEDBYTES], polyveck *t1, const uint8_t pk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES]);
|
|
20
|
+
|
|
21
|
+
void PQCLEAN_MLDSA44_CLEAN_unpack_sk(uint8_t rho[SEEDBYTES],
|
|
22
|
+
uint8_t tr[TRBYTES],
|
|
23
|
+
uint8_t key[SEEDBYTES],
|
|
24
|
+
polyveck *t0,
|
|
25
|
+
polyvecl *s1,
|
|
26
|
+
polyveck *s2,
|
|
27
|
+
const uint8_t sk[PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES]);
|
|
28
|
+
|
|
29
|
+
int PQCLEAN_MLDSA44_CLEAN_unpack_sig(uint8_t c[CTILDEBYTES], polyvecl *z, polyveck *h, const uint8_t sig[PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES]);
|
|
30
|
+
|
|
31
|
+
#endif
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA44_CLEAN_PARAMS_H
|
|
2
|
+
#define PQCLEAN_MLDSA44_CLEAN_PARAMS_H
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
#define SEEDBYTES 32
|
|
7
|
+
#define CRHBYTES 64
|
|
8
|
+
#define TRBYTES 64
|
|
9
|
+
#define RNDBYTES 32
|
|
10
|
+
#define N 256
|
|
11
|
+
#define Q 8380417
|
|
12
|
+
#define D 13
|
|
13
|
+
#define ROOT_OF_UNITY 1753
|
|
14
|
+
|
|
15
|
+
#define K 4
|
|
16
|
+
#define L 4
|
|
17
|
+
#define ETA 2
|
|
18
|
+
#define TAU 39
|
|
19
|
+
#define BETA 78
|
|
20
|
+
#define GAMMA1 (1 << 17)
|
|
21
|
+
#define GAMMA2 ((Q-1)/88)
|
|
22
|
+
#define OMEGA 80
|
|
23
|
+
#define CTILDEBYTES 32
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#define POLYT1_PACKEDBYTES 320
|
|
27
|
+
#define POLYT0_PACKEDBYTES 416
|
|
28
|
+
#define POLYVECH_PACKEDBYTES (OMEGA + K)
|
|
29
|
+
|
|
30
|
+
#define POLYZ_PACKEDBYTES 576
|
|
31
|
+
|
|
32
|
+
#define POLYW1_PACKEDBYTES 192
|
|
33
|
+
|
|
34
|
+
#define POLYETA_PACKEDBYTES 96
|
|
35
|
+
|
|
36
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_PUBLICKEYBYTES (SEEDBYTES + K*POLYT1_PACKEDBYTES)
|
|
37
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_SECRETKEYBYTES (2*SEEDBYTES \
|
|
38
|
+
+ TRBYTES \
|
|
39
|
+
+ L*POLYETA_PACKEDBYTES \
|
|
40
|
+
+ K*POLYETA_PACKEDBYTES \
|
|
41
|
+
+ K*POLYT0_PACKEDBYTES)
|
|
42
|
+
#define PQCLEAN_MLDSA44_CLEAN_CRYPTO_BYTES (CTILDEBYTES + L*POLYZ_PACKEDBYTES + POLYVECH_PACKEDBYTES)
|
|
43
|
+
|
|
44
|
+
#endif
|