Coverage Report

Created: 2024-05-21 06:36

/src/nss/lib/freebl/kyber-pqcrystals-ref.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 *
4
 * This file was generated from
5
 *   https://github.com/pq-crystals/kyber/commit/e0d1c6ff
6
 *
7
 * Files from that repository are listed here surrounded by
8
 * "* begin: [file] *" and "* end: [file] *" comments.
9
 *
10
 * The following changes have been made:
11
 *  - include guards have been removed,
12
 *  - include directives have been removed,
13
 *  - "#ifdef KYBER90S" blocks have been evaluated with "KYBER90S" undefined,
14
 *  - functions outside of kem.c have been made static.
15
*/
16
17
/** begin: ref/LICENSE **
18
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
19
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
20
21
For Keccak and AES we are using public-domain
22
code from sources and by authors listed in
23
comments on top of the respective files.
24
** end: ref/LICENSE **/
25
26
/** begin: ref/AUTHORS **
27
Joppe Bos,
28
Léo Ducas,
29
Eike Kiltz,
30
Tancrède Lepoint,
31
Vadim Lyubashevsky,
32
John Schanck,
33
Peter Schwabe,
34
Gregor Seiler,
35
Damien Stehlé
36
** end: ref/AUTHORS **/
37
38
#include <assert.h>
39
#include <stddef.h>
40
#include <stdint.h>
41
#include <string.h>
42
43
#ifdef FREEBL_NO_DEPEND
44
#include "stubs.h"
45
#endif
46
47
#include "secport.h"
48
49
// We need to provide an implementation of randombytes to avoid an unused
50
// function warning. We don't use the randomized API in freebl, so we'll make
51
// calling randombytes an error.
52
static void
53
randombytes(uint8_t *out, size_t outlen)
54
0
{
55
    // this memset is to avoid "maybe-uninitialized" warnings that gcc-11 issues
56
    // for the (unused) crypto_kem_keypair and crypto_kem_enc functions.
57
0
    memset(out, 0, outlen);
58
0
    assert(0);
59
0
}
60
61
/*************************************************
62
* Name:        verify
63
*
64
* Description: Compare two arrays for equality in constant time.
65
*
66
* Arguments:   const uint8_t *a: pointer to first byte array
67
*              const uint8_t *b: pointer to second byte array
68
*              size_t len:       length of the byte arrays
69
*
70
* Returns 0 if the byte arrays are equal, 1 otherwise
71
**************************************************/
72
static int
73
verify(const uint8_t *a, const uint8_t *b, size_t len)
74
0
{
75
0
    return NSS_SecureMemcmp(a, b, len);
76
0
}
77
78
/*************************************************
79
* Name:        cmov
80
*
81
* Description: Copy len bytes from x to r if b is 1;
82
*              don't modify x if b is 0. Requires b to be in {0,1};
83
*              assumes two's complement representation of negative integers.
84
*              Runs in constant time.
85
*
86
* Arguments:   uint8_t *r:       pointer to output byte array
87
*              const uint8_t *x: pointer to input byte array
88
*              size_t len:       Amount of bytes to be copied
89
*              uint8_t b:        Condition bit; has to be in {0,1}
90
**************************************************/
91
static void
92
cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b)
93
0
{
94
0
    NSS_SecureSelect(r, r, x, len, b);
95
0
}
96
97
/** begin: ref/params.h **/
98
#ifndef KYBER_K
99
#define KYBER_K 3 /* Change this for different security strengths */
100
#endif
101
102
//#define KYBER_90S /* Uncomment this if you want the 90S variant */
103
104
/* Don't change parameters below this line */
105
#if (KYBER_K == 2)
106
#define KYBER_NAMESPACE(s) pqcrystals_kyber512_ref_##s
107
#elif (KYBER_K == 3)
108
0
#define KYBER_NAMESPACE(s) pqcrystals_kyber768_ref_##s
109
#elif (KYBER_K == 4)
110
#define KYBER_NAMESPACE(s) pqcrystals_kyber1024_ref_##s
111
#else
112
#error "KYBER_K must be in {2,3,4}"
113
#endif
114
115
0
#define KYBER_N 256
116
0
#define KYBER_Q 3329
117
118
0
#define KYBER_SYMBYTES 32 /* size in bytes of hashes, and seeds */
119
0
#define KYBER_SSBYTES 32  /* size in bytes of shared key */
120
121
0
#define KYBER_POLYBYTES 384
122
0
#define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES)
123
124
#if KYBER_K == 2
125
#define KYBER_ETA1 3
126
#define KYBER_POLYCOMPRESSEDBYTES 128
127
#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 320)
128
#elif KYBER_K == 3
129
#define KYBER_ETA1 2
130
0
#define KYBER_POLYCOMPRESSEDBYTES 128
131
0
#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 320)
132
#elif KYBER_K == 4
133
#define KYBER_ETA1 2
134
#define KYBER_POLYCOMPRESSEDBYTES 160
135
#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 352)
136
#endif
137
138
#define KYBER_ETA2 2
139
140
#define KYBER_INDCPA_MSGBYTES (KYBER_SYMBYTES)
141
0
#define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECBYTES + KYBER_SYMBYTES)
142
0
#define KYBER_INDCPA_SECRETKEYBYTES (KYBER_POLYVECBYTES)
143
0
#define KYBER_INDCPA_BYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_POLYCOMPRESSEDBYTES)
144
145
#define KYBER_PUBLICKEYBYTES (KYBER_INDCPA_PUBLICKEYBYTES)
146
/* 32 bytes of additional space to save H(pk) */
147
0
#define KYBER_SECRETKEYBYTES (KYBER_INDCPA_SECRETKEYBYTES + KYBER_INDCPA_PUBLICKEYBYTES + 2 * KYBER_SYMBYTES)
148
0
#define KYBER_CIPHERTEXTBYTES (KYBER_INDCPA_BYTES)
149
/** end: ref/params.h **/
150
151
/** begin: ref/reduce.h **/
152
#define MONT -1044 // 2^16 mod q
153
0
#define QINV -3327 // q^-1 mod 2^16
154
155
0
#define montgomery_reduce KYBER_NAMESPACE(montgomery_reduce)
156
static int16_t montgomery_reduce(int32_t a);
157
158
0
#define barrett_reduce KYBER_NAMESPACE(barrett_reduce)
159
static int16_t barrett_reduce(int16_t a);
160
/** end: ref/reduce.h **/
161
162
/** begin: ref/ntt.h **/
163
0
#define zetas KYBER_NAMESPACE(zetas)
164
extern const int16_t zetas[128];
165
166
0
#define ntt KYBER_NAMESPACE(ntt)
167
static void ntt(int16_t poly[256]);
168
169
0
#define invntt KYBER_NAMESPACE(invntt)
170
static void invntt(int16_t poly[256]);
171
172
0
#define basemul KYBER_NAMESPACE(basemul)
173
static void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta);
174
/** end: ref/ntt.h **/
175
176
/** begin: ref/poly.h **/
177
/*
178
 * Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial
179
 * coeffs[0] + X*coeffs[1] + X^2*coeffs[2] + ... + X^{n-1}*coeffs[n-1]
180
 */
181
typedef struct {
182
    int16_t coeffs[KYBER_N];
183
} poly;
184
185
0
#define poly_compress KYBER_NAMESPACE(poly_compress)
186
static void poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a);
187
0
#define poly_decompress KYBER_NAMESPACE(poly_decompress)
188
static void poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES]);
189
190
0
#define poly_tobytes KYBER_NAMESPACE(poly_tobytes)
191
static void poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a);
192
0
#define poly_frombytes KYBER_NAMESPACE(poly_frombytes)
193
static void poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]);
194
195
0
#define poly_frommsg KYBER_NAMESPACE(poly_frommsg)
196
static void poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]);
197
0
#define poly_tomsg KYBER_NAMESPACE(poly_tomsg)
198
static void poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *r);
199
200
0
#define poly_getnoise_eta1 KYBER_NAMESPACE(poly_getnoise_eta1)
201
static void poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
202
203
0
#define poly_getnoise_eta2 KYBER_NAMESPACE(poly_getnoise_eta2)
204
static void poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
205
206
0
#define poly_ntt KYBER_NAMESPACE(poly_ntt)
207
static void poly_ntt(poly *r);
208
0
#define poly_invntt_tomont KYBER_NAMESPACE(poly_invntt_tomont)
209
static void poly_invntt_tomont(poly *r);
210
0
#define poly_basemul_montgomery KYBER_NAMESPACE(poly_basemul_montgomery)
211
static void poly_basemul_montgomery(poly *r, const poly *a, const poly *b);
212
0
#define poly_tomont KYBER_NAMESPACE(poly_tomont)
213
static void poly_tomont(poly *r);
214
215
0
#define poly_reduce KYBER_NAMESPACE(poly_reduce)
216
static void poly_reduce(poly *r);
217
218
0
#define poly_add KYBER_NAMESPACE(poly_add)
219
static void poly_add(poly *r, const poly *a, const poly *b);
220
0
#define poly_sub KYBER_NAMESPACE(poly_sub)
221
static void poly_sub(poly *r, const poly *a, const poly *b);
222
/** end: ref/poly.h **/
223
224
/** begin: ref/cbd.h **/
225
0
#define poly_cbd_eta1 KYBER_NAMESPACE(poly_cbd_eta1)
226
static void poly_cbd_eta1(poly *r, const uint8_t buf[KYBER_ETA1 * KYBER_N / 4]);
227
228
0
#define poly_cbd_eta2 KYBER_NAMESPACE(poly_cbd_eta2)
229
static void poly_cbd_eta2(poly *r, const uint8_t buf[KYBER_ETA2 * KYBER_N / 4]);
230
/** end: ref/cbd.h **/
231
232
/** begin: ref/polyvec.h **/
233
typedef struct {
234
    poly vec[KYBER_K];
235
} polyvec;
236
237
0
#define polyvec_compress KYBER_NAMESPACE(polyvec_compress)
238
static void polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a);
239
0
#define polyvec_decompress KYBER_NAMESPACE(polyvec_decompress)
240
static void polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]);
241
242
0
#define polyvec_tobytes KYBER_NAMESPACE(polyvec_tobytes)
243
static void polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a);
244
0
#define polyvec_frombytes KYBER_NAMESPACE(polyvec_frombytes)
245
static void polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]);
246
247
0
#define polyvec_ntt KYBER_NAMESPACE(polyvec_ntt)
248
static void polyvec_ntt(polyvec *r);
249
0
#define polyvec_invntt_tomont KYBER_NAMESPACE(polyvec_invntt_tomont)
250
static void polyvec_invntt_tomont(polyvec *r);
251
252
0
#define polyvec_basemul_acc_montgomery KYBER_NAMESPACE(polyvec_basemul_acc_montgomery)
253
static void polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b);
254
255
0
#define polyvec_reduce KYBER_NAMESPACE(polyvec_reduce)
256
static void polyvec_reduce(polyvec *r);
257
258
0
#define polyvec_add KYBER_NAMESPACE(polyvec_add)
259
static void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b);
260
/** end: ref/polyvec.h **/
261
262
/** begin: ref/indcpa.h **/
263
0
#define gen_matrix KYBER_NAMESPACE(gen_matrix)
264
static void gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed);
265
266
0
#define indcpa_keypair_derand KYBER_NAMESPACE(indcpa_keypair_derand)
267
static void indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
268
                                  uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES],
269
                                  const uint8_t coins[KYBER_SYMBYTES]);
270
271
0
#define indcpa_enc KYBER_NAMESPACE(indcpa_enc)
272
static void indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES],
273
                       const uint8_t m[KYBER_INDCPA_MSGBYTES],
274
                       const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
275
                       const uint8_t coins[KYBER_SYMBYTES]);
276
277
0
#define indcpa_dec KYBER_NAMESPACE(indcpa_dec)
278
static void indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES],
279
                       const uint8_t c[KYBER_INDCPA_BYTES],
280
                       const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]);
281
/** end: ref/indcpa.h **/
282
283
/** begin: ref/fips202.h **/
284
0
#define SHAKE128_RATE 168
285
0
#define SHAKE256_RATE 136
286
0
#define SHA3_256_RATE 136
287
0
#define SHA3_512_RATE 72
288
289
0
#define FIPS202_NAMESPACE(s) pqcrystals_kyber_fips202_ref_##s
290
291
typedef struct {
292
    uint64_t s[25];
293
    unsigned int pos;
294
} keccak_state;
295
296
#define shake128_init FIPS202_NAMESPACE(shake128_init)
297
void shake128_init(keccak_state *state);
298
#define shake128_absorb FIPS202_NAMESPACE(shake128_absorb)
299
void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
300
#define shake128_finalize FIPS202_NAMESPACE(shake128_finalize)
301
void shake128_finalize(keccak_state *state);
302
0
#define shake128_squeeze FIPS202_NAMESPACE(shake128_squeeze)
303
void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
304
0
#define shake128_absorb_once FIPS202_NAMESPACE(shake128_absorb_once)
305
void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
306
0
#define shake128_squeezeblocks FIPS202_NAMESPACE(shake128_squeezeblocks)
307
void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
308
309
#define shake256_init FIPS202_NAMESPACE(shake256_init)
310
void shake256_init(keccak_state *state);
311
#define shake256_absorb FIPS202_NAMESPACE(shake256_absorb)
312
void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
313
#define shake256_finalize FIPS202_NAMESPACE(shake256_finalize)
314
void shake256_finalize(keccak_state *state);
315
0
#define shake256_squeeze FIPS202_NAMESPACE(shake256_squeeze)
316
void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
317
0
#define shake256_absorb_once FIPS202_NAMESPACE(shake256_absorb_once)
318
void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
319
0
#define shake256_squeezeblocks FIPS202_NAMESPACE(shake256_squeezeblocks)
320
void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
321
322
#define shake128 FIPS202_NAMESPACE(shake128)
323
void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
324
0
#define shake256 FIPS202_NAMESPACE(shake256)
325
void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
326
0
#define sha3_256 FIPS202_NAMESPACE(sha3_256)
327
void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen);
328
0
#define sha3_512 FIPS202_NAMESPACE(sha3_512)
329
void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen);
330
/** end: ref/fips202.h **/
331
332
/** begin: ref/symmetric.h **/
333
typedef keccak_state xof_state;
334
335
0
#define kyber_shake128_absorb KYBER_NAMESPACE(kyber_shake128_absorb)
336
static void kyber_shake128_absorb(keccak_state *s,
337
                                  const uint8_t seed[KYBER_SYMBYTES],
338
                                  uint8_t x,
339
                                  uint8_t y);
