/src/libgcrypt/cipher/kyber-kdep.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* kyber-kdep.c - the Kyber key encapsulation mechanism (KYBER_K dependent part) |
2 | | * Copyright (C) 2024 g10 Code GmbH |
3 | | * |
4 | | * This file was modified for use by Libgcrypt. |
5 | | * |
6 | | * This file is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as |
8 | | * published by the Free Software Foundation; either version 2.1 of |
9 | | * the License, or (at your option) any later version. |
10 | | * |
11 | | * This file is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this program; if not, see <https://www.gnu.org/licenses/>. |
18 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
19 | | * |
20 | | * You can also use this file under the same licence of original code. |
21 | | * SPDX-License-Identifier: CC0 OR Apache-2.0 |
22 | | * |
23 | | */ |
24 | | /* |
25 | | Original code from: |
26 | | |
27 | | Repository: https://github.com/pq-crystals/kyber.git |
28 | | Branch: standard |
29 | | Commit: 11d00ff1f20cfca1f72d819e5a45165c1e0a2816 |
30 | | |
31 | | Licence: |
32 | | Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/); |
33 | | or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html). |
34 | | |
35 | | Authors: |
36 | | Joppe Bos |
37 | | Léo Ducas |
38 | | Eike Kiltz |
39 | | Tancrède Lepoint |
40 | | Vadim Lyubashevsky |
41 | | John Schanck |
42 | | Peter Schwabe |
43 | | Gregor Seiler |
44 | | Damien Stehlé |
45 | | |
46 | | Kyber Home: https://www.pq-crystals.org/kyber/ |
47 | | */ |
48 | | /* |
49 | | * From original code, following modification was made. |
50 | | * |
51 | | * - C++ style comments are changed to C-style. |
52 | | * |
53 | | * - With the change of "verify" routine (now "verify1"), no negation |
54 | | * for the cmov argument in crypto_kem_dec. |
55 | | * |
56 | | * - Call to xof_init and xof_close are added in gen_matrix. |
57 | | */ |
58 | | |
59 | | /*************** kyber/ref/polyvec.h */ |
60 | | typedef struct{ |
61 | | poly vec[KYBER_K]; |
62 | | } polyvec; |
63 | | |
64 | | static void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a); |
65 | | static void polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]); |
66 | | |
67 | | static void polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a); |
68 | | static void polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]); |
69 | | |
70 | | static void polyvec_ntt(polyvec *r); |
71 | | static void polyvec_invntt_tomont(polyvec *r); |
72 | | |
73 | | static void polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b); |
74 | | |
75 | | static void polyvec_reduce(polyvec *r); |
76 | | |
77 | | static void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b); |
78 | | |
79 | | /*************** kyber/ref/indcpa.h */ |
80 | | static void gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed); |
81 | | |
82 | | static void indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], |
83 | | uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES], |
84 | | const uint8_t coins[KYBER_SYMBYTES]); |
85 | | |
86 | | static void indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES], |
87 | | const uint8_t m[KYBER_INDCPA_MSGBYTES], |
88 | | const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], |
89 | | const uint8_t coins[KYBER_SYMBYTES]); |
90 | | |
91 | | static void indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES], |
92 | | const uint8_t c[KYBER_INDCPA_BYTES], |
93 | | const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]); |
94 | | |
95 | | /*************** kyber/ref/kem.h */ |
96 | | |
97 | | static int crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins); |
98 | | |
99 | | static int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins); |
100 | | |
101 | | /*************** kyber/ref/indcpa.c */ |
102 | | |
103 | | /************************************************* |
104 | | * Name: pack_pk |
105 | | * |
106 | | * Description: Serialize the public key as concatenation of the |
107 | | * serialized vector of polynomials pk |
108 | | * and the public seed used to generate the matrix A. |
109 | | * |
110 | | * Arguments: uint8_t *r: pointer to the output serialized public key |
111 | | * polyvec *pk: pointer to the input public-key polyvec |
112 | | * const uint8_t *seed: pointer to the input public seed |
113 | | **************************************************/ |
114 | | static void pack_pk(uint8_t r[KYBER_INDCPA_PUBLICKEYBYTES], |
115 | | polyvec *pk, |
116 | | const uint8_t seed[KYBER_SYMBYTES]) |
117 | 0 | { |
118 | 0 | polyvec_tobytes(r, pk); |
119 | 0 | memcpy(r+KYBER_POLYVECBYTES, seed, KYBER_SYMBYTES); |
120 | 0 | } Unexecuted instantiation: kyber.c:pack_pk_2 Unexecuted instantiation: kyber.c:pack_pk_3 Unexecuted instantiation: kyber.c:pack_pk_4 |
121 | | |
122 | | /************************************************* |
123 | | * Name: unpack_pk |
124 | | * |
125 | | * Description: De-serialize public key from a byte array; |
126 | | * approximate inverse of pack_pk |
127 | | * |
128 | | * Arguments: - polyvec *pk: pointer to output public-key polynomial vector |
129 | | * - uint8_t *seed: pointer to output seed to generate matrix A |
130 | | * - const uint8_t *packedpk: pointer to input serialized public key |
131 | | **************************************************/ |
132 | | static void unpack_pk(polyvec *pk, |
133 | | uint8_t seed[KYBER_SYMBYTES], |
134 | | const uint8_t packedpk[KYBER_INDCPA_PUBLICKEYBYTES]) |
135 | 0 | { |
136 | 0 | polyvec_frombytes(pk, packedpk); |
137 | 0 | memcpy(seed, packedpk+KYBER_POLYVECBYTES, KYBER_SYMBYTES); |
138 | 0 | } Unexecuted instantiation: kyber.c:unpack_pk_2 Unexecuted instantiation: kyber.c:unpack_pk_3 Unexecuted instantiation: kyber.c:unpack_pk_4 |
139 | | |
140 | | /************************************************* |
141 | | * Name: pack_sk |
142 | | * |
143 | | * Description: Serialize the secret key |
144 | | * |
145 | | * Arguments: - uint8_t *r: pointer to output serialized secret key |
146 | | * - polyvec *sk: pointer to input vector of polynomials (secret key) |
147 | | **************************************************/ |
148 | | static void pack_sk(uint8_t r[KYBER_INDCPA_SECRETKEYBYTES], polyvec *sk) |
149 | 0 | { |
150 | 0 | polyvec_tobytes(r, sk); |
151 | 0 | } Unexecuted instantiation: kyber.c:pack_sk_2 Unexecuted instantiation: kyber.c:pack_sk_3 Unexecuted instantiation: kyber.c:pack_sk_4 |
152 | | |
153 | | /************************************************* |
154 | | * Name: unpack_sk |
155 | | * |
156 | | * Description: De-serialize the secret key; inverse of pack_sk |
157 | | * |
158 | | * Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key) |
159 | | * - const uint8_t *packedsk: pointer to input serialized secret key |
160 | | **************************************************/ |
161 | | static void unpack_sk(polyvec *sk, const uint8_t packedsk[KYBER_INDCPA_SECRETKEYBYTES]) |
162 | 0 | { |
163 | 0 | polyvec_frombytes(sk, packedsk); |
164 | 0 | } Unexecuted instantiation: kyber.c:unpack_sk_2 Unexecuted instantiation: kyber.c:unpack_sk_3 Unexecuted instantiation: kyber.c:unpack_sk_4 |
165 | | |
166 | | /************************************************* |
167 | | * Name: pack_ciphertext |
168 | | * |
169 | | * Description: Serialize the ciphertext as concatenation of the |
170 | | * compressed and serialized vector of polynomials b |
171 | | * and the compressed and serialized polynomial v |
172 | | * |
173 | | * Arguments: uint8_t *r: pointer to the output serialized ciphertext |
174 | | * poly *pk: pointer to the input vector of polynomials b |
175 | | * poly *v: pointer to the input polynomial v |
176 | | **************************************************/ |
177 | | static void pack_ciphertext(uint8_t r[KYBER_INDCPA_BYTES], polyvec *b, poly *v) |
178 | 0 | { |
179 | 0 | polyvec_compress(r, b); |
180 | 0 | poly_compress(r+KYBER_POLYVECCOMPRESSEDBYTES, v); |
181 | 0 | } Unexecuted instantiation: kyber.c:pack_ciphertext_2 Unexecuted instantiation: kyber.c:pack_ciphertext_3 Unexecuted instantiation: kyber.c:pack_ciphertext_4 |
182 | | |
183 | | /************************************************* |
184 | | * Name: unpack_ciphertext |
185 | | * |
186 | | * Description: De-serialize and decompress ciphertext from a byte array; |
187 | | * approximate inverse of pack_ciphertext |
188 | | * |
189 | | * Arguments: - polyvec *b: pointer to the output vector of polynomials b |
190 | | * - poly *v: pointer to the output polynomial v |
191 | | * - const uint8_t *c: pointer to the input serialized ciphertext |
192 | | **************************************************/ |
193 | | static void unpack_ciphertext(polyvec *b, poly *v, const uint8_t c[KYBER_INDCPA_BYTES]) |
194 | 0 | { |
195 | 0 | polyvec_decompress(b, c); |
196 | 0 | poly_decompress(v, c+KYBER_POLYVECCOMPRESSEDBYTES); |
197 | 0 | } Unexecuted instantiation: kyber.c:unpack_ciphertext_2 Unexecuted instantiation: kyber.c:unpack_ciphertext_3 Unexecuted instantiation: kyber.c:unpack_ciphertext_4 |
198 | | |
199 | 0 | #define gen_a(A,B) gen_matrix(A,B,0) |
200 | 0 | #define gen_at(A,B) gen_matrix(A,B,1) |
201 | | |
202 | | /************************************************* |
203 | | * Name: gen_matrix |
204 | | * |
205 | | * Description: Deterministically generate matrix A (or the transpose of A) |
206 | | * from a seed. Entries of the matrix are polynomials that look |
207 | | * uniformly random. Performs rejection sampling on output of |
208 | | * a XOF |
209 | | * |
210 | | * Arguments: - polyvec *a: pointer to ouptput matrix A |
211 | | * - const uint8_t *seed: pointer to input seed |
212 | | * - int transposed: boolean deciding whether A or A^T is generated |
213 | | **************************************************/ |
214 | | #if(XOF_BLOCKBYTES % 3) |
215 | | #error "Implementation of gen_matrix assumes that XOF_BLOCKBYTES is a multiple of 3" |
216 | | #endif |
217 | | |
218 | 0 | #define GEN_MATRIX_NBLOCKS ((12*KYBER_N/8*(1 << 12)/KYBER_Q + XOF_BLOCKBYTES)/XOF_BLOCKBYTES) |
219 | | void gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed) |
220 | 0 | { |
221 | 0 | unsigned int ctr, i, j; |
222 | 0 | unsigned int buflen; |
223 | 0 | uint8_t buf[GEN_MATRIX_NBLOCKS*XOF_BLOCKBYTES]; |
224 | 0 | xof_state state; |
225 | |
|
226 | 0 | for(i=0;i<KYBER_K;i++) { |
227 | 0 | for(j=0;j<KYBER_K;j++) { |
228 | 0 | xof_init(&state); |
229 | 0 | if(transposed) |
230 | 0 | xof_absorb(&state, seed, i, j); |
231 | 0 | else |
232 | 0 | xof_absorb(&state, seed, j, i); |
233 | |
|
234 | 0 | xof_squeezeblocks(buf, GEN_MATRIX_NBLOCKS, &state); |
235 | 0 | buflen = GEN_MATRIX_NBLOCKS*XOF_BLOCKBYTES; |
236 | 0 | ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, buflen); |
237 | |
|
238 | 0 | while(ctr < KYBER_N) { |
239 | 0 | xof_squeezeblocks(buf, 1, &state); |
240 | 0 | buflen = XOF_BLOCKBYTES; |
241 | 0 | ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, buflen); |
242 | 0 | } |
243 | 0 | xof_close (&state); |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } Unexecuted instantiation: kyber.c:gen_matrix_2 Unexecuted instantiation: kyber.c:gen_matrix_3 Unexecuted instantiation: kyber.c:gen_matrix_4 |
247 | | |
248 | | /************************************************* |
249 | | * Name: indcpa_keypair_derand |
250 | | * |
251 | | * Description: Generates public and private key for the CPA-secure |
252 | | * public-key encryption scheme underlying Kyber |
253 | | * |
254 | | * Arguments: - uint8_t *pk: pointer to output public key |
255 | | * (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) |
256 | | * - uint8_t *sk: pointer to output private key |
257 | | * (of length KYBER_INDCPA_SECRETKEYBYTES bytes) |
258 | | * - const uint8_t *coins: pointer to input randomness |
259 | | * (of length KYBER_SYMBYTES bytes) |
260 | | **************************************************/ |
261 | | void indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], |
262 | | uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES], |
263 | | const uint8_t coins[KYBER_SYMBYTES]) |
264 | 0 | { |
265 | 0 | unsigned int i; |
266 | 0 | uint8_t buf[2*KYBER_SYMBYTES]; |
267 | 0 | const uint8_t *publicseed = buf; |
268 | 0 | const uint8_t *noiseseed = buf+KYBER_SYMBYTES; |
269 | 0 | uint8_t nonce = 0; |
270 | 0 | polyvec a[KYBER_K], e, pkpv, skpv; |
271 | |
|
272 | 0 | memcpy(buf, coins, KYBER_SYMBYTES); |
273 | 0 | buf[KYBER_SYMBYTES] = KYBER_K; |
274 | 0 | hash_g(buf, buf, KYBER_SYMBYTES+1); |
275 | |
|
276 | 0 | gen_a(a, publicseed); |
277 | |
|
278 | 0 | for(i=0;i<KYBER_K;i++) |
279 | 0 | poly_getnoise_eta1(&skpv.vec[i], noiseseed, nonce++); |
280 | 0 | for(i=0;i<KYBER_K;i++) |
281 | 0 | poly_getnoise_eta1(&e.vec[i], noiseseed, nonce++); |
282 | |
|
283 | 0 | polyvec_ntt(&skpv); |
284 | 0 | polyvec_ntt(&e); |
285 | | |
286 | | /* matrix-vector multiplication */ |
287 | 0 | for(i=0;i<KYBER_K;i++) { |
288 | 0 | polyvec_basemul_acc_montgomery(&pkpv.vec[i], &a[i], &skpv); |
289 | 0 | poly_tomont(&pkpv.vec[i]); |
290 | 0 | } |
291 | |
|
292 | 0 | polyvec_add(&pkpv, &pkpv, &e); |
293 | 0 | polyvec_reduce(&pkpv); |
294 | |
|
295 | 0 | pack_sk(sk, &skpv); |
296 | 0 | pack_pk(pk, &pkpv, publicseed); |
297 | 0 | } Unexecuted instantiation: kyber.c:indcpa_keypair_derand_2 Unexecuted instantiation: kyber.c:indcpa_keypair_derand_3 Unexecuted instantiation: kyber.c:indcpa_keypair_derand_4 |
298 | | |
299 | | |
300 | | /************************************************* |
301 | | * Name: indcpa_enc |
302 | | * |
303 | | * Description: Encryption function of the CPA-secure |
304 | | * public-key encryption scheme underlying Kyber. |
305 | | * |
306 | | * Arguments: - uint8_t *c: pointer to output ciphertext |
307 | | * (of length KYBER_INDCPA_BYTES bytes) |
308 | | * - const uint8_t *m: pointer to input message |
309 | | * (of length KYBER_INDCPA_MSGBYTES bytes) |
310 | | * - const uint8_t *pk: pointer to input public key |
311 | | * (of length KYBER_INDCPA_PUBLICKEYBYTES) |
312 | | * - const uint8_t *coins: pointer to input random coins used as seed |
313 | | * (of length KYBER_SYMBYTES) to deterministically |
314 | | * generate all randomness |
315 | | **************************************************/ |
316 | | void indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES], |
317 | | const uint8_t m[KYBER_INDCPA_MSGBYTES], |
318 | | const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], |
319 | | const uint8_t coins[KYBER_SYMBYTES]) |
320 | 0 | { |
321 | 0 | unsigned int i; |
322 | 0 | uint8_t seed[KYBER_SYMBYTES]; |
323 | 0 | uint8_t nonce = 0; |
324 | 0 | polyvec sp, pkpv, ep, at[KYBER_K], b; |
325 | 0 | poly v, k, epp; |
326 | |
|
327 | 0 | unpack_pk(&pkpv, seed, pk); |
328 | 0 | poly_frommsg(&k, m); |
329 | 0 | gen_at(at, seed); |
330 | |
|
331 | 0 | for(i=0;i<KYBER_K;i++) |
332 | 0 | poly_getnoise_eta1(sp.vec+i, coins, nonce++); |
333 | 0 | for(i=0;i<KYBER_K;i++) |
334 | 0 | poly_getnoise_eta2(ep.vec+i, coins, nonce++); |
335 | 0 | poly_getnoise_eta2(&epp, coins, nonce++); |
336 | |
|
337 | 0 | polyvec_ntt(&sp); |
338 | | |
339 | | /* matrix-vector multiplication */ |
340 | 0 | for(i=0;i<KYBER_K;i++) |
341 | 0 | polyvec_basemul_acc_montgomery(&b.vec[i], &at[i], &sp); |
342 | |
|
343 | 0 | polyvec_basemul_acc_montgomery(&v, &pkpv, &sp); |
344 | |
|
345 | 0 | polyvec_invntt_tomont(&b); |
346 | 0 | poly_invntt_tomont(&v); |
347 | |
|
348 | 0 | polyvec_add(&b, &b, &ep); |
349 | 0 | poly_add(&v, &v, &epp); |
350 | 0 | poly_add(&v, &v, &k); |
351 | 0 | polyvec_reduce(&b); |
352 | 0 | poly_reduce(&v); |
353 | |
|
354 | 0 | pack_ciphertext(c, &b, &v); |
355 | 0 | } Unexecuted instantiation: kyber.c:indcpa_enc_2 Unexecuted instantiation: kyber.c:indcpa_enc_3 Unexecuted instantiation: kyber.c:indcpa_enc_4 |
356 | | |
357 | | /************************************************* |
358 | | * Name: indcpa_dec |
359 | | * |
360 | | * Description: Decryption function of the CPA-secure |
361 | | * public-key encryption scheme underlying Kyber. |
362 | | * |
363 | | * Arguments: - uint8_t *m: pointer to output decrypted message |
364 | | * (of length KYBER_INDCPA_MSGBYTES) |
365 | | * - const uint8_t *c: pointer to input ciphertext |
366 | | * (of length KYBER_INDCPA_BYTES) |
367 | | * - const uint8_t *sk: pointer to input secret key |
368 | | * (of length KYBER_INDCPA_SECRETKEYBYTES) |
369 | | **************************************************/ |
370 | | void indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES], |
371 | | const uint8_t c[KYBER_INDCPA_BYTES], |
372 | | const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]) |
373 | 0 | { |
374 | 0 | polyvec b, skpv; |
375 | 0 | poly v, mp; |
376 | |
|
377 | 0 | unpack_ciphertext(&b, &v, c); |
378 | 0 | unpack_sk(&skpv, sk); |
379 | |
|
380 | 0 | polyvec_ntt(&b); |
381 | 0 | polyvec_basemul_acc_montgomery(&mp, &skpv, &b); |
382 | 0 | poly_invntt_tomont(&mp); |
383 | |
|
384 | 0 | poly_sub(&mp, &v, &mp); |
385 | 0 | poly_reduce(&mp); |
386 | |
|
387 | 0 | poly_tomsg(m, &mp); |
388 | 0 | } Unexecuted instantiation: kyber.c:indcpa_dec_2 Unexecuted instantiation: kyber.c:indcpa_dec_3 Unexecuted instantiation: kyber.c:indcpa_dec_4 |
389 | | |
390 | | /*************** kyber/ref/kem.c */ |
391 | | /************************************************* |
392 | | * Name: crypto_kem_keypair_derand |
393 | | * |
394 | | * Description: Generates public and private key |
395 | | * for CCA-secure Kyber key encapsulation mechanism |
396 | | * |
397 | | * Arguments: - uint8_t *pk: pointer to output public key |
398 | | * (an already allocated array of KYBER_PUBLICKEYBYTES bytes) |
399 | | * - uint8_t *sk: pointer to output private key |
400 | | * (an already allocated array of KYBER_SECRETKEYBYTES bytes) |
401 | | * - uint8_t *coins: pointer to input randomness |
402 | | * (an already allocated array filled with 2*KYBER_SYMBYTES random bytes) |
403 | | ** |
404 | | * Returns 0 (success) |
405 | | **************************************************/ |
406 | | int crypto_kem_keypair_derand(uint8_t *pk, |
407 | | uint8_t *sk, |
408 | | const uint8_t *coins) |
409 | 0 | { |
410 | 0 | indcpa_keypair_derand(pk, sk, coins); |
411 | 0 | memcpy(sk+KYBER_INDCPA_SECRETKEYBYTES, pk, KYBER_PUBLICKEYBYTES); |
412 | 0 | hash_h(sk+KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); |
413 | | /* Value z for pseudo-random output on reject */ |
414 | 0 | memcpy(sk+KYBER_SECRETKEYBYTES-KYBER_SYMBYTES, coins+KYBER_SYMBYTES, KYBER_SYMBYTES); |
415 | 0 | return 0; |
416 | 0 | } Unexecuted instantiation: kyber.c:crypto_kem_keypair_derand_2 Unexecuted instantiation: kyber.c:crypto_kem_keypair_derand_3 Unexecuted instantiation: kyber.c:crypto_kem_keypair_derand_4 |
417 | | |
418 | | /************************************************* |
419 | | * Name: crypto_kem_keypair |
420 | | * |
421 | | * Description: Generates public and private key |
422 | | * for CCA-secure Kyber key encapsulation mechanism |
423 | | * |
424 | | * Arguments: - uint8_t *pk: pointer to output public key |
425 | | * (an already allocated array of KYBER_PUBLICKEYBYTES bytes) |
426 | | * - uint8_t *sk: pointer to output private key |
427 | | * (an already allocated array of KYBER_SECRETKEYBYTES bytes) |
428 | | * |
429 | | * Returns 0 (success) |
430 | | **************************************************/ |
431 | | int crypto_kem_keypair(uint8_t *pk, |
432 | | uint8_t *sk) |
433 | 0 | { |
434 | 0 | uint8_t coins[2*KYBER_SYMBYTES]; |
435 | 0 | randombytes(coins, 2*KYBER_SYMBYTES); |
436 | 0 | crypto_kem_keypair_derand(pk, sk, coins); |
437 | 0 | return 0; |
438 | 0 | } Unexecuted instantiation: kyber.c:crypto_kem_keypair_2 Unexecuted instantiation: kyber.c:crypto_kem_keypair_3 Unexecuted instantiation: kyber.c:crypto_kem_keypair_4 |
439 | | |
440 | | /************************************************* |
441 | | * Name: crypto_kem_enc_derand |
442 | | * |
443 | | * Description: Generates cipher text and shared |
444 | | * secret for given public key |
445 | | * |
446 | | * Arguments: - uint8_t *ct: pointer to output cipher text |
447 | | * (an already allocated array of KYBER_CIPHERTEXTBYTES bytes) |
448 | | * - uint8_t *ss: pointer to output shared secret |
449 | | * (an already allocated array of KYBER_SSBYTES bytes) |
450 | | * - const uint8_t *pk: pointer to input public key |
451 | | * (an already allocated array of KYBER_PUBLICKEYBYTES bytes) |
452 | | * - const uint8_t *coins: pointer to input randomness |
453 | | * (an already allocated array filled with KYBER_SYMBYTES random bytes) |
454 | | ** |
455 | | * Returns 0 (success) |
456 | | **************************************************/ |
457 | | int crypto_kem_enc_derand(uint8_t *ct, |
458 | | uint8_t *ss, |
459 | | const uint8_t *pk, |
460 | | const uint8_t *coins) |
461 | 0 | { |
462 | 0 | uint8_t buf[2*KYBER_SYMBYTES]; |
463 | | /* Will contain key, coins */ |
464 | 0 | uint8_t kr[2*KYBER_SYMBYTES]; |
465 | |
|
466 | 0 | memcpy(buf, coins, KYBER_SYMBYTES); |
467 | | |
468 | | /* Multitarget countermeasure for coins + contributory KEM */ |
469 | 0 | hash_h(buf+KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); |
470 | 0 | hash_g(kr, buf, 2*KYBER_SYMBYTES); |
471 | | |
472 | | /* coins are in kr+KYBER_SYMBYTES */ |
473 | 0 | indcpa_enc(ct, buf, pk, kr+KYBER_SYMBYTES); |
474 | |
|
475 | 0 | memcpy(ss,kr,KYBER_SYMBYTES); |
476 | 0 | return 0; |
477 | 0 | } Unexecuted instantiation: kyber.c:crypto_kem_enc_derand_2 Unexecuted instantiation: kyber.c:crypto_kem_enc_derand_3 Unexecuted instantiation: kyber.c:crypto_kem_enc_derand_4 |
478 | | |
479 | | /************************************************* |
480 | | * Name: crypto_kem_enc |
481 | | * |
482 | | * Description: Generates cipher text and shared |
483 | | * secret for given public key |
484 | | * |
485 | | * Arguments: - uint8_t *ct: pointer to output cipher text |
486 | | * (an already allocated array of KYBER_CIPHERTEXTBYTES bytes) |
487 | | * - uint8_t *ss: pointer to output shared secret |
488 | | * (an already allocated array of KYBER_SSBYTES bytes) |
489 | | * - const uint8_t *pk: pointer to input public key |
490 | | * (an already allocated array of KYBER_PUBLICKEYBYTES bytes) |
491 | | * |
492 | | * Returns 0 (success) |
493 | | **************************************************/ |
494 | | int crypto_kem_enc(uint8_t *ct, |
495 | | uint8_t *ss, |
496 | | const uint8_t *pk) |
497 | 0 | { |
498 | 0 | uint8_t coins[KYBER_SYMBYTES]; |
499 | 0 | randombytes(coins, KYBER_SYMBYTES); |
500 | 0 | crypto_kem_enc_derand(ct, ss, pk, coins); |
501 | 0 | return 0; |
502 | 0 | } Unexecuted instantiation: kyber.c:crypto_kem_enc_2 Unexecuted instantiation: kyber.c:crypto_kem_enc_3 Unexecuted instantiation: kyber.c:crypto_kem_enc_4 |
503 | | |
504 | | /************************************************* |
505 | | * Name: crypto_kem_dec |
506 | | * |
507 | | * Description: Generates shared secret for given |
508 | | * cipher text and private key |
509 | | * |
510 | | * Arguments: - uint8_t *ss: pointer to output shared secret |
511 | | * (an already allocated array of KYBER_SSBYTES bytes) |
512 | | * - const uint8_t *ct: pointer to input cipher text |
513 | | * (an already allocated array of KYBER_CIPHERTEXTBYTES bytes) |
514 | | * - const uint8_t *sk: pointer to input private key |
515 | | * (an already allocated array of KYBER_SECRETKEYBYTES bytes) |
516 | | * |
517 | | * Returns 0. |
518 | | * |
519 | | * On failure, ss will contain a pseudo-random value. |
520 | | **************************************************/ |
521 | | int crypto_kem_dec(uint8_t *ss, |
522 | | const uint8_t *ct, |
523 | | const uint8_t *sk) |
524 | 0 | { |
525 | 0 | unsigned int success; |
526 | 0 | uint8_t buf[2*KYBER_SYMBYTES]; |
527 | | /* Will contain key, coins */ |
528 | 0 | uint8_t kr[2*KYBER_SYMBYTES]; |
529 | 0 | uint8_t cmp[KYBER_CIPHERTEXTBYTES+KYBER_SYMBYTES]; |
530 | 0 | const uint8_t *pk = sk+KYBER_INDCPA_SECRETKEYBYTES; |
531 | |
|
532 | 0 | indcpa_dec(buf, ct, sk); |
533 | | |
534 | | /* Multitarget countermeasure for coins + contributory KEM */ |
535 | 0 | memcpy(buf+KYBER_SYMBYTES, sk+KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES, KYBER_SYMBYTES); |
536 | 0 | hash_g(kr, buf, 2*KYBER_SYMBYTES); |
537 | | |
538 | | /* coins are in kr+KYBER_SYMBYTES */ |
539 | 0 | indcpa_enc(cmp, buf, pk, kr+KYBER_SYMBYTES); |
540 | |
|
541 | 0 | success = verify1(ct, cmp, KYBER_CIPHERTEXTBYTES); |
542 | | |
543 | | /* Compute rejection key */ |
544 | 0 | rkprf(ss,sk+KYBER_SECRETKEYBYTES-KYBER_SYMBYTES,ct); |
545 | | |
546 | | /* Copy true key to return buffer if fail is false */ |
547 | 0 | cmov(ss,kr,KYBER_SYMBYTES,success); |
548 | |
|
549 | 0 | return 0; |
550 | 0 | } Unexecuted instantiation: kyber.c:crypto_kem_dec_2 Unexecuted instantiation: kyber.c:crypto_kem_dec_3 Unexecuted instantiation: kyber.c:crypto_kem_dec_4 |
551 | | |
552 | | /*************** kyber/ref/polyvec.c */ |
553 | | |
554 | | /************************************************* |
555 | | * Name: polyvec_compress |
556 | | * |
557 | | * Description: Compress and serialize vector of polynomials |
558 | | * |
559 | | * Arguments: - uint8_t *r: pointer to output byte array |
560 | | * (needs space for KYBER_POLYVECCOMPRESSEDBYTES) |
561 | | * - const polyvec *a: pointer to input vector of polynomials |
562 | | **************************************************/ |
563 | | void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a) |
564 | 0 | { |
565 | 0 | unsigned int i,j,k; |
566 | 0 | uint64_t d0; |
567 | |
|
568 | | #if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 352)) |
569 | | uint16_t t[8]; |
570 | 0 | for(i=0;i<KYBER_K;i++) { |
571 | 0 | for(j=0;j<KYBER_N/8;j++) { |
572 | 0 | for(k=0;k<8;k++) { |
573 | 0 | t[k] = a->vec[i].coeffs[8*j+k]; |
574 | 0 | t[k] += ((int16_t)t[k] >> 15) & KYBER_Q; |
575 | | /* t[k] = ((((uint32_t)t[k] << 11) + KYBER_Q/2)/KYBER_Q) & 0x7ff; */ |
576 | 0 | d0 = t[k]; |
577 | 0 | d0 <<= 11; |
578 | 0 | d0 += 1664; |
579 | 0 | d0 *= 645084; |
580 | 0 | d0 >>= 31; |
581 | 0 | t[k] = d0 & 0x7ff; |
582 | | |
583 | | } |
584 | |
|
585 | 0 | r[ 0] = (t[0] >> 0); |
586 | 0 | r[ 1] = (t[0] >> 8) | (t[1] << 3); |
587 | 0 | r[ 2] = (t[1] >> 5) | (t[2] << 6); |
588 | 0 | r[ 3] = (t[2] >> 2); |
589 | 0 | r[ 4] = (t[2] >> 10) | (t[3] << 1); |
590 | 0 | r[ 5] = (t[3] >> 7) | (t[4] << 4); |
591 | 0 | r[ 6] = (t[4] >> 4) | (t[5] << 7); |
592 | 0 | r[ 7] = (t[5] >> 1); |
593 | 0 | r[ 8] = (t[5] >> 9) | (t[6] << 2); |
594 | 0 | r[ 9] = (t[6] >> 6) | (t[7] << 5); |
595 | 0 | r[10] = (t[7] >> 3); |
596 | 0 | r += 11; |
597 | 0 | } |
598 | 0 | } |
599 | | #elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 320)) |
600 | | uint16_t t[4]; |
601 | 0 | for(i=0;i<KYBER_K;i++) { |
602 | 0 | for(j=0;j<KYBER_N/4;j++) { |
603 | 0 | for(k=0;k<4;k++) { |
604 | 0 | t[k] = a->vec[i].coeffs[4*j+k]; |
605 | 0 | t[k] += ((int16_t)t[k] >> 15) & KYBER_Q; |
606 | | /* t[k] = ((((uint32_t)t[k] << 10) + KYBER_Q/2)/ KYBER_Q) & 0x3ff; */ |
607 | 0 | d0 = t[k]; |
608 | 0 | d0 <<= 10; |
609 | 0 | d0 += 1665; |
610 | 0 | d0 *= 1290167; |
611 | 0 | d0 >>= 32; |
612 | 0 | t[k] = d0 & 0x3ff; |
613 | 0 | } |
614 | |
|
615 | 0 | r[0] = (t[0] >> 0); |
616 | 0 | r[1] = (t[0] >> 8) | (t[1] << 2); |
617 | 0 | r[2] = (t[1] >> 6) | (t[2] << 4); |
618 | 0 | r[3] = (t[2] >> 4) | (t[3] << 6); |
619 | 0 | r[4] = (t[3] >> 2); |
620 | 0 | r += 5; |
621 | 0 | } |
622 | 0 | } |
623 | | #else |
624 | | #error "KYBER_POLYVECCOMPRESSEDBYTES needs to be in {320*KYBER_K, 352*KYBER_K}" |
625 | | #endif |
626 | 0 | } Unexecuted instantiation: kyber.c:polyvec_compress_2 Unexecuted instantiation: kyber.c:polyvec_compress_3 Unexecuted instantiation: kyber.c:polyvec_compress_4 |
627 | | |
628 | | /************************************************* |
629 | | * Name: polyvec_decompress |
630 | | * |
631 | | * Description: De-serialize and decompress vector of polynomials; |
632 | | * approximate inverse of polyvec_compress |
633 | | * |
634 | | * Arguments: - polyvec *r: pointer to output vector of polynomials |
635 | | * - const uint8_t *a: pointer to input byte array |
636 | | * (of length KYBER_POLYVECCOMPRESSEDBYTES) |
637 | | **************************************************/ |
638 | | void polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]) |
639 | 0 | { |
640 | 0 | unsigned int i,j,k; |
641 | |
|
642 | | #if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 352)) |
643 | | uint16_t t[8]; |
644 | 0 | for(i=0;i<KYBER_K;i++) { |
645 | 0 | for(j=0;j<KYBER_N/8;j++) { |
646 | 0 | t[0] = (a[0] >> 0) | ((uint16_t)a[ 1] << 8); |
647 | 0 | t[1] = (a[1] >> 3) | ((uint16_t)a[ 2] << 5); |
648 | 0 | t[2] = (a[2] >> 6) | ((uint16_t)a[ 3] << 2) | ((uint16_t)a[4] << 10); |
649 | 0 | t[3] = (a[4] >> 1) | ((uint16_t)a[ 5] << 7); |
650 | 0 | t[4] = (a[5] >> 4) | ((uint16_t)a[ 6] << 4); |
651 | 0 | t[5] = (a[6] >> 7) | ((uint16_t)a[ 7] << 1) | ((uint16_t)a[8] << 9); |
652 | 0 | t[6] = (a[8] >> 2) | ((uint16_t)a[ 9] << 6); |
653 | 0 | t[7] = (a[9] >> 5) | ((uint16_t)a[10] << 3); |
654 | 0 | a += 11; |
655 | |
|
656 | 0 | for(k=0;k<8;k++) |
657 | 0 | r->vec[i].coeffs[8*j+k] = ((uint32_t)(t[k] & 0x7FF)*KYBER_Q + 1024) >> 11; |
658 | 0 | } |
659 | 0 | } |
660 | | #elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 320)) |
661 | | uint16_t t[4]; |
662 | 0 | for(i=0;i<KYBER_K;i++) { |
663 | 0 | for(j=0;j<KYBER_N/4;j++) { |
664 | 0 | t[0] = (a[0] >> 0) | ((uint16_t)a[1] << 8); |
665 | 0 | t[1] = (a[1] >> 2) | ((uint16_t)a[2] << 6); |
666 | 0 | t[2] = (a[2] >> 4) | ((uint16_t)a[3] << 4); |
667 | 0 | t[3] = (a[3] >> 6) | ((uint16_t)a[4] << 2); |
668 | 0 | a += 5; |
669 | |
|
670 | 0 | for(k=0;k<4;k++) |
671 | 0 | r->vec[i].coeffs[4*j+k] = ((uint32_t)(t[k] & 0x3FF)*KYBER_Q + 512) >> 10; |
672 | 0 | } |
673 | 0 | } |
674 | | #else |
675 | | #error "KYBER_POLYVECCOMPRESSEDBYTES needs to be in {320*KYBER_K, 352*KYBER_K}" |
676 | | #endif |
677 | 0 | } Unexecuted instantiation: kyber.c:polyvec_decompress_2 Unexecuted instantiation: kyber.c:polyvec_decompress_3 Unexecuted instantiation: kyber.c:polyvec_decompress_4 |
678 | | |
679 | | /************************************************* |
680 | | * Name: polyvec_tobytes |
681 | | * |
682 | | * Description: Serialize vector of polynomials |
683 | | * |
684 | | * Arguments: - uint8_t *r: pointer to output byte array |
685 | | * (needs space for KYBER_POLYVECBYTES) |
686 | | * - const polyvec *a: pointer to input vector of polynomials |
687 | | **************************************************/ |
688 | | void polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a) |
689 | 0 | { |
690 | 0 | unsigned int i; |
691 | 0 | for(i=0;i<KYBER_K;i++) |
692 | 0 | poly_tobytes(r+i*KYBER_POLYBYTES, &a->vec[i]); |
693 | 0 | } Unexecuted instantiation: kyber.c:polyvec_tobytes_2 Unexecuted instantiation: kyber.c:polyvec_tobytes_3 Unexecuted instantiation: kyber.c:polyvec_tobytes_4 |
694 | | |
695 | | /************************************************* |
696 | | * Name: polyvec_frombytes |
697 | | * |
698 | | * Description: De-serialize vector of polynomials; |
699 | | * inverse of polyvec_tobytes |
700 | | * |
701 | | * Arguments: - uint8_t *r: pointer to output byte array |
702 | | * - const polyvec *a: pointer to input vector of polynomials |
703 | | * (of length KYBER_POLYVECBYTES) |
704 | | **************************************************/ |
705 | | void polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]) |
706 | 0 | { |
707 | 0 | unsigned int i; |
708 | 0 | for(i=0;i<KYBER_K;i++) |
709 | 0 | poly_frombytes(&r->vec[i], a+i*KYBER_POLYBYTES); |
710 | 0 | } Unexecuted instantiation: kyber.c:polyvec_frombytes_2 Unexecuted instantiation: kyber.c:polyvec_frombytes_3 Unexecuted instantiation: kyber.c:polyvec_frombytes_4 |
711 | | |
712 | | /************************************************* |
713 | | * Name: polyvec_ntt |
714 | | * |
715 | | * Description: Apply forward NTT to all elements of a vector of polynomials |
716 | | * |
717 | | * Arguments: - polyvec *r: pointer to in/output vector of polynomials |
718 | | **************************************************/ |
719 | | void polyvec_ntt(polyvec *r) |
720 | 0 | { |
721 | 0 | unsigned int i; |
722 | 0 | for(i=0;i<KYBER_K;i++) |
723 | 0 | poly_ntt(&r->vec[i]); |
724 | 0 | } Unexecuted instantiation: kyber.c:polyvec_ntt_2 Unexecuted instantiation: kyber.c:polyvec_ntt_3 Unexecuted instantiation: kyber.c:polyvec_ntt_4 |
725 | | |
726 | | /************************************************* |
727 | | * Name: polyvec_invntt_tomont |
728 | | * |
729 | | * Description: Apply inverse NTT to all elements of a vector of polynomials |
730 | | * and multiply by Montgomery factor 2^16 |
731 | | * |
732 | | * Arguments: - polyvec *r: pointer to in/output vector of polynomials |
733 | | **************************************************/ |
734 | | void polyvec_invntt_tomont(polyvec *r) |
735 | 0 | { |
736 | 0 | unsigned int i; |
737 | 0 | for(i=0;i<KYBER_K;i++) |
738 | 0 | poly_invntt_tomont(&r->vec[i]); |
739 | 0 | } Unexecuted instantiation: kyber.c:polyvec_invntt_tomont_2 Unexecuted instantiation: kyber.c:polyvec_invntt_tomont_3 Unexecuted instantiation: kyber.c:polyvec_invntt_tomont_4 |
740 | | |
741 | | /************************************************* |
742 | | * Name: polyvec_basemul_acc_montgomery |
743 | | * |
744 | | * Description: Multiply elements of a and b in NTT domain, accumulate into r, |
745 | | * and multiply by 2^-16. |
746 | | * |
747 | | * Arguments: - poly *r: pointer to output polynomial |
748 | | * - const polyvec *a: pointer to first input vector of polynomials |
749 | | * - const polyvec *b: pointer to second input vector of polynomials |
750 | | **************************************************/ |
751 | | void polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b) |
752 | 0 | { |
753 | 0 | unsigned int i; |
754 | 0 | poly t; |
755 | |
|
756 | 0 | poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]); |
757 | 0 | for(i=1;i<KYBER_K;i++) { |
758 | 0 | poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]); |
759 | 0 | poly_add(r, r, &t); |
760 | 0 | } |
761 | |
|
762 | 0 | poly_reduce(r); |
763 | 0 | } Unexecuted instantiation: kyber.c:polyvec_basemul_acc_montgomery_2 Unexecuted instantiation: kyber.c:polyvec_basemul_acc_montgomery_3 Unexecuted instantiation: kyber.c:polyvec_basemul_acc_montgomery_4 |
764 | | |
765 | | /************************************************* |
766 | | * Name: polyvec_reduce |
767 | | * |
768 | | * Description: Applies Barrett reduction to each coefficient |
769 | | * of each element of a vector of polynomials; |
770 | | * for details of the Barrett reduction see comments in reduce.c |
771 | | * |
772 | | * Arguments: - polyvec *r: pointer to input/output polynomial |
773 | | **************************************************/ |
774 | | void polyvec_reduce(polyvec *r) |
775 | 0 | { |
776 | 0 | unsigned int i; |
777 | 0 | for(i=0;i<KYBER_K;i++) |
778 | 0 | poly_reduce(&r->vec[i]); |
779 | 0 | } Unexecuted instantiation: kyber.c:polyvec_reduce_2 Unexecuted instantiation: kyber.c:polyvec_reduce_3 Unexecuted instantiation: kyber.c:polyvec_reduce_4 |
780 | | |
781 | | /************************************************* |
782 | | * Name: polyvec_add |
783 | | * |
784 | | * Description: Add vectors of polynomials |
785 | | * |
786 | | * Arguments: - polyvec *r: pointer to output vector of polynomials |
787 | | * - const polyvec *a: pointer to first input vector of polynomials |
788 | | * - const polyvec *b: pointer to second input vector of polynomials |
789 | | **************************************************/ |
790 | | void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) |
791 | 0 | { |
792 | 0 | unsigned int i; |
793 | 0 | for(i=0;i<KYBER_K;i++) |
794 | 0 | poly_add(&r->vec[i], &a->vec[i], &b->vec[i]); |
795 | 0 | } Unexecuted instantiation: kyber.c:polyvec_add_2 Unexecuted instantiation: kyber.c:polyvec_add_3 Unexecuted instantiation: kyber.c:polyvec_add_4 |
796 | | |
797 | | /*****************/ |
798 | | #undef KYBER_K |
799 | | #undef KYBER_POLYCOMPRESSEDBYTES |
800 | | #undef KYBER_POLYVECCOMPRESSEDBYTES |
801 | | #undef poly_compress |
802 | | #undef poly_decompress |
803 | | #undef poly_getnoise_eta1 |
804 | | #undef crypto_kem_keypair_derand |
805 | | #undef crypto_kem_enc_derand |
806 | | #undef crypto_kem_keypair |
807 | | #undef crypto_kem_enc |
808 | | #undef crypto_kem_dec |
809 | | #undef polyvec |
810 | | #undef polyvec_compress |
811 | | #undef polyvec_decompress |
812 | | #undef polyvec_tobytes |
813 | | #undef polyvec_frombytes |
814 | | #undef polyvec_ntt |
815 | | #undef polyvec_invntt_tomont |
816 | | #undef polyvec_basemul_acc_montgomery |
817 | | #undef polyvec_reduce |
818 | | #undef polyvec_add |
819 | | #undef pack_pk |
820 | | #undef unpack_pk |
821 | | #undef pack_sk |
822 | | #undef unpack_sk |
823 | | #undef pack_ciphertext |
824 | | #undef unpack_ciphertext |
825 | | #undef gen_matrix |
826 | | #undef indcpa_keypair_derand |
827 | | #undef indcpa_enc |
828 | | #undef indcpa_dec |