pq_crypto 0.3.2 → 0.4.2
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 +4 -4
- data/.github/workflows/ci.yml +56 -0
- data/CHANGELOG.md +37 -0
- data/GET_STARTED.md +361 -40
- data/README.md +58 -241
- data/SECURITY.md +101 -82
- data/ext/pqcrypto/extconf.rb +40 -7
- data/ext/pqcrypto/mldsa_api.h +71 -1
- data/ext/pqcrypto/mlkem_api.h +24 -0
- data/ext/pqcrypto/pq_externalmu.c +14 -1
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +484 -81
- data/ext/pqcrypto/pqcrypto_secure.c +179 -72
- data/ext/pqcrypto/pqcrypto_secure.h +87 -7
- data/ext/pqcrypto/pqcrypto_version.h +7 -0
- data/ext/pqcrypto/vendor/.vendored +1 -1
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.c +83 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.c +311 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.c +198 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.c +108 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.c +299 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.c +188 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.c +848 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric.h +34 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.c +823 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.c +92 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric.h +34 -0
- data/lib/pq_crypto/algorithm_registry.rb +200 -0
- data/lib/pq_crypto/hybrid_kem.rb +1 -12
- data/lib/pq_crypto/kem.rb +104 -13
- data/lib/pq_crypto/pkcs8.rb +387 -0
- data/lib/pq_crypto/serialization.rb +1 -14
- data/lib/pq_crypto/signature.rb +123 -17
- data/lib/pq_crypto/spki.rb +131 -0
- data/lib/pq_crypto/version.rb +1 -1
- data/lib/pq_crypto.rb +78 -19
- data/script/vendor_libs.rb +4 -0
- metadata +95 -3
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#include "indcpa.h"
|
|
2
|
+
#include "ntt.h"
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include "poly.h"
|
|
5
|
+
#include "polyvec.h"
|
|
6
|
+
#include "randombytes.h"
|
|
7
|
+
#include "symmetric.h"
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
|
|
12
|
+
/*************************************************
|
|
13
|
+
* Name: pack_pk
|
|
14
|
+
*
|
|
15
|
+
* Description: Serialize the public key as concatenation of the
|
|
16
|
+
* serialized vector of polynomials pk
|
|
17
|
+
* and the public seed used to generate the matrix A.
|
|
18
|
+
*
|
|
19
|
+
* Arguments: uint8_t *r: pointer to the output serialized public key
|
|
20
|
+
* polyvec *pk: pointer to the input public-key polyvec
|
|
21
|
+
* const uint8_t *seed: pointer to the input public seed
|
|
22
|
+
**************************************************/
|
|
23
|
+
static void pack_pk(uint8_t r[KYBER_INDCPA_PUBLICKEYBYTES],
|
|
24
|
+
polyvec *pk,
|
|
25
|
+
const uint8_t seed[KYBER_SYMBYTES]) {
|
|
26
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes(r, pk);
|
|
27
|
+
memcpy(r + KYBER_POLYVECBYTES, seed, KYBER_SYMBYTES);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*************************************************
|
|
31
|
+
* Name: unpack_pk
|
|
32
|
+
*
|
|
33
|
+
* Description: De-serialize public key from a byte array;
|
|
34
|
+
* approximate inverse of pack_pk
|
|
35
|
+
*
|
|
36
|
+
* Arguments: - polyvec *pk: pointer to output public-key polynomial vector
|
|
37
|
+
* - uint8_t *seed: pointer to output seed to generate matrix A
|
|
38
|
+
* - const uint8_t *packedpk: pointer to input serialized public key
|
|
39
|
+
**************************************************/
|
|
40
|
+
static void unpack_pk(polyvec *pk,
|
|
41
|
+
uint8_t seed[KYBER_SYMBYTES],
|
|
42
|
+
const uint8_t packedpk[KYBER_INDCPA_PUBLICKEYBYTES]) {
|
|
43
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_frombytes(pk, packedpk);
|
|
44
|
+
memcpy(seed, packedpk + KYBER_POLYVECBYTES, KYBER_SYMBYTES);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*************************************************
|
|
48
|
+
* Name: pack_sk
|
|
49
|
+
*
|
|
50
|
+
* Description: Serialize the secret key
|
|
51
|
+
*
|
|
52
|
+
* Arguments: - uint8_t *r: pointer to output serialized secret key
|
|
53
|
+
* - polyvec *sk: pointer to input vector of polynomials (secret key)
|
|
54
|
+
**************************************************/
|
|
55
|
+
static void pack_sk(uint8_t r[KYBER_INDCPA_SECRETKEYBYTES], polyvec *sk) {
|
|
56
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes(r, sk);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/*************************************************
|
|
60
|
+
* Name: unpack_sk
|
|
61
|
+
*
|
|
62
|
+
* Description: De-serialize the secret key; inverse of pack_sk
|
|
63
|
+
*
|
|
64
|
+
* Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key)
|
|
65
|
+
* - const uint8_t *packedsk: pointer to input serialized secret key
|
|
66
|
+
**************************************************/
|
|
67
|
+
static void unpack_sk(polyvec *sk, const uint8_t packedsk[KYBER_INDCPA_SECRETKEYBYTES]) {
|
|
68
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_frombytes(sk, packedsk);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/*************************************************
|
|
72
|
+
* Name: pack_ciphertext
|
|
73
|
+
*
|
|
74
|
+
* Description: Serialize the ciphertext as concatenation of the
|
|
75
|
+
* compressed and serialized vector of polynomials b
|
|
76
|
+
* and the compressed and serialized polynomial v
|
|
77
|
+
*
|
|
78
|
+
* Arguments: uint8_t *r: pointer to the output serialized ciphertext
|
|
79
|
+
* poly *pk: pointer to the input vector of polynomials b
|
|
80
|
+
* poly *v: pointer to the input polynomial v
|
|
81
|
+
**************************************************/
|
|
82
|
+
static void pack_ciphertext(uint8_t r[KYBER_INDCPA_BYTES], polyvec *b, poly *v) {
|
|
83
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_compress(r, b);
|
|
84
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/*************************************************
|
|
88
|
+
* Name: unpack_ciphertext
|
|
89
|
+
*
|
|
90
|
+
* Description: De-serialize and decompress ciphertext from a byte array;
|
|
91
|
+
* approximate inverse of pack_ciphertext
|
|
92
|
+
*
|
|
93
|
+
* Arguments: - polyvec *b: pointer to the output vector of polynomials b
|
|
94
|
+
* - poly *v: pointer to the output polynomial v
|
|
95
|
+
* - const uint8_t *c: pointer to the input serialized ciphertext
|
|
96
|
+
**************************************************/
|
|
97
|
+
static void unpack_ciphertext(polyvec *b, poly *v, const uint8_t c[KYBER_INDCPA_BYTES]) {
|
|
98
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_decompress(b, c);
|
|
99
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/*************************************************
|
|
103
|
+
* Name: rej_uniform
|
|
104
|
+
*
|
|
105
|
+
* Description: Run rejection sampling on uniform random bytes to generate
|
|
106
|
+
* uniform random integers mod q
|
|
107
|
+
*
|
|
108
|
+
* Arguments: - int16_t *r: pointer to output buffer
|
|
109
|
+
* - unsigned int len: requested number of 16-bit integers (uniform mod q)
|
|
110
|
+
* - const uint8_t *buf: pointer to input buffer (assumed to be uniformly random bytes)
|
|
111
|
+
* - unsigned int buflen: length of input buffer in bytes
|
|
112
|
+
*
|
|
113
|
+
* Returns number of sampled 16-bit integers (at most len)
|
|
114
|
+
**************************************************/
|
|
115
|
+
static unsigned int rej_uniform(int16_t *r,
|
|
116
|
+
unsigned int len,
|
|
117
|
+
const uint8_t *buf,
|
|
118
|
+
unsigned int buflen) {
|
|
119
|
+
unsigned int ctr, pos;
|
|
120
|
+
uint16_t val0, val1;
|
|
121
|
+
|
|
122
|
+
ctr = pos = 0;
|
|
123
|
+
while (ctr < len && pos + 3 <= buflen) {
|
|
124
|
+
val0 = ((buf[pos + 0] >> 0) | ((uint16_t)buf[pos + 1] << 8)) & 0xFFF;
|
|
125
|
+
val1 = ((buf[pos + 1] >> 4) | ((uint16_t)buf[pos + 2] << 4)) & 0xFFF;
|
|
126
|
+
pos += 3;
|
|
127
|
+
|
|
128
|
+
if (val0 < KYBER_Q) {
|
|
129
|
+
r[ctr++] = val0;
|
|
130
|
+
}
|
|
131
|
+
if (ctr < len && val1 < KYBER_Q) {
|
|
132
|
+
r[ctr++] = val1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return ctr;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#define gen_a(A,B) PQCLEAN_MLKEM1024_CLEAN_gen_matrix(A,B,0)
|
|
140
|
+
#define gen_at(A,B) PQCLEAN_MLKEM1024_CLEAN_gen_matrix(A,B,1)
|
|
141
|
+
|
|
142
|
+
/*************************************************
|
|
143
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_gen_matrix
|
|
144
|
+
*
|
|
145
|
+
* Description: Deterministically generate matrix A (or the transpose of A)
|
|
146
|
+
* from a seed. Entries of the matrix are polynomials that look
|
|
147
|
+
* uniformly random. Performs rejection sampling on output of
|
|
148
|
+
* a XOF
|
|
149
|
+
*
|
|
150
|
+
* Arguments: - polyvec *a: pointer to ouptput matrix A
|
|
151
|
+
* - const uint8_t *seed: pointer to input seed
|
|
152
|
+
* - int transposed: boolean deciding whether A or A^T is generated
|
|
153
|
+
**************************************************/
|
|
154
|
+
|
|
155
|
+
#define GEN_MATRIX_NBLOCKS ((12*KYBER_N/8*(1 << 12)/KYBER_Q + XOF_BLOCKBYTES)/XOF_BLOCKBYTES)
|
|
156
|
+
// Not static for benchmarking
|
|
157
|
+
void PQCLEAN_MLKEM1024_CLEAN_gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed) {
|
|
158
|
+
unsigned int ctr, i, j;
|
|
159
|
+
unsigned int buflen;
|
|
160
|
+
uint8_t buf[GEN_MATRIX_NBLOCKS * XOF_BLOCKBYTES];
|
|
161
|
+
xof_state state;
|
|
162
|
+
|
|
163
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
164
|
+
for (j = 0; j < KYBER_K; j++) {
|
|
165
|
+
if (transposed) {
|
|
166
|
+
xof_absorb(&state, seed, (uint8_t)i, (uint8_t)j);
|
|
167
|
+
} else {
|
|
168
|
+
xof_absorb(&state, seed, (uint8_t)j, (uint8_t)i);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
xof_squeezeblocks(buf, GEN_MATRIX_NBLOCKS, &state);
|
|
172
|
+
buflen = GEN_MATRIX_NBLOCKS * XOF_BLOCKBYTES;
|
|
173
|
+
ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, buflen);
|
|
174
|
+
|
|
175
|
+
while (ctr < KYBER_N) {
|
|
176
|
+
xof_squeezeblocks(buf, 1, &state);
|
|
177
|
+
buflen = XOF_BLOCKBYTES;
|
|
178
|
+
ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, buflen);
|
|
179
|
+
}
|
|
180
|
+
xof_ctx_release(&state);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*************************************************
|
|
186
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_indcpa_keypair_derand
|
|
187
|
+
*
|
|
188
|
+
* Description: Generates public and private key for the CPA-secure
|
|
189
|
+
* public-key encryption scheme underlying Kyber
|
|
190
|
+
*
|
|
191
|
+
* Arguments: - uint8_t *pk: pointer to output public key
|
|
192
|
+
* (of length KYBER_INDCPA_PUBLICKEYBYTES bytes)
|
|
193
|
+
* - uint8_t *sk: pointer to output private key
|
|
194
|
+
* (of length KYBER_INDCPA_SECRETKEYBYTES bytes)
|
|
195
|
+
* - const uint8_t *coins: pointer to input randomness
|
|
196
|
+
* (of length KYBER_SYMBYTES bytes)
|
|
197
|
+
**************************************************/
|
|
198
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
|
|
199
|
+
uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES],
|
|
200
|
+
const uint8_t coins[KYBER_SYMBYTES]) {
|
|
201
|
+
unsigned int i;
|
|
202
|
+
uint8_t buf[2 * KYBER_SYMBYTES];
|
|
203
|
+
const uint8_t *publicseed = buf;
|
|
204
|
+
const uint8_t *noiseseed = buf + KYBER_SYMBYTES;
|
|
205
|
+
uint8_t nonce = 0;
|
|
206
|
+
polyvec a[KYBER_K], e, pkpv, skpv;
|
|
207
|
+
|
|
208
|
+
memcpy(buf, coins, KYBER_SYMBYTES);
|
|
209
|
+
buf[KYBER_SYMBYTES] = KYBER_K;
|
|
210
|
+
hash_g(buf, buf, KYBER_SYMBYTES + 1);
|
|
211
|
+
|
|
212
|
+
gen_a(a, publicseed);
|
|
213
|
+
|
|
214
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
215
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1(&skpv.vec[i], noiseseed, nonce++);
|
|
216
|
+
}
|
|
217
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
218
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1(&e.vec[i], noiseseed, nonce++);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(&skpv);
|
|
222
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(&e);
|
|
223
|
+
|
|
224
|
+
// matrix-vector multiplication
|
|
225
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
226
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(&pkpv.vec[i], &a[i], &skpv);
|
|
227
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_tomont(&pkpv.vec[i]);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_add(&pkpv, &pkpv, &e);
|
|
231
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_reduce(&pkpv);
|
|
232
|
+
|
|
233
|
+
pack_sk(sk, &skpv);
|
|
234
|
+
pack_pk(pk, &pkpv, publicseed);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
/*************************************************
|
|
239
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_indcpa_enc
|
|
240
|
+
*
|
|
241
|
+
* Description: Encryption function of the CPA-secure
|
|
242
|
+
* public-key encryption scheme underlying Kyber.
|
|
243
|
+
*
|
|
244
|
+
* Arguments: - uint8_t *c: pointer to output ciphertext
|
|
245
|
+
* (of length KYBER_INDCPA_BYTES bytes)
|
|
246
|
+
* - const uint8_t *m: pointer to input message
|
|
247
|
+
* (of length KYBER_INDCPA_MSGBYTES bytes)
|
|
248
|
+
* - const uint8_t *pk: pointer to input public key
|
|
249
|
+
* (of length KYBER_INDCPA_PUBLICKEYBYTES)
|
|
250
|
+
* - const uint8_t *coins: pointer to input random coins used as seed
|
|
251
|
+
* (of length KYBER_SYMBYTES) to deterministically
|
|
252
|
+
* generate all randomness
|
|
253
|
+
**************************************************/
|
|
254
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES],
|
|
255
|
+
const uint8_t m[KYBER_INDCPA_MSGBYTES],
|
|
256
|
+
const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
|
|
257
|
+
const uint8_t coins[KYBER_SYMBYTES]) {
|
|
258
|
+
unsigned int i;
|
|
259
|
+
uint8_t seed[KYBER_SYMBYTES];
|
|
260
|
+
uint8_t nonce = 0;
|
|
261
|
+
polyvec sp, pkpv, ep, at[KYBER_K], b;
|
|
262
|
+
poly v, k, epp;
|
|
263
|
+
|
|
264
|
+
unpack_pk(&pkpv, seed, pk);
|
|
265
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_frommsg(&k, m);
|
|
266
|
+
gen_at(at, seed);
|
|
267
|
+
|
|
268
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
269
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1(sp.vec + i, coins, nonce++);
|
|
270
|
+
}
|
|
271
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
272
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta2(ep.vec + i, coins, nonce++);
|
|
273
|
+
}
|
|
274
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta2(&epp, coins, nonce++);
|
|
275
|
+
|
|
276
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(&sp);
|
|
277
|
+
|
|
278
|
+
// matrix-vector multiplication
|
|
279
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
280
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(&b.vec[i], &at[i], &sp);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(&v, &pkpv, &sp);
|
|
284
|
+
|
|
285
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_invntt_tomont(&b);
|
|
286
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont(&v);
|
|
287
|
+
|
|
288
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_add(&b, &b, &ep);
|
|
289
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_add(&v, &v, &epp);
|
|
290
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_add(&v, &v, &k);
|
|
291
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_reduce(&b);
|
|
292
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_reduce(&v);
|
|
293
|
+
|
|
294
|
+
pack_ciphertext(c, &b, &v);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/*************************************************
|
|
298
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_indcpa_dec
|
|
299
|
+
*
|
|
300
|
+
* Description: Decryption function of the CPA-secure
|
|
301
|
+
* public-key encryption scheme underlying Kyber.
|
|
302
|
+
*
|
|
303
|
+
* Arguments: - uint8_t *m: pointer to output decrypted message
|
|
304
|
+
* (of length KYBER_INDCPA_MSGBYTES)
|
|
305
|
+
* - const uint8_t *c: pointer to input ciphertext
|
|
306
|
+
* (of length KYBER_INDCPA_BYTES)
|
|
307
|
+
* - const uint8_t *sk: pointer to input secret key
|
|
308
|
+
* (of length KYBER_INDCPA_SECRETKEYBYTES)
|
|
309
|
+
**************************************************/
|
|
310
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES],
|
|
311
|
+
const uint8_t c[KYBER_INDCPA_BYTES],
|
|
312
|
+
const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]) {
|
|
313
|
+
polyvec b, skpv;
|
|
314
|
+
poly v, mp;
|
|
315
|
+
|
|
316
|
+
unpack_ciphertext(&b, &v, c);
|
|
317
|
+
unpack_sk(&skpv, sk);
|
|
318
|
+
|
|
319
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(&b);
|
|
320
|
+
PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(&mp, &skpv, &b);
|
|
321
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont(&mp);
|
|
322
|
+
|
|
323
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_sub(&mp, &v, &mp);
|
|
324
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_reduce(&mp);
|
|
325
|
+
|
|
326
|
+
PQCLEAN_MLKEM1024_CLEAN_poly_tomsg(m, &mp);
|
|
327
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM1024_CLEAN_INDCPA_H
|
|
2
|
+
#define PQCLEAN_MLKEM1024_CLEAN_INDCPA_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include "polyvec.h"
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
void PQCLEAN_MLKEM1024_CLEAN_gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed);
|
|
8
|
+
|
|
9
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
|
|
10
|
+
uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES],
|
|
11
|
+
const uint8_t coins[KYBER_SYMBYTES]);
|
|
12
|
+
|
|
13
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES],
|
|
14
|
+
const uint8_t m[KYBER_INDCPA_MSGBYTES],
|
|
15
|
+
const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
|
|
16
|
+
const uint8_t coins[KYBER_SYMBYTES]);
|
|
17
|
+
|
|
18
|
+
void PQCLEAN_MLKEM1024_CLEAN_indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES],
|
|
19
|
+
const uint8_t c[KYBER_INDCPA_BYTES],
|
|
20
|
+
const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]);
|
|
21
|
+
|
|
22
|
+
#endif
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#include "indcpa.h"
|
|
2
|
+
#include "kem.h"
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include "randombytes.h"
|
|
5
|
+
#include "symmetric.h"
|
|
6
|
+
#include "verify.h"
|
|
7
|
+
#include <stddef.h>
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
/*************************************************
|
|
11
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair_derand
|
|
12
|
+
*
|
|
13
|
+
* Description: Generates public and private key
|
|
14
|
+
* for CCA-secure Kyber key encapsulation mechanism
|
|
15
|
+
*
|
|
16
|
+
* Arguments: - uint8_t *pk: pointer to output public key
|
|
17
|
+
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
|
|
18
|
+
* - uint8_t *sk: pointer to output private key
|
|
19
|
+
* (an already allocated array of KYBER_SECRETKEYBYTES bytes)
|
|
20
|
+
* - uint8_t *coins: pointer to input randomness
|
|
21
|
+
* (an already allocated array filled with 2*KYBER_SYMBYTES random bytes)
|
|
22
|
+
**
|
|
23
|
+
* Returns 0 (success)
|
|
24
|
+
**************************************************/
|
|
25
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair_derand(uint8_t *pk,
|
|
26
|
+
uint8_t *sk,
|
|
27
|
+
const uint8_t *coins) {
|
|
28
|
+
PQCLEAN_MLKEM1024_CLEAN_indcpa_keypair_derand(pk, sk, coins);
|
|
29
|
+
memcpy(sk + KYBER_INDCPA_SECRETKEYBYTES, pk, KYBER_PUBLICKEYBYTES);
|
|
30
|
+
hash_h(sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
|
|
31
|
+
/* Value z for pseudo-random output on reject */
|
|
32
|
+
memcpy(sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, coins + KYBER_SYMBYTES, KYBER_SYMBYTES);
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/*************************************************
|
|
37
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair
|
|
38
|
+
*
|
|
39
|
+
* Description: Generates public and private key
|
|
40
|
+
* for CCA-secure Kyber key encapsulation mechanism
|
|
41
|
+
*
|
|
42
|
+
* Arguments: - uint8_t *pk: pointer to output public key
|
|
43
|
+
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
|
|
44
|
+
* - uint8_t *sk: pointer to output private key
|
|
45
|
+
* (an already allocated array of KYBER_SECRETKEYBYTES bytes)
|
|
46
|
+
*
|
|
47
|
+
* Returns 0 (success)
|
|
48
|
+
**************************************************/
|
|
49
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair(uint8_t *pk,
|
|
50
|
+
uint8_t *sk) {
|
|
51
|
+
uint8_t coins[2 * KYBER_SYMBYTES];
|
|
52
|
+
randombytes(coins, 2 * KYBER_SYMBYTES);
|
|
53
|
+
PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair_derand(pk, sk, coins);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/*************************************************
|
|
58
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc_derand
|
|
59
|
+
*
|
|
60
|
+
* Description: Generates cipher text and shared
|
|
61
|
+
* secret for given public key
|
|
62
|
+
*
|
|
63
|
+
* Arguments: - uint8_t *ct: pointer to output cipher text
|
|
64
|
+
* (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
|
|
65
|
+
* - uint8_t *ss: pointer to output shared secret
|
|
66
|
+
* (an already allocated array of KYBER_SSBYTES bytes)
|
|
67
|
+
* - const uint8_t *pk: pointer to input public key
|
|
68
|
+
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
|
|
69
|
+
* - const uint8_t *coins: pointer to input randomness
|
|
70
|
+
* (an already allocated array filled with KYBER_SYMBYTES random bytes)
|
|
71
|
+
**
|
|
72
|
+
* Returns 0 (success)
|
|
73
|
+
**************************************************/
|
|
74
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc_derand(uint8_t *ct,
|
|
75
|
+
uint8_t *ss,
|
|
76
|
+
const uint8_t *pk,
|
|
77
|
+
const uint8_t *coins) {
|
|
78
|
+
uint8_t buf[2 * KYBER_SYMBYTES];
|
|
79
|
+
/* Will contain key, coins */
|
|
80
|
+
uint8_t kr[2 * KYBER_SYMBYTES];
|
|
81
|
+
|
|
82
|
+
memcpy(buf, coins, KYBER_SYMBYTES);
|
|
83
|
+
|
|
84
|
+
/* Multitarget countermeasure for coins + contributory KEM */
|
|
85
|
+
hash_h(buf + KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
|
|
86
|
+
hash_g(kr, buf, 2 * KYBER_SYMBYTES);
|
|
87
|
+
|
|
88
|
+
/* coins are in kr+KYBER_SYMBYTES */
|
|
89
|
+
PQCLEAN_MLKEM1024_CLEAN_indcpa_enc(ct, buf, pk, kr + KYBER_SYMBYTES);
|
|
90
|
+
|
|
91
|
+
memcpy(ss, kr, KYBER_SYMBYTES);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/*************************************************
|
|
96
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc
|
|
97
|
+
*
|
|
98
|
+
* Description: Generates cipher text and shared
|
|
99
|
+
* secret for given public key
|
|
100
|
+
*
|
|
101
|
+
* Arguments: - uint8_t *ct: pointer to output cipher text
|
|
102
|
+
* (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
|
|
103
|
+
* - uint8_t *ss: pointer to output shared secret
|
|
104
|
+
* (an already allocated array of KYBER_SSBYTES bytes)
|
|
105
|
+
* - const uint8_t *pk: pointer to input public key
|
|
106
|
+
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
|
|
107
|
+
*
|
|
108
|
+
* Returns 0 (success)
|
|
109
|
+
**************************************************/
|
|
110
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc(uint8_t *ct,
|
|
111
|
+
uint8_t *ss,
|
|
112
|
+
const uint8_t *pk) {
|
|
113
|
+
uint8_t coins[KYBER_SYMBYTES];
|
|
114
|
+
randombytes(coins, KYBER_SYMBYTES);
|
|
115
|
+
PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc_derand(ct, ss, pk, coins);
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*************************************************
|
|
120
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_crypto_kem_dec
|
|
121
|
+
*
|
|
122
|
+
* Description: Generates shared secret for given
|
|
123
|
+
* cipher text and private key
|
|
124
|
+
*
|
|
125
|
+
* Arguments: - uint8_t *ss: pointer to output shared secret
|
|
126
|
+
* (an already allocated array of KYBER_SSBYTES bytes)
|
|
127
|
+
* - const uint8_t *ct: pointer to input cipher text
|
|
128
|
+
* (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
|
|
129
|
+
* - const uint8_t *sk: pointer to input private key
|
|
130
|
+
* (an already allocated array of KYBER_SECRETKEYBYTES bytes)
|
|
131
|
+
*
|
|
132
|
+
* Returns 0.
|
|
133
|
+
*
|
|
134
|
+
* On failure, ss will contain a pseudo-random value.
|
|
135
|
+
**************************************************/
|
|
136
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_dec(uint8_t *ss,
|
|
137
|
+
const uint8_t *ct,
|
|
138
|
+
const uint8_t *sk) {
|
|
139
|
+
int fail;
|
|
140
|
+
uint8_t buf[2 * KYBER_SYMBYTES];
|
|
141
|
+
/* Will contain key, coins */
|
|
142
|
+
uint8_t kr[2 * KYBER_SYMBYTES];
|
|
143
|
+
uint8_t cmp[KYBER_CIPHERTEXTBYTES + KYBER_SYMBYTES];
|
|
144
|
+
const uint8_t *pk = sk + KYBER_INDCPA_SECRETKEYBYTES;
|
|
145
|
+
|
|
146
|
+
PQCLEAN_MLKEM1024_CLEAN_indcpa_dec(buf, ct, sk);
|
|
147
|
+
|
|
148
|
+
/* Multitarget countermeasure for coins + contributory KEM */
|
|
149
|
+
memcpy(buf + KYBER_SYMBYTES, sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, KYBER_SYMBYTES);
|
|
150
|
+
hash_g(kr, buf, 2 * KYBER_SYMBYTES);
|
|
151
|
+
|
|
152
|
+
/* coins are in kr+KYBER_SYMBYTES */
|
|
153
|
+
PQCLEAN_MLKEM1024_CLEAN_indcpa_enc(cmp, buf, pk, kr + KYBER_SYMBYTES);
|
|
154
|
+
|
|
155
|
+
fail = PQCLEAN_MLKEM1024_CLEAN_verify(ct, cmp, KYBER_CIPHERTEXTBYTES);
|
|
156
|
+
|
|
157
|
+
/* Compute rejection key */
|
|
158
|
+
rkprf(ss, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, ct);
|
|
159
|
+
|
|
160
|
+
/* Copy true key to return buffer if fail is false */
|
|
161
|
+
PQCLEAN_MLKEM1024_CLEAN_cmov(ss, kr, KYBER_SYMBYTES, (uint8_t) (1 - fail));
|
|
162
|
+
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM1024_CLEAN_KEM_H
|
|
2
|
+
#define PQCLEAN_MLKEM1024_CLEAN_KEM_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
#define PQCLEAN_MLKEM1024_CLEAN_CRYPTO_SECRETKEYBYTES KYBER_SECRETKEYBYTES
|
|
7
|
+
#define PQCLEAN_MLKEM1024_CLEAN_CRYPTO_PUBLICKEYBYTES KYBER_PUBLICKEYBYTES
|
|
8
|
+
#define PQCLEAN_MLKEM1024_CLEAN_CRYPTO_CIPHERTEXTBYTES KYBER_CIPHERTEXTBYTES
|
|
9
|
+
#define PQCLEAN_MLKEM1024_CLEAN_CRYPTO_BYTES KYBER_SSBYTES
|
|
10
|
+
|
|
11
|
+
#define PQCLEAN_MLKEM1024_CLEAN_CRYPTO_ALGNAME "ML-KEM-1024"
|
|
12
|
+
|
|
13
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins);
|
|
14
|
+
|
|
15
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_keypair(uint8_t *pk, uint8_t *sk);
|
|
16
|
+
|
|
17
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins);
|
|
18
|
+
|
|
19
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);
|
|
20
|
+
|
|
21
|
+
int PQCLEAN_MLKEM1024_CLEAN_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk);
|
|
22
|
+
|
|
23
|
+
#endif
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#include "ntt.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "reduce.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
/* Code to generate PQCLEAN_MLKEM1024_CLEAN_zetas and zetas_inv used in the number-theoretic transform:
|
|
7
|
+
|
|
8
|
+
#define KYBER_ROOT_OF_UNITY 17
|
|
9
|
+
|
|
10
|
+
static const uint8_t tree[128] = {
|
|
11
|
+
0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120,
|
|
12
|
+
4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124,
|
|
13
|
+
2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122,
|
|
14
|
+
6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126,
|
|
15
|
+
1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121,
|
|
16
|
+
5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125,
|
|
17
|
+
3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123,
|
|
18
|
+
7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
void init_ntt() {
|
|
22
|
+
unsigned int i;
|
|
23
|
+
int16_t tmp[128];
|
|
24
|
+
|
|
25
|
+
tmp[0] = MONT;
|
|
26
|
+
for(i=1;i<128;i++)
|
|
27
|
+
tmp[i] = fqmul(tmp[i-1],MONT*KYBER_ROOT_OF_UNITY % KYBER_Q);
|
|
28
|
+
|
|
29
|
+
for(i=0;i<128;i++) {
|
|
30
|
+
PQCLEAN_MLKEM1024_CLEAN_zetas[i] = tmp[tree[i]];
|
|
31
|
+
if(PQCLEAN_MLKEM1024_CLEAN_zetas[i] > KYBER_Q/2)
|
|
32
|
+
PQCLEAN_MLKEM1024_CLEAN_zetas[i] -= KYBER_Q;
|
|
33
|
+
if(PQCLEAN_MLKEM1024_CLEAN_zetas[i] < -KYBER_Q/2)
|
|
34
|
+
PQCLEAN_MLKEM1024_CLEAN_zetas[i] += KYBER_Q;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const int16_t PQCLEAN_MLKEM1024_CLEAN_zetas[128] = {
|
|
40
|
+
-1044, -758, -359, -1517, 1493, 1422, 287, 202,
|
|
41
|
+
-171, 622, 1577, 182, 962, -1202, -1474, 1468,
|
|
42
|
+
573, -1325, 264, 383, -829, 1458, -1602, -130,
|
|
43
|
+
-681, 1017, 732, 608, -1542, 411, -205, -1571,
|
|
44
|
+
1223, 652, -552, 1015, -1293, 1491, -282, -1544,
|
|
45
|
+
516, -8, -320, -666, -1618, -1162, 126, 1469,
|
|
46
|
+
-853, -90, -271, 830, 107, -1421, -247, -951,
|
|
47
|
+
-398, 961, -1508, -725, 448, -1065, 677, -1275,
|
|
48
|
+
-1103, 430, 555, 843, -1251, 871, 1550, 105,
|
|
49
|
+
422, 587, 177, -235, -291, -460, 1574, 1653,
|
|
50
|
+
-246, 778, 1159, -147, -777, 1483, -602, 1119,
|
|
51
|
+
-1590, 644, -872, 349, 418, 329, -156, -75,
|
|
52
|
+
817, 1097, 603, 610, 1322, -1285, -1465, 384,
|
|
53
|
+
-1215, -136, 1218, -1335, -874, 220, -1187, -1659,
|
|
54
|
+
-1185, -1530, -1278, 794, -1510, -854, -870, 478,
|
|
55
|
+
-108, -308, 996, 991, 958, -1460, 1522, 1628
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/*************************************************
|
|
59
|
+
* Name: fqmul
|
|
60
|
+
*
|
|
61
|
+
* Description: Multiplication followed by Montgomery reduction
|
|
62
|
+
*
|
|
63
|
+
* Arguments: - int16_t a: first factor
|
|
64
|
+
* - int16_t b: second factor
|
|
65
|
+
*
|
|
66
|
+
* Returns 16-bit integer congruent to a*b*R^{-1} mod q
|
|
67
|
+
**************************************************/
|
|
68
|
+
static int16_t fqmul(int16_t a, int16_t b) {
|
|
69
|
+
return PQCLEAN_MLKEM1024_CLEAN_montgomery_reduce((int32_t)a * b);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*************************************************
|
|
73
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_ntt
|
|
74
|
+
*
|
|
75
|
+
* Description: Inplace number-theoretic transform (NTT) in Rq.
|
|
76
|
+
* input is in standard order, output is in bitreversed order
|
|
77
|
+
*
|
|
78
|
+
* Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
|
|
79
|
+
**************************************************/
|
|
80
|
+
void PQCLEAN_MLKEM1024_CLEAN_ntt(int16_t r[256]) {
|
|
81
|
+
unsigned int len, start, j, k;
|
|
82
|
+
int16_t t, zeta;
|
|
83
|
+
|
|
84
|
+
k = 1;
|
|
85
|
+
for (len = 128; len >= 2; len >>= 1) {
|
|
86
|
+
for (start = 0; start < 256; start = j + len) {
|
|
87
|
+
zeta = PQCLEAN_MLKEM1024_CLEAN_zetas[k++];
|
|
88
|
+
for (j = start; j < start + len; j++) {
|
|
89
|
+
t = fqmul(zeta, r[j + len]);
|
|
90
|
+
r[j + len] = r[j] - t;
|
|
91
|
+
r[j] = r[j] + t;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*************************************************
|
|
98
|
+
* Name: invntt_tomont
|
|
99
|
+
*
|
|
100
|
+
* Description: Inplace inverse number-theoretic transform in Rq and
|
|
101
|
+
* multiplication by Montgomery factor 2^16.
|
|
102
|
+
* Input is in bitreversed order, output is in standard order
|
|
103
|
+
*
|
|
104
|
+
* Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
|
|
105
|
+
**************************************************/
|
|
106
|
+
void PQCLEAN_MLKEM1024_CLEAN_invntt(int16_t r[256]) {
|
|
107
|
+
unsigned int start, len, j, k;
|
|
108
|
+
int16_t t, zeta;
|
|
109
|
+
const int16_t f = 1441; // mont^2/128
|
|
110
|
+
|
|
111
|
+
k = 127;
|
|
112
|
+
for (len = 2; len <= 128; len <<= 1) {
|
|
113
|
+
for (start = 0; start < 256; start = j + len) {
|
|
114
|
+
zeta = PQCLEAN_MLKEM1024_CLEAN_zetas[k--];
|
|
115
|
+
for (j = start; j < start + len; j++) {
|
|
116
|
+
t = r[j];
|
|
117
|
+
r[j] = PQCLEAN_MLKEM1024_CLEAN_barrett_reduce(t + r[j + len]);
|
|
118
|
+
r[j + len] = r[j + len] - t;
|
|
119
|
+
r[j + len] = fqmul(zeta, r[j + len]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
for (j = 0; j < 256; j++) {
|
|
125
|
+
r[j] = fqmul(r[j], f);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/*************************************************
|
|
130
|
+
* Name: PQCLEAN_MLKEM1024_CLEAN_basemul
|
|
131
|
+
*
|
|
132
|
+
* Description: Multiplication of polynomials in Zq[X]/(X^2-zeta)
|
|
133
|
+
* used for multiplication of elements in Rq in NTT domain
|
|
134
|
+
*
|
|
135
|
+
* Arguments: - int16_t r[2]: pointer to the output polynomial
|
|
136
|
+
* - const int16_t a[2]: pointer to the first factor
|
|
137
|
+
* - const int16_t b[2]: pointer to the second factor
|
|
138
|
+
* - int16_t zeta: integer defining the reduction polynomial
|
|
139
|
+
**************************************************/
|
|
140
|
+
void PQCLEAN_MLKEM1024_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta) {
|
|
141
|
+
r[0] = fqmul(a[1], b[1]);
|
|
142
|
+
r[0] = fqmul(r[0], zeta);
|
|
143
|
+
r[0] += fqmul(a[0], b[0]);
|
|
144
|
+
r[1] = fqmul(a[0], b[1]);
|
|
145
|
+
r[1] += fqmul(a[1], b[0]);
|
|
146
|
+
}
|