340
341
0
#define kyber_shake256_prf KYBER_NAMESPACE(kyber_shake256_prf)
342
static void kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYMBYTES], uint8_t nonce);
343
344
0
#define XOF_BLOCKBYTES SHAKE128_RATE
345
346
0
#define hash_h(OUT, IN, INBYTES) sha3_256(OUT, IN, INBYTES)
347
0
#define hash_g(OUT, IN, INBYTES) sha3_512(OUT, IN, INBYTES)
348
0
#define xof_absorb(STATE, SEED, X, Y) kyber_shake128_absorb(STATE, SEED, X, Y)
349
0
#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
350
0
#define prf(OUT, OUTBYTES, KEY, NONCE) kyber_shake256_prf(OUT, OUTBYTES, KEY, NONCE)
351
0
#define kdf(OUT, IN, INBYTES) shake256(OUT, KYBER_SSBYTES, IN, INBYTES)
352
/** end: ref/symmetric.h **/
353
354
/** begin: ref/kem.h **/
355
#define CRYPTO_SECRETKEYBYTES KYBER_SECRETKEYBYTES
356
#define CRYPTO_PUBLICKEYBYTES KYBER_PUBLICKEYBYTES
357
#define CRYPTO_CIPHERTEXTBYTES KYBER_CIPHERTEXTBYTES
358
#define CRYPTO_BYTES KYBER_SSBYTES
359
360
#if (KYBER_K == 2)
361
#define CRYPTO_ALGNAME "Kyber512"
362
#elif (KYBER_K == 3)
363
#define CRYPTO_ALGNAME "Kyber768"
364
#elif (KYBER_K == 4)
365
#define CRYPTO_ALGNAME "Kyber1024"
366
#endif
367
368
0
#define crypto_kem_keypair_derand KYBER_NAMESPACE(keypair_derand)
369
int crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins);
370
371
#define crypto_kem_keypair KYBER_NAMESPACE(keypair)
372
int crypto_kem_keypair(uint8_t *pk, uint8_t *sk);
373
374
0
#define crypto_kem_enc_derand KYBER_NAMESPACE(enc_derand)
375
int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins);
376
377
#define crypto_kem_enc KYBER_NAMESPACE(enc)
378
int crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);
379
380
#define crypto_kem_dec KYBER_NAMESPACE(dec)
381
int crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk);
382
/** end: ref/kem.h **/
383
384
/** begin: ref/reduce.c **/
385
/*************************************************
386
* Name:        montgomery_reduce
387
*
388
* Description: Montgomery reduction; given a 32-bit integer a, computes
389
*              16-bit integer congruent to a * R^-1 mod q, where R=2^16
390
*
391
* Arguments:   - int32_t a: input integer to be reduced;
392
*                           has to be in {-q2^15,...,q2^15-1}
393
*
394
* Returns:     integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q.
395
**************************************************/
396
static int16_t
397
montgomery_reduce(int32_t a)
398
0
{
399
0
    int16_t t;
400
401
0
    t = (int16_t)a * QINV;
402
0
    t = (a - (int32_t)t * KYBER_Q) >> 16;
403
0
    return t;
404
0
}
405
406
/*************************************************
407
* Name:        barrett_reduce
408
*
409
* Description: Barrett reduction; given a 16-bit integer a, computes
410
*              centered representative congruent to a mod q in {-(q-1)/2,...,(q-1)/2}
411
*
412
* Arguments:   - int16_t a: input integer to be reduced
413
*
414
* Returns:     integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
415
**************************************************/
416
static int16_t
417
barrett_reduce(int16_t a)
418
0
{
419
0
    int16_t t;
420
0
    const int16_t v = ((1 << 26) + KYBER_Q / 2) / KYBER_Q;
421
422
0
    t = ((int32_t)v * a + (1 << 25)) >> 26;
423
0
    t *= KYBER_Q;
424
0
    return a - t;
425
0
}
426
/** end: ref/reduce.c **/
427
428
/** begin: ref/cbd.c **/
429
/*************************************************
430
* Name:        load32_littleendian
431
*
432
* Description: load 4 bytes into a 32-bit integer
433
*              in little-endian order
434
*
435
* Arguments:   - const uint8_t *x: pointer to input byte array
436
*
437
* Returns 32-bit unsigned integer loaded from x
438
**************************************************/
439
static uint32_t
440
load32_littleendian(const uint8_t x[4])
441
0
{
442
0
    uint32_t r;
443
0
    r = (uint32_t)x[0];
444
0
    r |= (uint32_t)x[1] << 8;
445
0
    r |= (uint32_t)x[2] << 16;
446
0
    r |= (uint32_t)x[3] << 24;
447
0
    return r;
448
0
}
449
450
/*************************************************
451
* Name:        load24_littleendian
452
*
453
* Description: load 3 bytes into a 32-bit integer
454
*              in little-endian order.
455
*              This function is only needed for Kyber-512
456
*
457
* Arguments:   - const uint8_t *x: pointer to input byte array
458
*
459
* Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
460
**************************************************/
461
#if KYBER_ETA1 == 3
462
static uint32_t
463
load24_littleendian(const uint8_t x[3])
464
{
465
    uint32_t r;
466
    r = (uint32_t)x[0];
467
    r |= (uint32_t)x[1] << 8;
468
    r |= (uint32_t)x[2] << 16;
469
    return r;
470
}
471
#endif
472
473
/*************************************************
474
* Name:        cbd2
475
*
476
* Description: Given an array of uniformly random bytes, compute
477
*              polynomial with coefficients distributed according to
478
*              a centered binomial distribution with parameter eta=2
479
*
480
* Arguments:   - poly *r: pointer to output polynomial
481
*              - const uint8_t *buf: pointer to input byte array
482
**************************************************/
483
static void
484
cbd2(poly *r, const uint8_t buf[2 * KYBER_N / 4])
485
0
{
486
0
    unsigned int i, j;
487
0
    uint32_t t, d;
488
0
    int16_t a, b;
489
490
0
    for (i = 0; i < KYBER_N / 8; i++) {
491
0
        t = load32_littleendian(buf + 4 * i);
492
0
        d = t & 0x55555555;
493
0
        d += (t >> 1) & 0x55555555;
494
495
0
        for (j = 0; j < 8; j++) {
496
0
            a = (d >> (4 * j + 0)) & 0x3;
497
0
            b = (d >> (4 * j + 2)) & 0x3;
498
0
            r->coeffs[8 * i + j] = a - b;
499
0
        }
500
0
    }
501
0
}
502
503
/*************************************************
504
* Name:        cbd3
505
*
506
* Description: Given an array of uniformly random bytes, compute
507
*              polynomial with coefficients distributed according to
508
*              a centered binomial distribution with parameter eta=3.
509
*              This function is only needed for Kyber-512
510
*
511
* Arguments:   - poly *r: pointer to output polynomial
512
*              - const uint8_t *buf: pointer to input byte array
513
**************************************************/
514
#if KYBER_ETA1 == 3
515
static void
516
cbd3(poly *r, const uint8_t buf[3 * KYBER_N / 4])
517
{
518
    unsigned int i, j;
519
    uint32_t t, d;
520
    int16_t a, b;
521
522
    for (i = 0; i < KYBER_N / 4; i++) {
523
        t = load24_littleendian(buf + 3 * i);
524
        d = t & 0x00249249;
525
        d += (t >> 1) & 0x00249249;
526
        d += (t >> 2) & 0x00249249;
527
528
        for (j = 0; j < 4; j++) {
529
            a = (d >> (6 * j + 0)) & 0x7;
530
            b = (d >> (6 * j + 3)) & 0x7;
531
            r->coeffs[4 * i + j] = a - b;
532
        }
533
    }
534
}
535
#endif
536
537
static void
538
poly_cbd_eta1(poly *r, const uint8_t buf[KYBER_ETA1 * KYBER_N / 4])
539
0
{
540
0
#if KYBER_ETA1 == 2
541
0
    cbd2(r, buf);
542
#elif KYBER_ETA1 == 3
543
    cbd3(r, buf);
544
#else
545
#error "This implementation requires eta1 in {2,3}"
546
#endif
547
0
}
548
549
static void
550
poly_cbd_eta2(poly *r, const uint8_t buf[KYBER_ETA2 * KYBER_N / 4])
551
0
{
552
0
#if KYBER_ETA2 == 2
553
0
    cbd2(r, buf);
554
#else
555
#error "This implementation requires eta2 = 2"
556
#endif
557
0
}
558
/** end: ref/cbd.c **/
559
560
/** begin: ref/ntt.c **/
561
/* Code to generate zetas and zetas_inv used in the number-theoretic transform:
562
563
#define KYBER_ROOT_OF_UNITY 17
564
565
static const uint8_t tree[128] = {
566
  0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120,
567
  4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124,
568
  2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122,
569
  6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126,
570
  1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121,
571
  5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125,
572
  3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123,
573
  7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127
574
};
575
576
static void init_ntt() {
577
  unsigned int i;
578
  int16_t tmp[128];
579
580
  tmp[0] = MONT;
581
  for(i=1;i<128;i++)
582
    tmp[i] = fqmul(tmp[i-1],MONT*KYBER_ROOT_OF_UNITY % KYBER_Q);
583
584
  for(i=0;i<128;i++) {
585
    zetas[i] = tmp[tree[i]];
586
    if(zetas[i] > KYBER_Q/2)
587
      zetas[i] -= KYBER_Q;
588
    if(zetas[i] < -KYBER_Q/2)
589
      zetas[i] += KYBER_Q;
590
  }
591
}
592
*/
593
594
const int16_t zetas[128] = {
595
    -1044, -758, -359, -1517, 1493, 1422, 287, 202,
596
    -171, 622, 1577, 182, 962, -1202, -1474, 1468,
597
    573, -1325, 264, 383, -829, 1458, -1602, -130,
598
    -681, 1017, 732, 608, -1542, 411, -205, -1571,
599
    1223, 652, -552, 1015, -1293, 1491, -282, -1544,
600
    516, -8, -320, -666, -1618, -1162, 126, 1469,
601
    -853, -90, -271, 830, 107, -1421, -247, -951,
602
    -398, 961, -1508, -725, 448, -1065, 677, -1275,
603
    -1103, 430, 555, 843, -1251, 871, 1550, 105,
604
    422, 587, 177, -235, -291, -460, 1574, 1653,
605
    -246, 778, 1159, -147, -777, 1483, -602, 1119,
606
    -1590, 644, -872, 349, 418, 329, -156, -75,
607
    817, 1097, 603, 610, 1322, -1285, -1465, 384,
608
    -1215, -136, 1218, -1335, -874, 220, -1187, -1659,
609
    -1185, -1530, -1278, 794, -1510, -854, -870, 478,
610
    -108, -308, 996, 991, 958, -1460, 1522, 1628
611
};
612
613
/*************************************************
614
* Name:        fqmul
615
*
616
* Description: Multiplication followed by Montgomery reduction
617
*
618
* Arguments:   - int16_t a: first factor
619
*              - int16_t b: second factor
620
*
621
* Returns 16-bit integer congruent to a*b*R^{-1} mod q
622
**************************************************/
623
static int16_t
624
fqmul(int16_t a, int16_t b)
625
0
{
626
0
    return montgomery_reduce((int32_t)a * b);
627
0
}
628
629
/*************************************************
630
* Name:        ntt
631
*
632
* Description: Inplace number-theoretic transform (NTT) in Rq.
633
*              input is in standard order, output is in bitreversed order
634
*
635
* Arguments:   - int16_t r[256]: pointer to input/output vector of elements of Zq
636
**************************************************/
637
static void
638
ntt(int16_t r[256])
639
0
{
640
0
    unsigned int len, start, j, k;
641
0
    int16_t t, zeta;
642
643
0
    k = 1;
644
0
    for (len = 128; len >= 2; len >>= 1) {
645
0
        for (start = 0; start < 256; start = j + len) {
646
0
            zeta = zetas[k++];
647
0
            for (j = start; j < start + len; j++) {
648
0
                t = fqmul(zeta, r[j + len]);
649
0
                r[j + len] = r[j] - t;
650
0
                r[j] = r[j] + t;
651
0
            }
652
0
        }
653
0
    }
654
0
}
655
656
/*************************************************
657
* Name:        invntt_tomont
658
*
659
* Description: Inplace inverse number-theoretic transform in Rq and
660
*              multiplication by Montgomery factor 2^16.
661
*              Input is in bitreversed order, output is in standard order
662
*
663
* Arguments:   - int16_t r[256]: pointer to input/output vector of elements of Zq
664
**************************************************/
665
static void
666
invntt(int16_t r[256])
667
0
{
668
0
    unsigned int start, len, j, k;
669
0
    int16_t t, zeta;
670
0
    const int16_t f = 1441; // mont^2/128
671
672
0
    k = 127;
673
0
    for (len = 2; len <= 128; len <<= 1) {
674
0
        for (start = 0; start < 256; start = j + len) {
675
0
            zeta = zetas[k--];
676
0
            for (j = start; j < start + len; j++) {
677
0
                t = r[j];
678
0
                r[j] = barrett_reduce(t + r[j + len]);
679
0
                r[j + len] = r[j + len] - t;
680
0
                r[j + len] = fqmul(zeta, r[j + len]);
681
0
            }
682
0
        }
683
0
    }
684
685
0
    for (j = 0; j < 256; j++)
686
0
        r[j] = fqmul(r[j], f);
687
0
}
688
689
/*************************************************
690
* Name:        basemul
691
*
692
* Description: Multiplication of polynomials in Zq[X]/(X^2-zeta)
693
*              used for multiplication of elements in Rq in NTT domain
694
*
695
* Arguments:   - int16_t r[2]: pointer to the output polynomial
696
*              - const int16_t a[2]: pointer to the first factor
697
*              - const int16_t b[2]: pointer to the second factor
698
*              - int16_t zeta: integer defining the reduction polynomial
699
**************************************************/
700
static void
701
basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta)
702
0
{
703
0
    r[0] = fqmul(a[1], b[1]);
704
0
    r[0] = fqmul(r[0], zeta);
705
0
    r[0] += fqmul(a[0], b[0]);
706
0
    r[1] = fqmul(a[0], b[1]);
707
0
    r[1] += fqmul(a[1], b[0]);
708
0
}
709
/** end: ref/ntt.c **/
710
711
/** begin: ref/poly.c **/
712
/*************************************************
713
* Name:        poly_compress
714
*
715
* Description: Compression and subsequent serialization of a polynomial
716
*
717
* Arguments:   - uint8_t *r: pointer to output byte array
718
*                            (of length KYBER_POLYCOMPRESSEDBYTES)
719
*              - const poly *a: pointer to input polynomial
720
**************************************************/
721
static void
722
poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a)
723
0
{
724
0
    unsigned int i, j;
725
0
    int16_t u;
726
0
    uint32_t d0;
727
0
    uint8_t t[8];
728
729
0
#if (KYBER_POLYCOMPRESSEDBYTES == 128)
730
0
    for (i = 0; i < KYBER_N / 8; i++) {
731
0
        for (j = 0; j < 8; j++) {
732
            // map to positive standard representatives
733
0
            u = a->coeffs[8 * i + j];
734
0
            u += (u >> 15) & KYBER_Q;
735
            /*    t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15; */
736
0
            d0 = u << 4;
737
0
            d0 += 1665;
738
0
            d0 *= 80635;
739
0
            d0 >>= 28;
740
0
            t[j] = d0 & 0xf;
741
0
        }
742
743
0
        r[0] = t[0] | (t[1] << 4);
744
0
        r[1] = t[2] | (t[3] << 4);
745
0
        r[2] = t[4] | (t[5] << 4);
746
0
        r[3] = t[6] | (t[7] << 4);
747
0
        r += 4;
748
0
    }
749
#elif (KYBER_POLYCOMPRESSEDBYTES == 160)
750
    for (i = 0; i < KYBER_N / 8; i++) {
751
        for (j = 0; j < 8; j++) {
752
            // map to positive standard representatives
753
            u = a->coeffs[8 * i + j];
754
            u += (u >> 15) & KYBER_Q;
755
            /*      t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31; */
756
            d0 = u << 5;
757
            d0 += 1664;
758
            d0 *= 40318;
759
            d0 >>= 27;
760
            t[j] = d0 & 0x1f;
761
        }
762
763
        r[0] = (t[0] >> 0) | (t[1] << 5);
764
        r[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
765
        r[2] = (t[3] >> 1) | (t[4] << 4);
766
        r[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6);
767
        r[4] = (t[6] >> 2) | (t[7] << 3);
768
        r += 5;
769
    }
770
#else
771
#error "KYBER_POLYCOMPRESSEDBYTES needs to be in {128, 160}"
772
#endif
773
0
}
774
775
/*************************************************
776
* Name:        poly_decompress
777
*
778
* Description: De-serialization and subsequent decompression of a polynomial;
779
*              approximate inverse of poly_compress
780
*
781
* Arguments:   - poly *r: pointer to output polynomial
782
*              - const uint8_t *a: pointer to input byte array
783
*                                  (of length KYBER_POLYCOMPRESSEDBYTES bytes)
784
**************************************************/
785
static void
786
poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES])
787
0
{
788
0
    unsigned int i;
789
790
0
#if (KYBER_POLYCOMPRESSEDBYTES == 128)
791
0
    for (i = 0; i < KYBER_N / 2; i++) {
792
0
        r->coeffs[2 * i + 0] = (((uint16_t)(a[0] & 15) * KYBER_Q) + 8) >> 4;
793
0
        r->coeffs[2 * i + 1] = (((uint16_t)(a[0] >> 4) * KYBER_Q) + 8) >> 4;
794
0
        a += 1;
795
0
    }
796
#elif (KYBER_POLYCOMPRESSEDBYTES == 160)
797
    unsigned int j;
798
    uint8_t t[8];
799
    for (i = 0; i < KYBER_N / 8; i++) {
800
        t[0] = (a[0] >> 0);
801
        t[1] = (a[0] >> 5) | (a[1] << 3);
802
        t[2] = (a[1] >> 2);
803
        t[3] = (a[1] >> 7) | (a[2] << 1);
804
        t[4] = (a[2] >> 4) | (a[3] << 4);
805
        t[5] = (a[3] >> 1);
806
        t[6] = (a[3] >> 6) | (a[4] << 2);
807
        t[7] = (a[4] >> 3);
808
        a += 5;
809
810
        for (j = 0; j < 8; j++)
811
            r->coeffs[8 * i + j] = ((uint32_t)(t[j] & 31) * KYBER_Q + 16) >> 5;
812
    }
813
#else
814
#error "KYBER_POLYCOMPRESSEDBYTES needs to be in {128, 160}"
815
#endif
816
0
}
817
818
/*************************************************
819
* Name:        poly_tobytes
820
*
821
* Description: Serialization of a polynomial
822
*
823
* Arguments:   - uint8_t *r: pointer to output byte array
824
*                            (needs space for KYBER_POLYBYTES bytes)
825
*              - const poly *a: pointer to input polynomial
826
**************************************************/
827
static void
828
poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a)
829
0
{
830
0
    unsigned int i;
831
0
    uint16_t t0, t1;
832
833
0
    for (i = 0; i < KYBER_N / 2; i++) {
834
        // map to positive standard representatives
835
0
        t0 = a->coeffs[2 * i];
836
0
        t0 += ((int16_t)t0 >> 15) & KYBER_Q;
837
0
        t1 = a->coeffs[2 * i + 1];
838
0
        t1 += ((int16_t)t1 >> 15) & KYBER_Q;
839
0
        r[3 * i + 0] = (t0 >> 0);
840
0
        r[3 * i + 1] = (t0 >> 8) | (t1 << 4);
841
0
        r[3 * i + 2] = (t1 >> 4);
842
0
    }
843
0
}
844
845
/*************************************************
846
* Name:        poly_frombytes
847
*
848
* Description: De-serialization of a polynomial;
849
*              inverse of poly_tobytes
850
*
851
* Arguments:   - poly *r: pointer to output polynomial
852
*              - const uint8_t *a: pointer to input byte array
853
*                                  (of KYBER_POLYBYTES bytes)
854
**************************************************/
855
static void
856
poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES])
857
0
{
858
0
    unsigned int i;
859
0
    for (i = 0; i < KYBER_N / 2; i++) {
860
0
        r->coeffs[2 * i] = ((a[3 * i + 0] >> 0) | ((uint16_t)a[3 * i + 1] << 8)) & 0xFFF;
861
0
        r->coeffs[2 * i + 1] = ((a[3 * i + 1] >> 4) | ((uint16_t)a[3 * i + 2] << 4)) & 0xFFF;
862
0
    }
863
0
}
864
865
/*************************************************
866
* Name:        poly_frommsg
867
*
868
* Description: Convert 32-byte message to polynomial
869
*
870
* Arguments:   - poly *r: pointer to output polynomial
871
*              - const uint8_t *msg: pointer to input message
872
**************************************************/
873
static void
874
poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES])
875
0
{
876
0
    unsigned int i, j;
877
0
    int16_t mask;
878
879
#if (KYBER_INDCPA_MSGBYTES != KYBER_N / 8)
880
#error "KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!"
881
#endif
882
883
0
    for (i = 0; i < KYBER_N / 8; i++) {
884
0
        for (j = 0; j < 8; j++) {
885
0
            mask = -(int16_t)((msg[i] >> j) & 1);
886
0
            r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2);
887
0
        }
888
0
    }
