Coverage Report

Created: 2024-11-21 07:03

/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