889
0
}
890
891
/*************************************************
892
* Name:        poly_tomsg
893
*
894
* Description: Convert polynomial to 32-byte message
895
*
896
* Arguments:   - uint8_t *msg: pointer to output message
897
*              - const poly *a: pointer to input polynomial
898
**************************************************/
899
static void
900
poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a)
901
0
{
902
0
    unsigned int i, j;
903
0
    uint32_t t;
904
905
0
    for (i = 0; i < KYBER_N / 8; i++) {
906
0
        msg[i] = 0;
907
0
        for (j = 0; j < 8; j++) {
908
0
            t = a->coeffs[8 * i + j];
909
            // t += ((int16_t)t >> 15) & KYBER_Q;
910
            // t  = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1;
911
0
            t <<= 1;
912
0
            t += 1665;
913
0
            t *= 80635;
914
0
            t >>= 28;
915
0
            t &= 1;
916
0
            msg[i] |= t << j;
917
0
        }
918
0
    }
919
0
}
920
921
/*************************************************
922
* Name:        poly_getnoise_eta1
923
*
924
* Description: Sample a polynomial deterministically from a seed and a nonce,
925
*              with output polynomial close to centered binomial distribution
926
*              with parameter KYBER_ETA1
927
*
928
* Arguments:   - poly *r: pointer to output polynomial
929
*              - const uint8_t *seed: pointer to input seed
930
*                                     (of length KYBER_SYMBYTES bytes)
931
*              - uint8_t nonce: one-byte input nonce
932
**************************************************/
933
static void
934
poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
935
0
{
936
0
    uint8_t buf[KYBER_ETA1 * KYBER_N / 4];
937
0
    prf(buf, sizeof(buf), seed, nonce);
938
0
    poly_cbd_eta1(r, buf);
939
0
}
940
941
/*************************************************
942
* Name:        poly_getnoise_eta2
943
*
944
* Description: Sample a polynomial deterministically from a seed and a nonce,
945
*              with output polynomial close to centered binomial distribution
946
*              with parameter KYBER_ETA2
947
*
948
* Arguments:   - poly *r: pointer to output polynomial
949
*              - const uint8_t *seed: pointer to input seed
950
*                                     (of length KYBER_SYMBYTES bytes)
951
*              - uint8_t nonce: one-byte input nonce
952
**************************************************/
953
static void
954
poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
955
0
{
956
0
    uint8_t buf[KYBER_ETA2 * KYBER_N / 4];
957
0
    prf(buf, sizeof(buf), seed, nonce);
958
0
    poly_cbd_eta2(r, buf);
959
0
}
960
961
/*************************************************
962
* Name:        poly_ntt
963
*
964
* Description: Computes negacyclic number-theoretic transform (NTT) of
965
*              a polynomial in place;
966
*              inputs assumed to be in normal order, output in bitreversed order
967
*
968
* Arguments:   - uint16_t *r: pointer to in/output polynomial
969
**************************************************/
970
static void
971
poly_ntt(poly *r)
972
0
{
973
0
    ntt(r->coeffs);
974
0
    poly_reduce(r);
975
0
}
976
977
/*************************************************
978
* Name:        poly_invntt_tomont
979
*
980
* Description: Computes inverse of negacyclic number-theoretic transform (NTT)
981
*              of a polynomial in place;
982
*              inputs assumed to be in bitreversed order, output in normal order
983
*
984
* Arguments:   - uint16_t *a: pointer to in/output polynomial
985
**************************************************/
986
static void
987
poly_invntt_tomont(poly *r)
988
0
{
989
0
    invntt(r->coeffs);
990
0
}
991
992
/*************************************************
993
* Name:        poly_basemul_montgomery
994
*
995
* Description: Multiplication of two polynomials in NTT domain
996
*
997
* Arguments:   - poly *r: pointer to output polynomial
998
*              - const poly *a: pointer to first input polynomial
999
*              - const poly *b: pointer to second input polynomial
1000
**************************************************/
1001
static void
1002
poly_basemul_montgomery(poly *r, const poly *a, const poly *b)
1003
0
{
1004
0
    unsigned int i;
1005
0
    for (i = 0; i < KYBER_N / 4; i++) {
1006
0
        basemul(&r->coeffs[4 * i], &a->coeffs[4 * i], &b->coeffs[4 * i], zetas[64 + i]);
1007
0
        basemul(&r->coeffs[4 * i + 2], &a->coeffs[4 * i + 2], &b->coeffs[4 * i + 2], -zetas[64 + i]);
1008
0
    }
1009
0
}
1010
1011
/*************************************************
1012
* Name:        poly_tomont
1013
*
1014
* Description: Inplace conversion of all coefficients of a polynomial
1015
*              from normal domain to Montgomery domain
1016
*
1017
* Arguments:   - poly *r: pointer to input/output polynomial
1018
**************************************************/
1019
static void
1020
poly_tomont(poly *r)
1021
0
{
1022
0
    unsigned int i;
1023
0
    const int16_t f = (1ULL << 32) % KYBER_Q;
1024
0
    for (i = 0; i < KYBER_N; i++)
1025
0
        r->coeffs[i] = montgomery_reduce((int32_t)r->coeffs[i] * f);
1026
0
}
1027
1028
/*************************************************
1029
* Name:        poly_reduce
1030
*
1031
* Description: Applies Barrett reduction to all coefficients of a polynomial
1032
*              for details of the Barrett reduction see comments in reduce.c
1033
*
1034
* Arguments:   - poly *r: pointer to input/output polynomial
1035
**************************************************/
1036
static void
1037
poly_reduce(poly *r)
1038
0
{
1039
0
    unsigned int i;
1040
0
    for (i = 0; i < KYBER_N; i++)
1041
0
        r->coeffs[i] = barrett_reduce(r->coeffs[i]);
1042
0
}
1043
1044
/*************************************************
1045
* Name:        poly_add
1046
*
1047
* Description: Add two polynomials; no modular reduction is performed
1048
*
1049
* Arguments: - poly *r: pointer to output polynomial
1050
*            - const poly *a: pointer to first input polynomial
1051
*            - const poly *b: pointer to second input polynomial
1052
**************************************************/
1053
static void
1054
poly_add(poly *r, const poly *a, const poly *b)
1055
0
{
1056
0
    unsigned int i;
1057
0
    for (i = 0; i < KYBER_N; i++)
1058
0
        r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
1059
0
}
1060
1061
/*************************************************
1062
* Name:        poly_sub
1063
*
1064
* Description: Subtract two polynomials; no modular reduction is performed
1065
*
1066
* Arguments: - poly *r:       pointer to output polynomial
1067
*            - const poly *a: pointer to first input polynomial
1068
*            - const poly *b: pointer to second input polynomial
1069
**************************************************/
1070
static void
1071
poly_sub(poly *r, const poly *a, const poly *b)
1072
0
{
1073
0
    unsigned int i;
1074
0
    for (i = 0; i < KYBER_N; i++)
1075
0
        r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
1076
0
}
1077
/** end: ref/poly.c **/
1078
1079
/** begin: ref/polyvec.c **/
1080
/*************************************************
1081
* Name:        polyvec_compress
1082
*
1083
* Description: Compress and serialize vector of polynomials
1084
*
1085
* Arguments:   - uint8_t *r: pointer to output byte array
1086
*                            (needs space for KYBER_POLYVECCOMPRESSEDBYTES)
1087
*              - const polyvec *a: pointer to input vector of polynomials
1088
**************************************************/
1089
static void
1090
polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a)
1091
0
{
1092
0
    unsigned int i, j, k;
1093
0
    uint64_t d0;
1094
1095
#if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 352))
1096
    uint16_t t[8];
1097
    for (i = 0; i < KYBER_K; i++) {
1098
        for (j = 0; j < KYBER_N / 8; j++) {
1099
            for (k = 0; k < 8; k++) {
1100
                t[k] = a->vec[i].coeffs[8 * j + k];
1101
                t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
1102
                /*      t[k]  = ((((uint32_t)t[k] << 11) + KYBER_Q/2)/KYBER_Q) & 0x7ff; */
1103
                d0 = t[k];
1104
                d0 <<= 11;
1105
                d0 += 1664;
1106
                d0 *= 645084;
1107
                d0 >>= 31;
1108
                t[k] = d0 & 0x7ff;
1109
            }
1110
1111
            r[0] = (t[0] >> 0);
1112
            r[1] = (t[0] >> 8) | (t[1] << 3);
1113
            r[2] = (t[1] >> 5) | (t[2] << 6);
1114
            r[3] = (t[2] >> 2);
1115
            r[4] = (t[2] >> 10) | (t[3] << 1);
1116
            r[5] = (t[3] >> 7) | (t[4] << 4);
1117
            r[6] = (t[4] >> 4) | (t[5] << 7);
1118
            r[7] = (t[5] >> 1);
1119
            r[8] = (t[5] >> 9) | (t[6] << 2);
1120
            r[9] = (t[6] >> 6) | (t[7] << 5);
1121
            r[10] = (t[7] >> 3);
1122
            r += 11;
1123
        }
1124
    }
1125
#elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 320))
1126
    uint16_t t[4];
1127
0
    for (i = 0; i < KYBER_K; i++) {
1128
0
        for (j = 0; j < KYBER_N / 4; j++) {
1129
0
            for (k = 0; k < 4; k++) {
1130
0
                t[k] = a->vec[i].coeffs[4 * j + k];
1131
0
                t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
1132
                /*      t[k]  = ((((uint32_t)t[k] << 10) + KYBER_Q/2)/ KYBER_Q) & 0x3ff; */
1133
0
                d0 = t[k];
1134
0
                d0 <<= 10;
1135
0
                d0 += 1665;
1136
0
                d0 *= 1290167;
1137
0
                d0 >>= 32;
1138
0
                t[k] = d0 & 0x3ff;
1139
0
            }
1140
1141
0
            r[0] = (t[0] >> 0);
1142
0
            r[1] = (t[0] >> 8) | (t[1] << 2);
1143
0
            r[2] = (t[1] >> 6) | (t[2] << 4);
1144
0
            r[3] = (t[2] >> 4) | (t[3] << 6);
1145
0
            r[4] = (t[3] >> 2);
1146
0
            r += 5;
1147
0
        }
1148
0
    }
1149
#else
1150
#error "KYBER_POLYVECCOMPRESSEDBYTES needs to be in {320*KYBER_K, 352*KYBER_K}"
1151
#endif
1152
0
}
1153
1154
/*************************************************
1155
* Name:        polyvec_decompress
1156
*
1157
* Description: De-serialize and decompress vector of polynomials;
1158
*              approximate inverse of polyvec_compress
1159
*
1160
* Arguments:   - polyvec *r:       pointer to output vector of polynomials
1161
*              - const uint8_t *a: pointer to input byte array
1162
*                                  (of length KYBER_POLYVECCOMPRESSEDBYTES)
1163
**************************************************/
1164
static void
1165
polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES])
1166
0
{
1167
0
    unsigned int i, j, k;
1168
1169
#if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 352))
1170
    uint16_t t[8];
1171
    for (i = 0; i < KYBER_K; i++) {
1172
        for (j = 0; j < KYBER_N / 8; j++) {
1173
            t[0] = (a[0] >> 0) | ((uint16_t)a[1] << 8);
1174
            t[1] = (a[1] >> 3) | ((uint16_t)a[2] << 5);
1175
            t[2] = (a[2] >> 6) | ((uint16_t)a[3] << 2) | ((uint16_t)a[4] << 10);
1176
            t[3] = (a[4] >> 1) | ((uint16_t)a[5] << 7);
1177
            t[4] = (a[5] >> 4) | ((uint16_t)a[6] << 4);
1178
            t[5] = (a[6] >> 7) | ((uint16_t)a[7] << 1) | ((uint16_t)a[8] << 9);
1179
            t[6] = (a[8] >> 2) | ((uint16_t)a[9] << 6);
1180
            t[7] = (a[9] >> 5) | ((uint16_t)a[10] << 3);
1181
            a += 11;
1182
1183
            for (k = 0; k < 8; k++)
1184
                r->vec[i].coeffs[8 * j + k] = ((uint32_t)(t[k] & 0x7FF) * KYBER_Q + 1024) >> 11;
1185
        }
1186
    }
1187
#elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_K * 320))
1188
    uint16_t t[4];
1189
0
    for (i = 0; i < KYBER_K; i++) {
1190
0
        for (j = 0; j < KYBER_N / 4; j++) {
1191
0
            t[0] = (a[0] >> 0) | ((uint16_t)a[1] << 8);
1192
0
            t[1] = (a[1] >> 2) | ((uint16_t)a[2] << 6);
1193
0
            t[2] = (a[2] >> 4) | ((uint16_t)a[3] << 4);
1194
0
            t[3] = (a[3] >> 6) | ((uint16_t)a[4] << 2);
1195
0
            a += 5;
1196
1197
0
            for (k = 0; k < 4; k++)
1198
0
                r->vec[i].coeffs[4 * j + k] = ((uint32_t)(t[k] & 0x3FF) * KYBER_Q + 512) >> 10;
1199
0
        }
1200
0
    }
1201
#else
1202
#error "KYBER_POLYVECCOMPRESSEDBYTES needs to be in {320*KYBER_K, 352*KYBER_K}"
1203
#endif
1204
0
}
1205
1206
/*************************************************
1207
* Name:        polyvec_tobytes
1208
*
1209
* Description: Serialize vector of polynomials
1210
*
1211
* Arguments:   - uint8_t *r: pointer to output byte array
1212
*                            (needs space for KYBER_POLYVECBYTES)
1213
*              - const polyvec *a: pointer to input vector of polynomials
1214
**************************************************/
1215
static void
1216
polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a)
1217
0
{
1218
0
    unsigned int i;
1219
0
    for (i = 0; i < KYBER_K; i++)
1220
0
        poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
1221
0
}
1222
1223
/*************************************************
1224
* Name:        polyvec_frombytes
1225
*
1226
* Description: De-serialize vector of polynomials;
1227
*              inverse of polyvec_tobytes
1228
*
1229
* Arguments:   - uint8_t *r:       pointer to output byte array
1230
*              - const polyvec *a: pointer to input vector of polynomials
1231
*                                  (of length KYBER_POLYVECBYTES)
1232
**************************************************/
1233
static void
1234
polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES])
1235
0
{
1236
0
    unsigned int i;
1237
0
    for (i = 0; i < KYBER_K; i++)
1238
0
        poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
1239
0
}
1240
1241
/*************************************************
1242
* Name:        polyvec_ntt
1243
*
1244
* Description: Apply forward NTT to all elements of a vector of polynomials
1245
*
1246
* Arguments:   - polyvec *r: pointer to in/output vector of polynomials
1247
**************************************************/
1248
static void
1249
polyvec_ntt(polyvec *r)
1250
0
{
1251
0
    unsigned int i;
1252
0
    for (i = 0; i < KYBER_K; i++)
1253
0
        poly_ntt(&r->vec[i]);
1254
0
}
1255
1256
/*************************************************
1257
* Name:        polyvec_invntt_tomont
1258
*
1259
* Description: Apply inverse NTT to all elements of a vector of polynomials
1260
*              and multiply by Montgomery factor 2^16
1261
*
1262
* Arguments:   - polyvec *r: pointer to in/output vector of polynomials
1263
**************************************************/
1264
static void
1265
polyvec_invntt_tomont(polyvec *r)
1266
0
{
1267
0
    unsigned int i;
1268
0
    for (i = 0; i < KYBER_K; i++)
1269
0
        poly_invntt_tomont(&r->vec[i]);
1270
0
}
1271
1272
/*************************************************
1273
* Name:        polyvec_basemul_acc_montgomery
1274
*
1275
* Description: Multiply elements of a and b in NTT domain, accumulate into r,
1276
*              and multiply by 2^-16.
1277
*
1278
* Arguments: - poly *r: pointer to output polynomial
1279
*            - const polyvec *a: pointer to first input vector of polynomials
1280
*            - const polyvec *b: pointer to second input vector of polynomials
1281
**************************************************/
1282
static void
1283
polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b)
1284
0
{
1285
0
    unsigned int i;
1286
0
    poly t;
1287
1288
0
    poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]);
1289
0
    for (i = 1; i < KYBER_K; i++) {
1290
0
        poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]);
1291
0
        poly_add(r, r, &t);
1292
0
    }
1293
1294
0
    poly_reduce(r);
1295
0
}
1296
1297
/*************************************************
1298
* Name:        polyvec_reduce
1299
*
1300
* Description: Applies Barrett reduction to each coefficient
1301
*              of each element of a vector of polynomials;
1302
*              for details of the Barrett reduction see comments in reduce.c
1303
*
1304
* Arguments:   - polyvec *r: pointer to input/output polynomial
1305
**************************************************/
1306
static void
1307
polyvec_reduce(polyvec *r)
1308
0
{
1309
0
    unsigned int i;
1310
0
    for (i = 0; i < KYBER_K; i++)
1311
0
        poly_reduce(&r->vec[i]);
1312
0
}
1313
1314
/*************************************************
1315
* Name:        polyvec_add
1316
*
1317
* Description: Add vectors of polynomials
1318
*
1319
* Arguments: - polyvec *r: pointer to output vector of polynomials
1320
*            - const polyvec *a: pointer to first input vector of polynomials
1321
*            - const polyvec *b: pointer to second input vector of polynomials
1322
**************************************************/
1323
static void
1324
polyvec_add(polyvec *r, const polyvec *a, const polyvec *b)
1325
0
{
1326
0
    unsigned int i;
1327
0
    for (i = 0; i < KYBER_K; i++)
1328
0
        poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
1329
0
}
1330
/** end: ref/polyvec.c **/
1331
1332
/** begin: ref/indcpa.c **/
1333
/*************************************************
1334
* Name:        pack_pk
1335
*
1336
* Description: Serialize the public key as concatenation of the
1337
*              serialized vector of polynomials pk
1338
*              and the public seed used to generate the matrix A.
1339
*
1340
* Arguments:   uint8_t *r: pointer to the output serialized public key
1341
*              polyvec *pk: pointer to the input public-key polyvec
1342
*              const uint8_t *seed: pointer to the input public seed
1343
**************************************************/
1344
static void
1345
pack_pk(uint8_t r[KYBER_INDCPA_PUBLICKEYBYTES],
1346
        polyvec *pk,
1347
        const uint8_t seed[KYBER_SYMBYTES])
1348
0
{
1349
0
    size_t i;
1350
0
    polyvec_tobytes(r, pk);
1351
0
    for (i = 0; i < KYBER_SYMBYTES; i++)
1352
0
        r[i + KYBER_POLYVECBYTES] = seed[i];
1353
0
}
1354
1355
/*************************************************
1356
* Name:        unpack_pk
1357
*
1358
* Description: De-serialize public key from a byte array;
1359
*              approximate inverse of pack_pk
1360
*
1361
* Arguments:   - polyvec *pk: pointer to output public-key polynomial vector
1362
*              - uint8_t *seed: pointer to output seed to generate matrix A
1363
*              - const uint8_t *packedpk: pointer to input serialized public key
1364
**************************************************/
1365
static void
1366
unpack_pk(polyvec *pk,
1367
          uint8_t seed[KYBER_SYMBYTES],
1368
          const uint8_t packedpk[KYBER_INDCPA_PUBLICKEYBYTES])
1369
0
{
1370
0
    size_t i;
1371
0
    polyvec_frombytes(pk, packedpk);
1372
0
    for (i = 0; i < KYBER_SYMBYTES; i++)
1373
0
        seed[i] = packedpk[i + KYBER_POLYVECBYTES];
1374
0
}
1375
1376
/*************************************************
1377
* Name:        pack_sk
1378
*
1379
* Description: Serialize the secret key
1380
*
1381
* Arguments:   - uint8_t *r: pointer to output serialized secret key
1382
*              - polyvec *sk: pointer to input vector of polynomials (secret key)
1383
**************************************************/
1384
static void
1385
pack_sk(uint8_t r[KYBER_INDCPA_SECRETKEYBYTES], polyvec *sk)
1386
0
{
1387
0
    polyvec_tobytes(r, sk);
1388
0
}
1389
1390
/*************************************************
1391
* Name:        unpack_sk
1392
*
1393
* Description: De-serialize the secret key; inverse of pack_sk
1394
*
1395
* Arguments:   - polyvec *sk: pointer to output vector of polynomials (secret key)
1396
*              - const uint8_t *packedsk: pointer to input serialized secret key
1397
**************************************************/
1398
static void
1399
unpack_sk(polyvec *sk, const uint8_t packedsk[KYBER_INDCPA_SECRETKEYBYTES])
1400
0
{
1401
0
    polyvec_frombytes(sk, packedsk);
1402
0
}
1403
1404
/*************************************************
1405
* Name:        pack_ciphertext
1406
*
1407
* Description: Serialize the ciphertext as concatenation of the
1408
*              compressed and serialized vector of polynomials b
1409
*              and the compressed and serialized polynomial v
1410
*
1411
* Arguments:   uint8_t *r: pointer to the output serialized ciphertext
1412
*              poly *pk: pointer to the input vector of polynomials b
1413
*              poly *v: pointer to the input polynomial v
1414
**************************************************/
1415
static void
1416
pack_ciphertext(uint8_t r[KYBER_INDCPA_BYTES], polyvec *b, poly *v)
1417
0
{
1418
0
    polyvec_compress(r, b);
1419
0
    poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v);
1420
0
}
1421
1422
/*************************************************
1423
* Name:        unpack_ciphertext
1424
*
1425
* Description: De-serialize and decompress ciphertext from a byte array;
1426
*              approximate inverse of pack_ciphertext
1427
*
1428
* Arguments:   - polyvec *b: pointer to the output vector of polynomials b
1429
*              - poly *v: pointer to the output polynomial v
1430
*              - const uint8_t *c: pointer to the input serialized ciphertext
1431
**************************************************/
1432
static void
1433
unpack_ciphertext(polyvec *b, poly *v, const uint8_t c[KYBER_INDCPA_BYTES])
1434
0
{
1435
0
    polyvec_decompress(b, c);
1436
0
    poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES);
1437
0
}
1438
1439
/*************************************************
1440
* Name:        rej_uniform
1441
*
1442
* Description: Run rejection sampling on uniform random bytes to generate
1443
*              uniform random integers mod q
1444
*
1445
* Arguments:   - int16_t *r: pointer to output buffer
1446
*              - unsigned int len: requested number of 16-bit integers (uniform mod q)
1447
*              - const uint8_t *buf: pointer to input buffer (assumed to be uniformly random bytes)
1448
*              - unsigned int buflen: length of input buffer in bytes
1449
*
1450
* Returns number of sampled 16-bit integers (at most len)
1451
**************************************************/
1452
static unsigned int
1453
rej_uniform(int16_t *r,
1454
            unsigned int len,
1455
            const uint8_t *buf,
1456
            unsigned int buflen)
1457
0
{
1458
0
    unsigned int ctr, pos;
1459
0
    uint16_t val0, val1;
1460
1461
0
    ctr = pos = 0;
1462
0
    while (ctr < len && pos + 3 <= buflen) {
1463
0
        val0 = ((buf[pos + 0] >> 0) | ((uint16_t)buf[pos + 1] << 8)) & 0xFFF;
1464
0
        val1 = ((buf[pos + 1] >> 4) | ((uint16_t)buf[pos + 2] << 4)) & 0xFFF;
1465
0
        pos += 3;
1466
1467
0
        if (val0 < KYBER_Q)
1468
0
            r[ctr++] = val0;
1469
0
        if (ctr < len && val1 < KYBER_Q)
1470
0
            r[ctr++] = val1;
1471
0
    }
1472
1473
0
    return ctr;
1474
0
}
1475
1476
0
#define gen_a(A, B) gen_matrix(A, B, 0)
1477
0
#define gen_at(A, B) gen_matrix(A, B, 1)
1478
1479
/*************************************************
1480
* Name:        gen_matrix
1481
*
1482
* Description: Deterministically generate matrix A (or the transpose of A)
1483
*              from a seed. Entries of the matrix are polynomials that look
1484
*              uniformly random. Performs rejection sampling on output of
1485
*              a XOF
1486
*
1487
* Arguments:   - polyvec *a: pointer to ouptput matrix A
1488
*              - const uint8_t *seed: pointer to input seed
1489
*              - int transposed: boolean deciding whether A or A^T is generated
1490
**************************************************/
1491
0
#define GEN_MATRIX_NBLOCKS ((12 * KYBER_N / 8 * (1 << 12) / KYBER_Q + XOF_BLOCKBYTES) / XOF_BLOCKBYTES)
1492
// Not static for benchmarking
1493
static void
1494
gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed)
1495
0
{
1496
0
    unsigned int ctr, i, j, k;
1497
0
    unsigned int buflen, off;
1498
0
    uint8_t buf[GEN_MATRIX_NBLOCKS * XOF_BLOCKBYTES + 2];
1499
0
    xof_state state;
1500
1501
0
    for (i = 0; i < KYBER_K; i++) {
1502
0
        for (j = 0; j < KYBER_K; j++) {
1503
0
            if (transposed)
1504
0
                xof_absorb(&state, seed, i, j);
1505
0
            else
1506
0
                xof_absorb(&state, seed, j, i);
1507
1508
0
            xof_squeezeblocks(buf, GEN_MATRIX_NBLOCKS, &state);
1509
0
            buflen = GEN_MATRIX_NBLOCKS * XOF_BLOCKBYTES;
1510
0
            ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, buflen);
1511
1512
0
            while (ctr < KYBER_N) {
1513
0
                off = buflen % 3;
1514
0
                for (k = 0; k < off; k++)
1515
0
                    buf[k] = buf[buflen - off + k];
1516
0
                xof_squeezeblocks(buf + off, 1, &state);
1517
0
                buflen = off + XOF_BLOCKBYTES;
1518
0
                ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, buflen);
1519
0
            }
1520
0
        }
1521
0
    }
1522
0
}
1523
1524
/*************************************************
1525
* Name:        indcpa_keypair_derand
1526
*
1527
* Description: Generates public and private key for the CPA-secure
1528
*              public-key encryption scheme underlying Kyber
1529
*
1530
* Arguments:   - uint8_t *pk: pointer to output public key
1531
*                             (of length KYBER_INDCPA_PUBLICKEYBYTES bytes)
1532
*              - uint8_t *sk: pointer to output private key
1533
*                             (of length KYBER_INDCPA_SECRETKEYBYTES bytes)
1534
*              - const uint8_t *coins: pointer to input randomness
1535
*                             (of length KYBER_SYMBYTES bytes)
1536
**************************************************/
1537
static void
1538
indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
1539
                      uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES],
1540
                      const uint8_t coins[KYBER_SYMBYTES])
1541
0
{
1542
0
    unsigned int i;
1543
0
    uint8_t buf[2 * KYBER_SYMBYTES];
1544
0
    const uint8_t *publicseed = buf;
1545
0
    const uint8_t *noiseseed = buf + KYBER_SYMBYTES;
1546
0
    uint8_t nonce = 0;
1547
0
    polyvec a[KYBER_K], e, pkpv, skpv;
1548
1549
0
    hash_g(buf, coins, KYBER_SYMBYTES);
1550
1551
0
    gen_a(a, publicseed);
1552
1553
0
    for (i = 0; i < KYBER_K; i++)
1554
0
        poly_getnoise_eta1(&skpv.vec[i], noiseseed, nonce++);
1555
0
    for (i = 0; i < KYBER_K; i++)
1556
0
        poly_getnoise_eta1(&e.vec[i], noiseseed, nonce++);
1557
1558
0
    polyvec_ntt(&skpv);
1559
0
    polyvec_ntt(&e);
1560
1561
    // matrix-vector multiplication
1562
0
    for (i = 0; i < KYBER_K; i++) {
1563
0
        polyvec_basemul_acc_montgomery(&pkpv.vec[i], &a[i], &skpv);
1564
0
        poly_tomont(&pkpv.vec[i]);
1565
0
    }
1566
1567
0
    polyvec_add(&pkpv, &pkpv, &e);
1568
0
    polyvec_reduce(&pkpv);
1569
1570
0
    pack_sk(sk, &skpv);
1571
0
    pack_pk(pk, &pkpv, publicseed);
1572
0
}
1573
1574
/*************************************************
1575
* Name:        indcpa_enc
1576
*
1577
* Description: Encryption function of the CPA-secure
1578
*              public-key encryption scheme underlying Kyber.
1579
*
1580
* Arguments:   - uint8_t *c: pointer to output ciphertext
1581
*                            (of length KYBER_INDCPA_BYTES bytes)
1582
*              - const uint8_t *m: pointer to input message
1583
*                                  (of length KYBER_INDCPA_MSGBYTES bytes)
1584
*              - const uint8_t *pk: pointer to input public key
1585
*                                   (of length KYBER_INDCPA_PUBLICKEYBYTES)
1586
*              - const uint8_t *coins: pointer to input random coins used as seed
1587
*                                      (of length KYBER_SYMBYTES) to deterministically
1588
*                                      generate all randomness
1589
**************************************************/
1590
static void
1591
indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES],
1592
           const uint8_t m[KYBER_INDCPA_MSGBYTES],
1593
           const uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES],
1594
           const uint8_t coins[KYBER_SYMBYTES])
1595
0
{
1596
0
    unsigned int i;
1597
0
    uint8_t seed[KYBER_SYMBYTES];
1598
0
    uint8_t nonce = 0;
1599
0
    polyvec sp, pkpv, ep, at[KYBER_K], b;
1600
0
    poly v, k, epp;
1601
1602
0
    unpack_pk(&pkpv, seed, pk);
1603
0
    poly_frommsg(&k, m);
1604
0
    gen_at(at, seed);
1605
1606
0
    for (i = 0; i < KYBER_K; i++)
1607
0
        poly_getnoise_eta1(sp.vec + i, coins, nonce++);
1608
0
    for (i = 0; i < KYBER_K; i++)
1609
0
        poly_getnoise_eta2(ep.vec + i, coins, nonce++);
1610
0
    poly_getnoise_eta2(&epp, coins, nonce++);
1611
1612
0
    polyvec_ntt(&sp);
1613
1614
    // matrix-vector multiplication
1615
0
    for (i = 0; i < KYBER_K; i++)
1616
0
        polyvec_basemul_acc_montgomery(&b.vec[i], &at[i], &sp);
1617
1618
0
    polyvec_basemul_acc_montgomery(&v, &pkpv, &sp);
1619
1620
0
    polyvec_invntt_tomont(&b);
1621
0
    poly_invntt_tomont(&v);
1622
1623
0
    polyvec_add(&b, &b, &ep);
1624
0
    poly_add(&v, &v, &epp);
1625
0
    poly_add(&v, &v, &k);
1626
0
    polyvec_reduce(&b);
1627
0
    poly_reduce(&v);
1628
1629
0
    pack_ciphertext(c, &b, &v);
1630
0
}
1631
1632
/*************************************************
1633
* Name:        indcpa_dec
1634
*
1635
* Description: Decryption function of the CPA-secure
1636
*              public-key encryption scheme underlying Kyber.
1637
*
1638
* Arguments:   - uint8_t *m: pointer to output decrypted message
1639
*                            (of length KYBER_INDCPA_MSGBYTES)
1640
*              - const uint8_t *c: pointer to input ciphertext
1641
*                                  (of length KYBER_INDCPA_BYTES)
1642
*              - const uint8_t *sk: pointer to input secret key
1643
*                                   (of length KYBER_INDCPA_SECRETKEYBYTES)
1644
**************************************************/
1645
static void
1646
indcpa_dec(uint8_t m[KYBER_INDCPA_MSGBYTES],
1647
           const uint8_t c[KYBER_INDCPA_BYTES],
1648
           const uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES])
1649
0
{
1650
0
    polyvec b, skpv;
1651
0
    poly v, mp;
1652
1653
0
    unpack_ciphertext(&b, &v, c);
1654
0
    unpack_sk(&skpv, sk);
1655
1656
0
    polyvec_ntt(&b);
1657
0
    polyvec_basemul_acc_montgomery(&mp, &skpv, &b);
1658
0
    poly_invntt_tomont(&mp);
1659
1660
0
    poly_sub(&mp, &v, &mp);
1661
0
    poly_reduce(&mp);
1662
1663
0
    poly_tomsg(m, &mp);
1664
0
}
1665
/** end: ref/indcpa.c **/
1666
1667
/** begin: ref/fips202.c **/
1668
/* Based on the public domain implementation in crypto_hash/keccakc512/simple/ from
1669
 * http://bench.cr.yp.to/supercop.html by Ronny Van Keer and the public domain "TweetFips202"
1670
 * implementation from https://twitter.com/tweetfips202 by Gilles Van Assche, Daniel J. Bernstein,
1671
 * and Peter Schwabe */
1672
1673
0
#define NROUNDS 24
1674
0
#define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset)))
1675
1676
/*************************************************
1677
* Name:        load64
1678
*
1679
* Description: Load 8 bytes into uint64_t in little-endian order
1680
*
1681
* Arguments:   - const uint8_t *x: pointer to input byte array
1682
*
1683
* Returns the loaded 64-bit unsigned integer
1684
**************************************************/
1685
static uint64_t
1686
load64(const uint8_t x[8])
1687
0
{
1688
0
    unsigned int i;
1689
0
    uint64_t r = 0;
1690
1691
0
    for (i = 0; i < 8; i++)
1692
0
        r |= (uint64_t)x[i] << 8 * i;
1693
1694
0
    return r;
1695
0
}
1696
1697
/*************************************************
1698
* Name:        store64
1699
*
1700
* Description: Store a 64-bit integer to array of 8 bytes in little-endian order
1701
*
1702
* Arguments:   - uint8_t *x: pointer to the output byte array (allocated)
1703
*              - uint64_t u: input 64-bit unsigned integer
1704
**************************************************/
1705
static void
1706
store64(uint8_t x[8], uint64_t u)
1707
0
{
1708
0
    unsigned int i;
1709
1710
0
    for (i = 0; i < 8; i++)
1711
0
        x[i] = u >> 8 * i;
1712
0
}
1713
1714
/* Keccak round constants */
1715
static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
1716
    (uint64_t)0x0000000000000001ULL,
1717
    (uint64_t)0x0000000000008082ULL,
1718
    (uint64_t)0x800000000000808aULL,
1719
    (uint64_t)0x8000000080008000ULL,
1720
    (uint64_t)0x000000000000808bULL,
1721
    (uint64_t)0x0000000080000001ULL,
1722
    (uint64_t)0x8000000080008081ULL,
1723
    (uint64_t)0x8000000000008009ULL,
1724
    (uint64_t)0x000000000000008aULL,
1725
    (uint64_t)0x0000000000000088ULL,
1726
    (uint64_t)0x0000000080008009ULL,
1727
    (uint64_t)0x000000008000000aULL,
1728
    (uint64_t)0x000000008000808bULL,
1729
    (uint64_t)0x800000000000008bULL,
1730
    (uint64_t)0x8000000000008089ULL,
1731
    (uint64_t)0x8000000000008003ULL,
1732
    (uint64_t)0x8000000000008002ULL,
1733
    (uint64_t)0x8000000000000080ULL,
1734
    (uint64_t)0x000000000000800aULL,
1735
    (uint64_t)0x800000008000000aULL,
1736
    (uint64_t)0x8000000080008081ULL,
1737
    (uint64_t)0x8000000000008080ULL,
1738
    (uint64_t)0x0000000080000001ULL,
1739
    (uint64_t)0x8000000080008008ULL
1740
};
1741
1742
/*************************************************
1743
* Name:        KeccakF1600_StatePermute
1744
*
1745
* Description: The Keccak F1600 Permutation
1746
*
1747
* Arguments:   - uint64_t *state: pointer to input/output Keccak state
1748
**************************************************/
1749
static void
1750
KeccakF1600_StatePermute(uint64_t state[25])
1751
0
{
1752
0
    int round;
1753
1754
0
    uint64_t Aba, Abe, Abi, Abo, Abu;
1755
0
    uint64_t Aga, Age, Agi, Ago, Agu;
1756
0
    uint64_t Aka, Ake, Aki, Ako, Aku;
1757
0
    uint64_t Ama, Ame, Ami, Amo, Amu;
1758
0
    uint64_t Asa, Ase, Asi, Aso, Asu;
1759
0
    uint64_t BCa, BCe, BCi, BCo, BCu;
1760
0
    uint64_t Da, De, Di, Do, Du;
1761
0
    uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
1762
0
    uint64_t Ega, Ege, Egi, Ego, Egu;
1763
0
    uint64_t Eka, Eke, Eki, Eko, Eku;
1764
0
    uint64_t Ema, Eme, Emi, Emo, Emu;
1765
0
    uint64_t Esa, Ese, Esi, Eso, Esu;
1766
1767
    //copyFromState(A, state)
1768
0
    Aba = state[0];
1769
0
    Abe = state[1];
1770
0
    Abi = state[2];
1771
0
    Abo = state[3];
1772
0
    Abu = state[4];
1773
0
    Aga = state[5];
1774
0
    Age = state[6];
1775
0
    Agi = state[7];
1776
0
    Ago = state[8];
1777
0
    Agu = state[9];
1778
0
    Aka = state[10];
1779
0
    Ake = state[11];
1780
0
    Aki = state[12];
1781
0
    Ako = state[13];
1782
0
    Aku = state[14];
1783
0
    Ama = state[15];
1784
0
    Ame = state[16];
1785
0
    Ami = state[17];
1786
0
    Amo = state[18];
1787
0
    Amu = state[19];
1788
0
    Asa = state[20];
1789
0
    Ase = state[21];
1790
0
    Asi = state[22];
1791
0
    Aso = state[23];
1792
0
    Asu = state[24];
1793
1794
0
    for (round = 0; round < NROUNDS; round += 2) {
1795
        //    prepareTheta
1796
0
        BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
1797
0
        BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
1798
0
        BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
1799
0
        BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
1800
0
        BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
1801
1802
        //thetaRhoPiChiIotaPrepareTheta(round, A, E)
1803
0
        Da = BCu ^ ROL(BCe, 1);
1804
0
        De = BCa ^ ROL(BCi, 1);
1805
0
        Di = BCe ^ ROL(BCo, 1);
1806
0
        Do = BCi ^ ROL(BCu, 1);
1807
0
        Du = BCo ^ ROL(BCa, 1);
1808
1809
0
        Aba ^= Da;
1810
0
        BCa = Aba;
1811
0
        Age ^= De;
1812
0
        BCe = ROL(Age, 44);
1813
0
        Aki ^= Di;
1814
0
        BCi = ROL(Aki, 43);
1815
0
        Amo ^= Do;
1816
0
        BCo = ROL(Amo, 21);
1817
0
        Asu ^= Du;
1818
0
        BCu = ROL(Asu, 14);
1819
0
        Eba = BCa ^ ((~BCe) & BCi);
1820
0
        Eba ^= (uint64_t)KeccakF_RoundConstants[round];
1821
0
        Ebe = BCe ^ ((~BCi) & BCo);
1822
0
        Ebi = BCi ^ ((~BCo) & BCu);
1823
0
        Ebo = BCo ^ ((~BCu) & BCa);
1824
0
        Ebu = BCu ^ ((~BCa) & BCe);
1825
1826
0
        Abo ^= Do;
1827
0
        BCa = ROL(Abo, 28);
1828
0
        Agu ^= Du;
1829
0
        BCe = ROL(Agu, 20);
1830
0
        Aka ^= Da;
1831
0
        BCi = ROL(Aka, 3);
1832
0
        Ame ^= De;
1833
0
        BCo = ROL(Ame, 45);
1834
0
        Asi ^= Di;
1835
0
        BCu = ROL(Asi, 61);
1836
0
        Ega = BCa ^ ((~BCe) & BCi);
1837
0
        Ege = BCe ^ ((~BCi) & BCo);
1838
0
        Egi = BCi ^ ((~BCo) & BCu);
1839
0
        Ego = BCo ^ ((~BCu) & BCa);
1840
0
        Egu = BCu ^ ((~BCa) & BCe);
1841
1842
0
        Abe ^= De;
1843
0
        BCa = ROL(Abe, 1);
1844
0
        Agi ^= Di;
1845
0
        BCe = ROL(Agi, 6);
1846
0
        Ako ^= Do;
1847
0
        BCi = ROL(Ako, 25);
1848
0
        Amu ^= Du;
1849
0
        BCo = ROL(Amu, 8);
1850
0
        Asa ^= Da;
1851
0
        BCu = ROL(Asa, 18);
1852
0
        Eka = BCa ^ ((~BCe) & BCi);
1853
0
        Eke = BCe ^ ((~BCi) & BCo);
1854
0
        Eki = BCi ^ ((~BCo) & BCu);
1855
0
        Eko = BCo ^ ((~BCu) & BCa);
1856
0
        Eku = BCu ^ ((~BCa) & BCe);
1857
1858
0
        Abu ^= Du;
1859
0
        BCa = ROL(Abu, 27);
1860
0
        Aga ^= Da;
1861
0
        BCe = ROL(Aga, 36);
1862
0
        Ake ^= De;
1863
0
        BCi = ROL(Ake, 10);
1864
0
        Ami ^= Di;
1865
0
        BCo = ROL(Ami, 15);
1866
0
        Aso ^= Do;
1867
0
        BCu = ROL(Aso, 56);
1868
0
        Ema = BCa ^ ((~BCe) & BCi);
1869
0
        Eme = BCe ^ ((~BCi) & BCo);
1870
0
        Emi = BCi ^ ((~BCo) & BCu);
1871
0
        Emo = BCo ^ ((~BCu) & BCa);
1872
0
        Emu = BCu ^ ((~BCa) & BCe);
1873
1874
0
        Abi ^= Di;
1875
0
        BCa = ROL(Abi, 62);
1876
0
        Ago ^= Do;
1877
0
        BCe = ROL(Ago, 55);
1878
0
        Aku ^= Du;
1879
0
        BCi = ROL(Aku, 39);
1880
0
        Ama ^= Da;
1881
0
        BCo = ROL(Ama, 41);
1882
0
        Ase ^= De;
1883
0
        BCu = ROL(Ase, 2);
1884
0
        Esa = BCa ^ ((~BCe) & BCi);
1885
0
        Ese = BCe ^ ((~BCi) & BCo);
1886
0
        Esi = BCi ^ ((~BCo) & BCu);
1887
0
        Eso = BCo ^ ((~BCu) & BCa);
1888
0
        Esu = BCu ^ ((~BCa) & BCe);
1889
1890
        //    prepareTheta
1891
0
        BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
1892
0
        BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
1893
0
        BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
1894
0
        BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
1895
0
        BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
1896
1897
        //thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
1898
0
        Da = BCu ^ ROL(BCe, 1);
1899
0
        De = BCa ^ ROL(BCi, 1);
1900
0
        Di = BCe ^ ROL(BCo, 1);
1901
0
        Do = BCi ^ ROL(BCu, 1);
1902
0
        Du = BCo ^ ROL(BCa, 1);
1903
1904
0
        Eba ^= Da;
1905
0
        BCa = Eba;
1906
0
        Ege ^= De;
1907
0
        BCe = ROL(Ege, 44);
1908
0
        Eki ^= Di;
1909
0
        BCi = ROL(Eki, 43);
1910
0
        Emo ^= Do;
1911
0
        BCo = ROL(Emo, 21);
1912
0
        Esu ^= Du;
1913
0
        BCu = ROL(Esu, 14);
1914
0
        Aba = BCa ^ ((~BCe) & BCi);
1915
0
        Aba ^= (uint64_t)KeccakF_RoundConstants[round + 1];
1916
0
        Abe = BCe ^ ((~BCi) & BCo);
1917
0
        Abi = BCi ^ ((~BCo) & BCu);
1918
0
        Abo = BCo ^ ((~BCu) & BCa);
1919
0
        Abu = BCu ^ ((~BCa) & BCe);
1920
1921
0
        Ebo ^= Do;
1922
0
        BCa = ROL(Ebo, 28);
1923
0
        Egu ^= Du;
1924
0
        BCe = ROL(Egu, 20);
1925
0
        Eka ^= Da;
1926
0
        BCi = ROL(Eka, 3);
1927
0
        Eme ^= De;
1928
0
        BCo = ROL(Eme, 45);
1929
0
        Esi ^= Di;
1930
0
        BCu = ROL(Esi, 61);
1931
0
        Aga = BCa ^ ((~BCe) & BCi);
1932
0
        Age = BCe ^ ((~BCi) & BCo);
1933
0
        Agi = BCi ^ ((~BCo) & BCu);
1934
0
        Ago = BCo ^ ((~BCu) & BCa);
1935
0
        Agu = BCu ^ ((~BCa) & BCe);
1936
1937
0
        Ebe ^= De;
1938
0
        BCa = ROL(Ebe, 1);
1939
0
        Egi ^= Di;
1940
0
        BCe = ROL(Egi, 6);
1941
0
        Eko ^= Do;
1942
0
        BCi = ROL(Eko, 25);
1943
0
        Emu ^= Du;
1944
0
        BCo = ROL(Emu, 8);
1945
0
        Esa ^= Da;
1946
0
        BCu = ROL(Esa, 18);
1947
0
        Aka = BCa ^ ((~BCe) & BCi);
1948
0
        Ake = BCe ^ ((~BCi) & BCo);
1949
0
        Aki = BCi ^ ((~BCo) & BCu);
1950
0
        Ako = BCo ^ ((~BCu) & BCa);
1951
0
        Aku = BCu ^ ((~BCa) & BCe);
1952
1953
0
        Ebu ^= Du;
1954
0
        BCa = ROL(Ebu, 27);
1955
0
        Ega ^= Da;
1956
0
        BCe = ROL(Ega, 36);
1957
0
        Eke ^= De;
1958
0
        BCi = ROL(Eke, 10);
1959
0
        Emi ^= Di;
1960
0
        BCo = ROL(Emi, 15);
1961
0
        Eso ^= Do;
1962
0
        BCu = ROL(Eso, 56);
1963
0
        Ama = BCa ^ ((~BCe) & BCi);
1964
0
        Ame = BCe ^ ((~BCi) & BCo);
1965
0
        Ami = BCi ^ ((~BCo) & BCu);
1966
0
        Amo = BCo ^ ((~BCu) & BCa);
1967
0
        Amu = BCu ^ ((~BCa) & BCe);
1968
1969
0
        Ebi ^= Di;
1970
0
        BCa = ROL(Ebi, 62);
1971
0
        Ego ^= Do;
1972
0
        BCe = ROL(Ego, 55);
1973
0
        Eku ^= Du;
1974
0
        BCi = ROL(Eku, 39);
1975
0
        Ema ^= Da;
1976
0
        BCo = ROL(Ema, 41);
1977
0
        Ese ^= De;
1978
0
        BCu = ROL(Ese, 2);
1979
0
        Asa = BCa ^ ((~BCe) & BCi);
1980
0
        Ase = BCe ^ ((~BCi) & BCo);
1981
0
        Asi = BCi ^ ((~BCo) & BCu);
1982
0
        Aso = BCo ^ ((~BCu) & BCa);
1983
0
        Asu = BCu ^ ((~BCa) & BCe);
1984
0
    }
1985
1986
    //copyToState(state, A)
1987
0
    state[0] = Aba;
1988
0
    state[1] = Abe;
1989
0
    state[2] = Abi;
1990
0
    state[3] = Abo;
1991
0
    state[4] = Abu;
1992
0
    state[5] = Aga;
1993
0
    state[6] = Age;
1994
0
    state[7] = Agi;
1995
0
    state[8] = Ago;
1996
0
    state[9] = Agu;
1997
0
    state[10] = Aka;
1998
0
    state[11] = Ake;
1999
0
    state[12] = Aki;
2000
0
    state[13] = Ako;
2001
0
    state[14] = Aku;
2002
0
    state[15] = Ama;
2003
0
    state[16] = Ame;
2004
0
    state[17] = Ami;
2005
0
    state[18] = Amo;
2006
0
    state[19] = Amu;
2007
0
    state[20] = Asa;
2008
0
    state[21] = Ase;
2009
0
    state[22] = Asi;
2010
0
    state[23] = Aso;
2011
0
    state[24] = Asu;
2012
0
}
2013
2014
/*************************************************
2015
* Name:        keccak_init
2016
*
2017
* Description: Initializes the Keccak state.
2018
*
2019
* Arguments:   - uint64_t *s: pointer to Keccak state
2020
**************************************************/
2021
static void
2022
keccak_init(uint64_t s[25])
2023
0
{
2024
0
    unsigned int i;
2025
0
    for (i = 0; i < 25; i++)
2026
0
        s[i] = 0;
2027
0
}
2028
2029
/*************************************************
2030
* Name:        keccak_absorb
2031
*
2032
* Description: Absorb step of Keccak; incremental.
2033
*
2034
* Arguments:   - uint64_t *s: pointer to Keccak state
2035
*              - unsigned int pos: position in current block to be absorbed
2036
*              - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
2037
*              - const uint8_t *in: pointer to input to be absorbed into s
2038
*              - size_t inlen: length of input in bytes
2039
*
2040
* Returns new position pos in current block
2041
**************************************************/
2042
static unsigned int
2043
keccak_absorb(uint64_t s[25],
2044
              unsigned int pos,
2045
              unsigned int r,
2046
              const uint8_t *in,
2047
              size_t inlen)
2048
0
{
2049
0
    unsigned int i;
2050
2051
0
    while (pos + inlen >= r) {
2052
0
        for (i = pos; i < r; i++)
2053
0
            s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
2054
0
        inlen -= r - pos;
2055
0
        KeccakF1600_StatePermute(s);
2056
0
        pos = 0;
2057
0
    }
2058
2059
0
    for (i = pos; i < pos + inlen; i++)
2060
0
        s[i / 8] ^= (uint64_t)*in++ << 8 * (i % 8);
2061
2062
0
    return i;
2063
0
}
2064
2065
/*************************************************
2066
* Name:        keccak_finalize
2067
*
2068
* Description: Finalize absorb step.
2069
*
2070
* Arguments:   - uint64_t *s: pointer to Keccak state
2071
*              - unsigned int pos: position in current block to be absorbed
2072
*              - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
2073
*              - uint8_t p: domain separation byte
2074
**************************************************/
2075
static void
2076
keccak_finalize(uint64_t s[25], unsigned int pos, unsigned int r, uint8_t p)
2077
0
{
2078
0
    s[pos / 8] ^= (uint64_t)p << 8 * (pos % 8);
2079
0
    s[r / 8 - 1] ^= 1ULL << 63;
2080
0
}
2081
2082
/*************************************************
2083
* Name:        keccak_squeeze
2084
*
2085
* Description: Squeeze step of Keccak. Squeezes arbitratrily many bytes.
2086
*              Modifies the state. Can be called multiple times to keep
2087
*              squeezing, i.e., is incremental.
2088
*
2089
* Arguments:   - uint8_t *out: pointer to output
2090
*              - size_t outlen: number of bytes to be squeezed (written to out)
2091
*              - uint64_t *s: pointer to input/output Keccak state
2092
*              - unsigned int pos: number of bytes in current block already squeezed
2093
*              - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
2094
*
2095
* Returns new position pos in current block
2096
**************************************************/
2097
static unsigned int
2098
keccak_squeeze(uint8_t *out,
2099
               size_t outlen,
2100
               uint64_t s[25],
2101
               unsigned int pos,
2102
               unsigned int r)
2103
0
{
2104
0
    unsigned int i;
2105
2106
0
    while (outlen) {
2107
0
        if (pos == r) {
2108
0
            KeccakF1600_StatePermute(s);
2109
0
            pos = 0;
2110
0
        }
2111
0
        for (i = pos; i < r && i < pos + outlen; i++)
2112
0
            *out++ = s[i / 8] >> 8 * (i % 8);
2113
0
        outlen -= i - pos;
2114
0
        pos = i;
2115
0
    }
2116
2117
0
    return pos;
2118
0
}
2119
2120
/*************************************************
2121
* Name:        keccak_absorb_once
2122
*
2123
* Description: Absorb step of Keccak;
2124
*              non-incremental, starts by zeroeing the state.
2125
*
2126
* Arguments:   - uint64_t *s: pointer to (uninitialized) output Keccak state
2127
*              - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
2128
*              - const uint8_t *in: pointer to input to be absorbed into s
2129
*              - size_t inlen: length of input in bytes
2130
*              - uint8_t p: domain-separation byte for different Keccak-derived functions
2131
**************************************************/
2132
static void
2133
keccak_absorb_once(uint64_t s[25],
2134
                   unsigned int r,
2135
                   const uint8_t *in,
2136
                   size_t inlen,
2137
                   uint8_t p)
2138
0
{
2139
0
    unsigned int i;
2140
2141
0
    for (i = 0; i < 25; i++)
2142
0
        s[i] = 0;
2143
2144
0
    while (inlen >= r) {
2145
0
        for (i = 0; i < r / 8; i++)
2146
0
            s[i] ^= load64(in + 8 * i);
2147
0
        in += r;
2148
0
        inlen -= r;
2149
0
        KeccakF1600_StatePermute(s);
2150
0
    }
2151
2152
0
    for (i = 0; i < inlen; i++)
2153
0
        s[i / 8] ^= (uint64_t)in[i] << 8 * (i % 8);
2154
2155
0
    s[i / 8] ^= (uint64_t)p << 8 * (i % 8);
2156
0
    s[(r - 1) / 8] ^= 1ULL << 63;
2157
0
}
2158
2159
/*************************************************
2160
* Name:        keccak_squeezeblocks
2161
*
2162
* Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
2163
*              Modifies the state. Can be called multiple times to keep
2164
*              squeezing, i.e., is incremental. Assumes zero bytes of current
2165
*              block have already been squeezed.
2166
*
2167
* Arguments:   - uint8_t *out: pointer to output blocks
2168
*              - size_t nblocks: number of blocks to be squeezed (written to out)
2169
*              - uint64_t *s: pointer to input/output Keccak state
2170
*              - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
2171
**************************************************/
2172
static void
2173
keccak_squeezeblocks(uint8_t *out,
2174
                     size_t nblocks,
2175
                     uint64_t s[25],
2176
                     unsigned int r)
2177
0
{
2178
0
    unsigned int i;
2179
2180
0
    while (nblocks) {
2181
0
        KeccakF1600_StatePermute(s);
2182
0
        for (i = 0; i < r / 8; i++)
2183
0
            store64(out + 8 * i, s[i]);
2184
0
        out += r;
2185
0
        nblocks -= 1;
2186
0
    }
2187
0
}
2188
2189
/*************************************************
2190
* Name:        shake128_init
2191
*
2192
* Description: Initilizes Keccak state for use as SHAKE128 XOF
2193
*
2194
* Arguments:   - keccak_state *state: pointer to (uninitialized) Keccak state
2195
**************************************************/
2196
void
2197
shake128_init(keccak_state *state)
2198
0
{
2199
0
    keccak_init(state->s);
2200
0
    state->pos = 0;
2201
0
}
2202
2203
/*************************************************
2204
* Name:        shake128_absorb
2205
*
2206
* Description: Absorb step of the SHAKE128 XOF; incremental.
2207
*
2208
* Arguments:   - keccak_state *state: pointer to (initialized) output Keccak state
2209
*              - const uint8_t *in: pointer to input to be absorbed into s
2210
*              - size_t inlen: length of input in bytes
2211
**************************************************/
2212
void
2213
shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen)
2214
0
{
2215
0
    state->pos = keccak_absorb(state->s, state->pos, SHAKE128_RATE, in, inlen);
2216
0
}
2217
2218
/*************************************************
2219
* Name:        shake128_finalize
2220
*
2221
* Description: Finalize absorb step of the SHAKE128 XOF.
2222
*
2223
* Arguments:   - keccak_state *state: pointer to Keccak state
2224
**************************************************/
2225
void
2226
shake128_finalize(keccak_state *state)
2227
0
{
2228
0
    keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F);
2229
0
    state->pos = SHAKE128_RATE;
2230
0
}
2231
2232
/*************************************************
2233
* Name:        shake128_squeeze
2234
*
2235
* Description: Squeeze step of SHAKE128 XOF. Squeezes arbitraily many
2236
*              bytes. Can be called multiple times to keep squeezing.
2237
*
2238
* Arguments:   - uint8_t *out: pointer to output blocks
2239
*              - size_t outlen : number of bytes to be squeezed (written to output)
2240
*              - keccak_state *s: pointer to input/output Keccak state
2241
**************************************************/
2242
void
2243
shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state)
2244
0
{
2245
0
    state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE128_RATE);
2246
0
}
2247
2248
/*************************************************
2249
* Name:        shake128_absorb_once
2250
*
2251
* Description: Initialize, absorb into and finalize SHAKE128 XOF; non-incremental.
2252
*
2253
* Arguments:   - keccak_state *state: pointer to (uninitialized) output Keccak state
2254
*              - const uint8_t *in: pointer to input to be absorbed into s
2255
*              - size_t inlen: length of input in bytes
2256
**************************************************/
2257
void
2258
shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen)
2259
0
{
2260
0
    keccak_absorb_once(state->s, SHAKE128_RATE, in, inlen, 0x1F);
2261
0
    state->pos = SHAKE128_RATE;
2262
0
}
2263
2264
/*************************************************
2265
* Name:        shake128_squeezeblocks
2266
*
2267
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
2268
*              SHAKE128_RATE bytes each. Can be called multiple times
2269
*              to keep squeezing. Assumes new block has not yet been
2270
*              started (state->pos = SHAKE128_RATE).
2271
*
2272
* Arguments:   - uint8_t *out: pointer to output blocks
2273
*              - size_t nblocks: number of blocks to be squeezed (written to output)
2274
*              - keccak_state *s: pointer to input/output Keccak state
2275
**************************************************/
2276
void
2277
shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
2278
0
{
2279
0
    keccak_squeezeblocks(out, nblocks, state->s, SHAKE128_RATE);
2280
0
}
2281
2282
/*************************************************
2283
* Name:        shake256_init
2284
*
2285
* Description: Initilizes Keccak state for use as SHAKE256 XOF
2286
*
2287
* Arguments:   - keccak_state *state: pointer to (uninitialized) Keccak state
2288
**************************************************/
2289
void
2290
shake256_init(keccak_state *state)
2291
0
{
2292
0
    keccak_init(state->s);
2293
0
    state->pos = 0;
2294
0
}
2295
2296
/*************************************************
2297
* Name:        shake256_absorb
2298
*
2299
* Description: Absorb step of the SHAKE256 XOF; incremental.
2300
*
2301
* Arguments:   - keccak_state *state: pointer to (initialized) output Keccak state
2302
*              - const uint8_t *in: pointer to input to be absorbed into s
2303
*              - size_t inlen: length of input in bytes
2304
**************************************************/
2305
void
2306
shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen)
2307
0
{
2308
0
    state->pos = keccak_absorb(state->s, state->pos, SHAKE256_RATE, in, inlen);
2309
0
}
2310
2311
/*************************************************
2312
* Name:        shake256_finalize
2313
*
2314
* Description: Finalize absorb step of the SHAKE256 XOF.
2315
*
2316
* Arguments:   - keccak_state *state: pointer to Keccak state
2317
**************************************************/
2318
void
2319
shake256_finalize(keccak_state *state)
2320
0
{
2321
0
    keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F);
2322
0
    state->pos = SHAKE256_RATE;
2323
0
}
2324
2325
/*************************************************
2326
* Name:        shake256_squeeze
2327
*
2328
* Description: Squeeze step of SHAKE256 XOF. Squeezes arbitraily many
2329
*              bytes. Can be called multiple times to keep squeezing.
2330
*
2331
* Arguments:   - uint8_t *out: pointer to output blocks
2332
*              - size_t outlen : number of bytes to be squeezed (written to output)
2333
*              - keccak_state *s: pointer to input/output Keccak state
2334
**************************************************/
2335
void
2336
shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state)
2337
0
{
2338
0
    state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE256_RATE);
2339
0
}
2340
2341
/*************************************************
2342
* Name:        shake256_absorb_once
2343
*
2344
* Description: Initialize, absorb into and finalize SHAKE256 XOF; non-incremental.
2345
*
2346
* Arguments:   - keccak_state *state: pointer to (uninitialized) output Keccak state
2347
*              - const uint8_t *in: pointer to input to be absorbed into s
2348
*              - size_t inlen: length of input in bytes
2349
**************************************************/
2350
void
2351
shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen)
2352
0
{
2353
0
    keccak_absorb_once(state->s, SHAKE256_RATE, in, inlen, 0x1F);
2354
0
    state->pos = SHAKE256_RATE;
2355
0
}
2356
2357
/*************************************************
2358
* Name:        shake256_squeezeblocks
2359
*
2360
* Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
2361
*              SHAKE256_RATE bytes each. Can be called multiple times
2362
*              to keep squeezing. Assumes next block has not yet been
2363
*              started (state->pos = SHAKE256_RATE).
2364
*
2365
* Arguments:   - uint8_t *out: pointer to output blocks
2366
*              - size_t nblocks: number of blocks to be squeezed (written to output)
2367
*              - keccak_state *s: pointer to input/output Keccak state
2368
**************************************************/
2369
void
2370
shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
2371
0
{
2372
0
    keccak_squeezeblocks(out, nblocks, state->s, SHAKE256_RATE);
2373
0
}
2374
2375
/*************************************************
2376
* Name:        shake128
2377
*
2378
* Description: SHAKE128 XOF with non-incremental API
2379
*
2380
* Arguments:   - uint8_t *out: pointer to output
2381
*              - size_t outlen: requested output length in bytes
2382
*              - const uint8_t *in: pointer to input
2383
*              - size_t inlen: length of input in bytes
2384
**************************************************/
2385
void
2386
shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
2387
0
{
2388
0
    size_t nblocks;
2389
0
    keccak_state state;
2390
2391
0
    shake128_absorb_once(&state, in, inlen);
2392
0
    nblocks = outlen / SHAKE128_RATE;
2393
0
    shake128_squeezeblocks(out, nblocks, &state);
2394
0
    outlen -= nblocks * SHAKE128_RATE;
2395
0
    out += nblocks * SHAKE128_RATE;
2396
0
    shake128_squeeze(out, outlen, &state);
2397
0
}
2398
2399
/*************************************************
2400
* Name:        shake256
2401
*
2402
* Description: SHAKE256 XOF with non-incremental API
2403
*
2404
* Arguments:   - uint8_t *out: pointer to output
2405
*              - size_t outlen: requested output length in bytes
2406
*              - const uint8_t *in: pointer to input
2407
*              - size_t inlen: length of input in bytes
2408
**************************************************/
2409
void
2410
shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
2411
0
{
2412
0
    size_t nblocks;
2413
0
    keccak_state state;
2414
2415
0
    shake256_absorb_once(&state, in, inlen);
2416
0
    nblocks = outlen / SHAKE256_RATE;
2417
0
    shake256_squeezeblocks(out, nblocks, &state);
2418
0
    outlen -= nblocks * SHAKE256_RATE;
2419
0
    out += nblocks * SHAKE256_RATE;
2420
0
    shake256_squeeze(out, outlen, &state);
2421
0
}
2422
2423
/*************************************************
2424
* Name:        sha3_256
2425
*
2426
* Description: SHA3-256 with non-incremental API
2427
*
2428
* Arguments:   - uint8_t *h: pointer to output (32 bytes)
2429
*              - const uint8_t *in: pointer to input
2430
*              - size_t inlen: length of input in bytes
2431
**************************************************/
2432
void
2433
sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen)
2434
0
{
2435
0
    unsigned int i;
2436
0
    uint64_t s[25];
2437
2438
0
    keccak_absorb_once(s, SHA3_256_RATE, in, inlen, 0x06);
2439
0
    KeccakF1600_StatePermute(s);
2440
0
    for (i = 0; i < 4; i++)
2441
0
        store64(h + 8 * i, s[i]);
2442
0
}
2443
2444
/*************************************************
2445
* Name:        sha3_512
2446
*
2447
* Description: SHA3-512 with non-incremental API
2448
*
2449
* Arguments:   - uint8_t *h: pointer to output (64 bytes)
2450
*              - const uint8_t *in: pointer to input
2451
*              - size_t inlen: length of input in bytes
2452
**************************************************/
2453
void
2454
sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen)
2455
0
{
2456
0
    unsigned int i;
2457
0
    uint64_t s[25];
2458
2459
0
    keccak_absorb_once(s, SHA3_512_RATE, in, inlen, 0x06);
2460
0
    KeccakF1600_StatePermute(s);
2461
0
    for (i = 0; i < 8; i++)
2462
0
        store64(h + 8 * i, s[i]);
2463
0
}
2464
/** end: ref/fips202.c **/
2465
2466
/** begin: ref/symmetric-shake.c **/
2467
/*************************************************
2468
* Name:        kyber_shake128_absorb
2469
*
2470
* Description: Absorb step of the SHAKE128 specialized for the Kyber context.
2471
*
2472
* Arguments:   - keccak_state *state: pointer to (uninitialized) output Keccak state
2473
*              - const uint8_t *seed: pointer to KYBER_SYMBYTES input to be absorbed into state
2474
*              - uint8_t i: additional byte of input
2475
*              - uint8_t j: additional byte of input
2476
**************************************************/
2477
static void
2478
kyber_shake128_absorb(keccak_state *state,
2479
                      const uint8_t seed[KYBER_SYMBYTES],
2480
                      uint8_t x,
2481
                      uint8_t y)
2482
0
{
2483
0
    uint8_t extseed[KYBER_SYMBYTES + 2];
2484
2485
0
    memcpy(extseed, seed, KYBER_SYMBYTES);
2486
0
    extseed[KYBER_SYMBYTES + 0] = x;
2487
0
    extseed[KYBER_SYMBYTES + 1] = y;
2488
2489
0
    shake128_absorb_once(state, extseed, sizeof(extseed));
2490
0
}
2491
2492
/*************************************************
2493
* Name:        kyber_shake256_prf
2494
*
2495
* Description: Usage of SHAKE256 as a PRF, concatenates secret and public input
2496
*              and then generates outlen bytes of SHAKE256 output
2497
*
2498
* Arguments:   - uint8_t *out: pointer to output
2499
*              - size_t outlen: number of requested output bytes
2500
*              - const uint8_t *key: pointer to the key (of length KYBER_SYMBYTES)
2501
*              - uint8_t nonce: single-byte nonce (public PRF input)
2502
**************************************************/
2503
static void
2504
kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYMBYTES], uint8_t nonce)
2505
0
{
2506
0
    uint8_t extkey[KYBER_SYMBYTES + 1];
2507
2508
0
    memcpy(extkey, key, KYBER_SYMBYTES);
2509
0
    extkey[KYBER_SYMBYTES] = nonce;
2510
2511
0
    shake256(out, outlen, extkey, sizeof(extkey));
2512
0
}
2513
/** end: ref/symmetric-shake.c **/
2514
2515
/** begin: ref/kem.c **/
2516
/*************************************************
2517
* Name:        crypto_kem_keypair_derand
2518
*
2519
* Description: Generates public and private key
2520
*              for CCA-secure Kyber key encapsulation mechanism
2521
*
2522
* Arguments:   - uint8_t *pk: pointer to output public key
2523
*                (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
2524
*              - uint8_t *sk: pointer to output private key
2525
*                (an already allocated array of KYBER_SECRETKEYBYTES bytes)
2526
*              - uint8_t *coins: pointer to input randomness
2527
*                (an already allocated array filled with 2*KYBER_SYMBYTES random bytes)
2528
**
2529
* Returns 0 (success)
2530
**************************************************/
2531
int
2532
crypto_kem_keypair_derand(uint8_t *pk,
2533
                          uint8_t *sk,
2534
                          const uint8_t *coins)
2535
0
{
2536
0
    size_t i;
2537
0
    indcpa_keypair_derand(pk, sk, coins);
2538
0
    for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++)
2539
0
        sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i];
2540
0
    hash_h(sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
2541
    /* Value z for pseudo-random output on reject */
2542
0
    for (i = 0; i < KYBER_SYMBYTES; i++)
2543
0
        sk[KYBER_SECRETKEYBYTES - KYBER_SYMBYTES + i] = coins[KYBER_SYMBYTES + i];
2544
0
    return 0;
2545
0
}
2546
2547
/*************************************************
2548
* Name:        crypto_kem_keypair
2549
*
2550
* Description: Generates public and private key
2551
*              for CCA-secure Kyber key encapsulation mechanism
2552
*
2553
* Arguments:   - uint8_t *pk: pointer to output public key
2554
*                (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
2555
*              - uint8_t *sk: pointer to output private key
2556
*                (an already allocated array of KYBER_SECRETKEYBYTES bytes)
2557
*
2558
* Returns 0 (success)
2559
**************************************************/
2560
int
2561
crypto_kem_keypair(uint8_t *pk,
2562
                   uint8_t *sk)
2563
0
{
2564
0
    uint8_t coins[2 * KYBER_SYMBYTES];
2565
0
    randombytes(coins, KYBER_SYMBYTES);
2566
0
    randombytes(coins + KYBER_SYMBYTES, KYBER_SYMBYTES);
2567
0
    crypto_kem_keypair_derand(pk, sk, coins);
2568
0
    return 0;
2569
0
}
2570
2571
/*************************************************
2572
* Name:        crypto_kem_enc_derand
2573
*
2574
* Description: Generates cipher text and shared
2575
*              secret for given public key
2576
*
2577
* Arguments:   - uint8_t *ct: pointer to output cipher text
2578
*                (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
2579
*              - uint8_t *ss: pointer to output shared secret
2580
*                (an already allocated array of KYBER_SSBYTES bytes)
2581
*              - const uint8_t *pk: pointer to input public key
2582
*                (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
2583
*              - const uint8_t *coins: pointer to input randomness
2584
*                (an already allocated array filled with KYBER_SYMBYTES random bytes)
2585
**
2586
* Returns 0 (success)
2587
**************************************************/
2588
int
2589
crypto_kem_enc_derand(uint8_t *ct,
2590
                      uint8_t *ss,
2591
                      const uint8_t *pk,
2592
                      const uint8_t *coins)
2593
0
{
2594
0
    uint8_t buf[2 * KYBER_SYMBYTES];
2595
    /* Will contain key, coins */
2596
0
    uint8_t kr[2 * KYBER_SYMBYTES];
2597
2598
    /* Don't release system RNG output */
2599
0
    hash_h(buf, coins, KYBER_SYMBYTES);
2600
2601
    /* Multitarget countermeasure for coins + contributory KEM */
2602
0
    hash_h(buf + KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
2603
0
    hash_g(kr, buf, 2 * KYBER_SYMBYTES);
2604
2605
    /* coins are in kr+KYBER_SYMBYTES */
2606
0
    indcpa_enc(ct, buf, pk, kr + KYBER_SYMBYTES);
2607
2608
    /* overwrite coins in kr with H(c) */
2609
0
    hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES);
2610
    /* hash concatenation of pre-k and H(c) to k */
2611
0
    kdf(ss, kr, 2 * KYBER_SYMBYTES);
2612
0
    return 0;
2613
0
}
2614
2615
/*************************************************
2616
* Name:        crypto_kem_enc
2617
*
2618
* Description: Generates cipher text and shared
2619
*              secret for given public key
2620
*
2621
* Arguments:   - uint8_t *ct: pointer to output cipher text
2622
*                (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
2623
*              - uint8_t *ss: pointer to output shared secret
2624
*                (an already allocated array of KYBER_SSBYTES bytes)
2625
*              - const uint8_t *pk: pointer to input public key
2626
*                (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
2627
*
2628
* Returns 0 (success)
2629
**************************************************/
2630
int
2631
crypto_kem_enc(uint8_t *ct,
2632
               uint8_t *ss,
2633
               const uint8_t *pk)
2634
0
{
2635
0
    uint8_t coins[KYBER_SYMBYTES];
2636
0
    randombytes(coins, KYBER_SYMBYTES);
2637
0
    crypto_kem_enc_derand(ct, ss, pk, coins);
2638
0
    return 0;
2639
0
}
2640
2641
/*************************************************
2642
* Name:        crypto_kem_dec
2643
*
2644
* Description: Generates shared secret for given
2645
*              cipher text and private key
2646
*
2647
* Arguments:   - uint8_t *ss: pointer to output shared secret
2648
*                (an already allocated array of KYBER_SSBYTES bytes)
2649
*              - const uint8_t *ct: pointer to input cipher text
2650
*                (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
2651
*              - const uint8_t *sk: pointer to input private key
2652
*                (an already allocated array of KYBER_SECRETKEYBYTES bytes)
2653
*
2654
* Returns 0.
2655
*
2656
* On failure, ss will contain a pseudo-random value.
2657
**************************************************/
2658
int
2659
crypto_kem_dec(uint8_t *ss,
2660
               const uint8_t *ct,
2661
               const uint8_t *sk)
2662
0
{
2663
0
    size_t i;
2664
0
    int fail;
2665
0
    uint8_t buf[2 * KYBER_SYMBYTES];
2666
    /* Will contain key, coins */
2667
0
    uint8_t kr[2 * KYBER_SYMBYTES];
2668
0
    uint8_t cmp[KYBER_CIPHERTEXTBYTES];
2669
0
    const uint8_t *pk = sk + KYBER_INDCPA_SECRETKEYBYTES;
2670
2671
0
    indcpa_dec(buf, ct, sk);
2672
2673
    /* Multitarget countermeasure for coins + contributory KEM */
2674
0
    for (i = 0; i < KYBER_SYMBYTES; i++)
2675
0
        buf[KYBER_SYMBYTES + i] = sk[KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES + i];
2676
0
    hash_g(kr, buf, 2 * KYBER_SYMBYTES);
2677
2678
    /* coins are in kr+KYBER_SYMBYTES */
2679
0
    indcpa_enc(cmp, buf, pk, kr + KYBER_SYMBYTES);
2680
2681
0
    fail = verify(ct, cmp, KYBER_CIPHERTEXTBYTES);
2682
2683
    /* overwrite coins in kr with H(c) */
2684
0
    hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES);
2685
2686
    /* Overwrite pre-k with z on re-encryption failure */
2687
0
    cmov(kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES, fail);
2688
2689
    /* hash concatenation of pre-k and H(c) to k */
2690
0
    kdf(ss, kr, 2 * KYBER_SYMBYTES);
2691
0
    return 0;
2692
0
}
2693
/** end: ref/kem.c **/