Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/cipher/kyber-common.c
Line
Count
Source (jump to first uncovered line)
1
/* kyber-common.c - the Kyber key encapsulation mechanism (common part)
2
 * Copyright (C) 2024 g10 Code GmbH
3
 *
4
 * This file was modified for use by Libgcrypt.
5
 *
6
 * This file is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * This file is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
18
 * SPDX-License-Identifier: LGPL-2.1-or-later
19
 *
20
 * You can also use this file under the same licence of original code.
21
 * SPDX-License-Identifier: CC0 OR Apache-2.0
22
 *
23
 */
24
/*
25
  Original code from:
26
27
  Repository: https://github.com/pq-crystals/kyber.git
28
  Branch: standard
29
  Commit: 11d00ff1f20cfca1f72d819e5a45165c1e0a2816
30
31
  Licence:
32
  Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
33
  or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
34
35
  Authors:
36
        Joppe Bos
37
        Léo Ducas
38
        Eike Kiltz
39
        Tancrède Lepoint
40
        Vadim Lyubashevsky
41
        John Schanck
42
        Peter Schwabe
43
        Gregor Seiler
44
        Damien Stehlé
45
46
  Kyber Home: https://www.pq-crystals.org/kyber/
47
 */
48
/*
49
 * From original code, following modification was made.
50
 *
51
 * - C++ style comments are changed to C-style.
52
 *
53
 * - Functions "poly_cbd_eta1" "poly_cbd_eta2" are removed.
54
 *
55
 * - Constant "zeta" is static, not available outside.
56
 *
57
 * - "poly_compress" and "poly_decompress" are now two variants _128
58
 *   and _160.
59
 *
60
 * - "poly_getnoise_eta1" is now two variants _2 and _3_4.
61
 *
62
 * - "poly_getnoise_eta2" directly uses "cbd2" function.
63
 */
64
65
/*************** kyber/ref/cbd.c */
66
67
/*************************************************
68
* Name:        load32_littleendian
69
*
70
* Description: load 4 bytes into a 32-bit integer
71
*              in little-endian order
72
*
73
* Arguments:   - const uint8_t *x: pointer to input byte array
74
*
75
* Returns 32-bit unsigned integer loaded from x
76
**************************************************/
77
static uint32_t load32_littleendian(const uint8_t x[4])
78
0
{
79
0
  uint32_t r;
80
0
  r  = (uint32_t)x[0];
81
0
  r |= (uint32_t)x[1] << 8;
82
0
  r |= (uint32_t)x[2] << 16;
83
0
  r |= (uint32_t)x[3] << 24;
84
0
  return r;
85
0
}
86
87
/*************************************************
88
* Name:        load24_littleendian
89
*
90
* Description: load 3 bytes into a 32-bit integer
91
*              in little-endian order.
92
*              This function is only needed for Kyber-512
93
*
94
* Arguments:   - const uint8_t *x: pointer to input byte array
95
*
96
* Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
97
**************************************************/
98
#if !defined(KYBER_K) || KYBER_K == 2
99
static uint32_t load24_littleendian(const uint8_t x[3])
100
0
{
101
0
  uint32_t r;
102
0
  r  = (uint32_t)x[0];
103
0
  r |= (uint32_t)x[1] << 8;
104
0
  r |= (uint32_t)x[2] << 16;
105
0
  return r;
106
0
}
107
#endif
108
109
110
/*************************************************
111
* Name:        cbd2
112
*
113
* Description: Given an array of uniformly random bytes, compute
114
*              polynomial with coefficients distributed according to
115
*              a centered binomial distribution with parameter eta=2
116
*
117
* Arguments:   - poly *r: pointer to output polynomial
118
*              - const uint8_t *buf: pointer to input byte array
119
**************************************************/
120
static void cbd2(poly *r, const uint8_t buf[2*KYBER_N/4])
121
0
{
122
0
  unsigned int i,j;
123
0
  uint32_t t,d;
124
0
  int16_t a,b;
125
126
0
  for(i=0;i<KYBER_N/8;i++) {
127
0
    t  = load32_littleendian(buf+4*i);
128
0
    d  = t & 0x55555555;
129
0
    d += (t>>1) & 0x55555555;
130
131
0
    for(j=0;j<8;j++) {
132
0
      a = (d >> (4*j+0)) & 0x3;
133
0
      b = (d >> (4*j+2)) & 0x3;
134
0
      r->coeffs[8*i+j] = a - b;
135
0
    }
136
0
  }
137
0
}
138
139
/*************************************************
140
* Name:        cbd3
141
*
142
* Description: Given an array of uniformly random bytes, compute
143
*              polynomial with coefficients distributed according to
144
*              a centered binomial distribution with parameter eta=3.
145
*              This function is only needed for Kyber-512
146
*
147
* Arguments:   - poly *r: pointer to output polynomial
148
*              - const uint8_t *buf: pointer to input byte array
149
**************************************************/
150
#if !defined(KYBER_K) || KYBER_K == 2
151
static void cbd3(poly *r, const uint8_t buf[3*KYBER_N/4])
152
0
{
153
0
  unsigned int i,j;
154
0
  uint32_t t,d;
155
0
  int16_t a,b;
156
157
0
  for(i=0;i<KYBER_N/4;i++) {
158
0
    t  = load24_littleendian(buf+3*i);
159
0
    d  = t & 0x00249249;
160
0
    d += (t>>1) & 0x00249249;
161
0
    d += (t>>2) & 0x00249249;
162
163
0
    for(j=0;j<4;j++) {
164
0
      a = (d >> (6*j+0)) & 0x7;
165
0
      b = (d >> (6*j+3)) & 0x7;
166
0
      r->coeffs[4*i+j] = a - b;
167
0
    }
168
0
  }
169
0
}
170
#endif
171
172
/*************** kyber/ref/indcpa.c */
173
/*************************************************
174
* Name:        rej_uniform
175
*
176
* Description: Run rejection sampling on uniform random bytes to generate
177
*              uniform random integers mod q
178
*
179
* Arguments:   - int16_t *r: pointer to output buffer
180
*              - unsigned int len: requested number of 16-bit integers (uniform mod q)
181
*              - const uint8_t *buf: pointer to input buffer (assumed to be uniformly random bytes)
182
*              - unsigned int buflen: length of input buffer in bytes
183
*
184
* Returns number of sampled 16-bit integers (at most len)
185
**************************************************/
186
static unsigned int rej_uniform(int16_t *r,
187
                                unsigned int len,
188
                                const uint8_t *buf,
189
                                unsigned int buflen)
190
0
{
191
0
  unsigned int ctr, pos;
192
0
  uint16_t val0, val1;
193
194
0
  ctr = pos = 0;
195
0
  while(ctr < len && pos + 3 <= buflen) {
196
0
    val0 = ((buf[pos+0] >> 0) | ((uint16_t)buf[pos+1] << 8)) & 0xFFF;
197
0
    val1 = ((buf[pos+1] >> 4) | ((uint16_t)buf[pos+2] << 4)) & 0xFFF;
198
0
    pos += 3;
199
200
0
    if(val0 < KYBER_Q)
201
0
      r[ctr++] = val0;
202
0
    if(ctr < len && val1 < KYBER_Q)
203
0
      r[ctr++] = val1;
204
0
  }
205
206
0
  return ctr;
207
0
}
208
209
/*************** kyber/ref/ntt.c */
210
/* Code to generate zetas and zetas_inv used in the number-theoretic transform:
211
212
#define KYBER_ROOT_OF_UNITY 17
213
214
static const uint8_t tree[128] = {
215
  0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120,
216
  4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124,
217
  2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122,
218
  6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126,
219
  1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121,
220
  5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125,
221
  3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123,
222
  7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127
223
};
224
225
void init_ntt() {
226
  unsigned int i;
227
  int16_t tmp[128];
228
229
  tmp[0] = MONT;
230
  for(i=1;i<128;i++)
231
    tmp[i] = fqmul(tmp[i-1],MONT*KYBER_ROOT_OF_UNITY % KYBER_Q);
232
233
  for(i=0;i<128;i++) {
234
    zetas[i] = tmp[tree[i]];
235
    if(zetas[i] > KYBER_Q/2)
236
      zetas[i] -= KYBER_Q;
237
    if(zetas[i] < -KYBER_Q/2)
238
      zetas[i] += KYBER_Q;
239
  }
240
}
241
*/
242
243
static const int16_t zetas[128] = {
244
  -1044,  -758,  -359, -1517,  1493,  1422,   287,   202,
245
   -171,   622,  1577,   182,   962, -1202, -1474,  1468,
246
    573, -1325,   264,   383,  -829,  1458, -1602,  -130,
247
   -681,  1017,   732,   608, -1542,   411,  -205, -1571,
248
   1223,   652,  -552,  1015, -1293,  1491,  -282, -1544,
249
    516,    -8,  -320,  -666, -1618, -1162,   126,  1469,
250
   -853,   -90,  -271,   830,   107, -1421,  -247,  -951,
251
   -398,   961, -1508,  -725,   448, -1065,   677, -1275,
252
  -1103,   430,   555,   843, -1251,   871,  1550,   105,
253
    422,   587,   177,  -235,  -291,  -460,  1574,  1653,
254
   -246,   778,  1159,  -147,  -777,  1483,  -602,  1119,
255
  -1590,   644,  -872,   349,   418,   329,  -156,   -75,
256
    817,  1097,   603,   610,  1322, -1285, -1465,   384,
257
  -1215,  -136,  1218, -1335,  -874,   220, -1187, -1659,
258
  -1185, -1530, -1278,   794, -1510,  -854,  -870,   478,
259
   -108,  -308,   996,   991,   958, -1460,  1522,  1628
260
};
261
262
/*************************************************
263
* Name:        fqmul
264
*
265
* Description: Multiplication followed by Montgomery reduction
266
*
267
* Arguments:   - int16_t a: first factor
268
*              - int16_t b: second factor
269
*
270
* Returns 16-bit integer congruent to a*b*R^{-1} mod q
271
**************************************************/
272
0
static int16_t fqmul(int16_t a, int16_t b) {
273
0
  return montgomery_reduce((int32_t)a*b);
274
0
}
275
276
/*************************************************
277
* Name:        ntt
278
*
279
* Description: Inplace number-theoretic transform (NTT) in Rq.
280
*              input is in standard order, output is in bitreversed order
281
*
282
* Arguments:   - int16_t r[256]: pointer to input/output vector of elements of Zq
283
**************************************************/
284
0
void ntt(int16_t r[256]) {
285
0
  unsigned int len, start, j, k;
286
0
  int16_t t, zeta;
287
288
0
  k = 1;
289
0
  for(len = 128; len >= 2; len >>= 1) {
290
0
    for(start = 0; start < 256; start = j + len) {
291
0
      zeta = zetas[k++];
292
0
      for(j = start; j < start + len; j++) {
293
0
        t = fqmul(zeta, r[j + len]);
294
0
        r[j + len] = r[j] - t;
295
0
        r[j] = r[j] + t;
296
0
      }
297
0
    }
298
0
  }
299
0
}
300
301
/*************************************************
302
* Name:        invntt_tomont
303
*
304
* Description: Inplace inverse number-theoretic transform in Rq and
305
*              multiplication by Montgomery factor 2^16.
306
*              Input is in bitreversed order, output is in standard order
307
*
308
* Arguments:   - int16_t r[256]: pointer to input/output vector of elements of Zq
309
**************************************************/
310
0
void invntt(int16_t r[256]) {
311
0
  unsigned int start, len, j, k;
312
0
  int16_t t, zeta;
313
0
  const int16_t f = 1441; /* mont^2/128 */
314
315
0
  k = 127;
316
0
  for(len = 2; len <= 128; len <<= 1) {
317
0
    for(start = 0; start < 256; start = j + len) {
318
0
      zeta = zetas[k--];
319
0
      for(j = start; j < start + len; j++) {
320
0
        t = r[j];
321
0
        r[j] = barrett_reduce(t + r[j + len]);
322
0
        r[j + len] = r[j + len] - t;
323
0
        r[j + len] = fqmul(zeta, r[j + len]);
324
0
      }
325
0
    }
326
0
  }
327
328
0
  for(j = 0; j < 256; j++)
329
0
    r[j] = fqmul(r[j], f);
330
0
}
331
332
/*************************************************
333
* Name:        basemul
334
*
335
* Description: Multiplication of polynomials in Zq[X]/(X^2-zeta)
336
*              used for multiplication of elements in Rq in NTT domain
337
*
338
* Arguments:   - int16_t r[2]: pointer to the output polynomial
339
*              - const int16_t a[2]: pointer to the first factor
340
*              - const int16_t b[2]: pointer to the second factor
341
*              - int16_t zeta: integer defining the reduction polynomial
342
**************************************************/
343
void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta)
344
0
{
345
0
  r[0]  = fqmul(a[1], b[1]);
346
0
  r[0]  = fqmul(r[0], zeta);
347
0
  r[0] += fqmul(a[0], b[0]);
348
0
  r[1]  = fqmul(a[0], b[1]);
349
0
  r[1] += fqmul(a[1], b[0]);
350
0
}
351
/*************** kyber/ref/poly.c */
352
353
/*************************************************
354
* Name:        poly_compress
355
*
356
* Description: Compression and subsequent serialization of a polynomial
357
*
358
* Arguments:   - uint8_t *r: pointer to output byte array
359
*                            (of length KYBER_POLYCOMPRESSEDBYTES)
360
*              - const poly *a: pointer to input polynomial
361
**************************************************/
362
#if !defined(KYBER_K) || KYBER_K == 2 || KYBER_K == 3
363
void poly_compress_128(uint8_t r[KYBER_POLYCOMPRESSEDBYTES_2_3], const poly *a)
364
0
{
365
0
  unsigned int i,j;
366
0
  int32_t u;
367
0
  uint32_t d0;
368
0
  uint8_t t[8];
369
370
0
  for(i=0;i<KYBER_N/8;i++) {
371
0
    for(j=0;j<8;j++) {
372
      /* map to positive standard representatives */
373
0
      u  = a->coeffs[8*i+j];
374
0
      u += (u >> 15) & KYBER_Q;
375
/*    t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15; */
376
0
      d0 = u << 4;
377
0
      d0 += 1665;
378
0
      d0 *= 80635;
379
0
      d0 >>= 28;
380
0
      t[j] = d0 & 0xf;
381
0
    }
382
383
0
    r[0] = t[0] | (t[1] << 4);
384
0
    r[1] = t[2] | (t[3] << 4);
385
0
    r[2] = t[4] | (t[5] << 4);
386
0
    r[3] = t[6] | (t[7] << 4);
387
0
    r += 4;
388
0
  }
389
0
}
390
#endif
391
392
#if !defined(KYBER_K) || KYBER_K == 4
393
void poly_compress_160(uint8_t r[KYBER_POLYCOMPRESSEDBYTES_4], const poly *a)
394
0
{
395
0
  unsigned int i,j;
396
0
  int32_t u;
397
0
  uint32_t d0;
398
0
  uint8_t t[8];
399
400
0
  for(i=0;i<KYBER_N/8;i++) {
401
0
    for(j=0;j<8;j++) {
402
      /* map to positive standard representatives */
403
0
      u  = a->coeffs[8*i+j];
404
0
      u += (u >> 15) & KYBER_Q;
405
/*    t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31; */
406
0
      d0 = u << 5;
407
0
      d0 += 1664;
408
0
      d0 *= 40318;
409
0
      d0 >>= 27;
410
0
      t[j] = d0 & 0x1f;
411
0
    }
412
413
0
    r[0] = (t[0] >> 0) | (t[1] << 5);
414
0
    r[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
415
0
    r[2] = (t[3] >> 1) | (t[4] << 4);
416
0
    r[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6);
417
0
    r[4] = (t[6] >> 2) | (t[7] << 3);
418
0
    r += 5;
419
0
  }
420
0
}
421
#endif
422
423
/*************************************************
424
* Name:        poly_decompress
425
*
426
* Description: De-serialization and subsequent decompression of a polynomial;
427
*              approximate inverse of poly_compress
428
*
429
* Arguments:   - poly *r: pointer to output polynomial
430
*              - const uint8_t *a: pointer to input byte array
431
*                                  (of length KYBER_POLYCOMPRESSEDBYTES bytes)
432
**************************************************/
433
#if !defined(KYBER_K) || KYBER_K == 2 || KYBER_K == 3
434
void poly_decompress_128(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES_2_3])
435
0
{
436
0
  unsigned int i;
437
0
  for(i=0;i<KYBER_N/2;i++) {
438
0
    r->coeffs[2*i+0] = (((uint16_t)(a[0] & 15)*KYBER_Q) + 8) >> 4;
439
0
    r->coeffs[2*i+1] = (((uint16_t)(a[0] >> 4)*KYBER_Q) + 8) >> 4;
440
0
    a += 1;
441
0
  }
442
0
}
443
#endif
444
445
#if !defined(KYBER_K) || KYBER_K == 4
446
void poly_decompress_160(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES_4])
447
0
{
448
0
  unsigned int i;
449
0
  unsigned int j;
450
0
  uint8_t t[8];
451
0
  for(i=0;i<KYBER_N/8;i++) {
452
0
    t[0] = (a[0] >> 0);
453
0
    t[1] = (a[0] >> 5) | (a[1] << 3);
454
0
    t[2] = (a[1] >> 2);
455
0
    t[3] = (a[1] >> 7) | (a[2] << 1);
456
0
    t[4] = (a[2] >> 4) | (a[3] << 4);
457
0
    t[5] = (a[3] >> 1);
458
0
    t[6] = (a[3] >> 6) | (a[4] << 2);
459
0
    t[7] = (a[4] >> 3);
460
0
    a += 5;
461
462
0
    for(j=0;j<8;j++)
463
0
      r->coeffs[8*i+j] = ((uint32_t)(t[j] & 31)*KYBER_Q + 16) >> 5;
464
0
  }
465
0
}
466
#endif
467
468
/*************************************************
469
* Name:        poly_tobytes
470
*
471
* Description: Serialization of a polynomial
472
*
473
* Arguments:   - uint8_t *r: pointer to output byte array
474
*                            (needs space for KYBER_POLYBYTES bytes)
475
*              - const poly *a: pointer to input polynomial
476
**************************************************/
477
void poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a)
478
0
{
479
0
  unsigned int i;
480
0
  uint16_t t0, t1;
481
482
0
  for(i=0;i<KYBER_N/2;i++) {
483
    /* map to positive standard representatives */
484
0
    t0  = a->coeffs[2*i];
485
0
    t0 += ((int16_t)t0 >> 15) & KYBER_Q;
486
0
    t1 = a->coeffs[2*i+1];
487
0
    t1 += ((int16_t)t1 >> 15) & KYBER_Q;
488
0
    r[3*i+0] = (t0 >> 0);
489
0
    r[3*i+1] = (t0 >> 8) | (t1 << 4);
490
0
    r[3*i+2] = (t1 >> 4);
491
0
  }
492
0
}
493
494
/*************************************************
495
* Name:        poly_frombytes
496
*
497
* Description: De-serialization of a polynomial;
498
*              inverse of poly_tobytes
499
*
500
* Arguments:   - poly *r: pointer to output polynomial
501
*              - const uint8_t *a: pointer to input byte array
502
*                                  (of KYBER_POLYBYTES bytes)
503
**************************************************/
504
void poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES])
505
0
{
506
0
  unsigned int i;
507
0
  for(i=0;i<KYBER_N/2;i++) {
508
0
    r->coeffs[2*i]   = ((a[3*i+0] >> 0) | ((uint16_t)a[3*i+1] << 8)) & 0xFFF;
509
0
    r->coeffs[2*i+1] = ((a[3*i+1] >> 4) | ((uint16_t)a[3*i+2] << 4)) & 0xFFF;
510
0
  }
511
0
}
512
513
/*************************************************
514
* Name:        poly_frommsg
515
*
516
* Description: Convert 32-byte message to polynomial
517
*
518
* Arguments:   - poly *r: pointer to output polynomial
519
*              - const uint8_t *msg: pointer to input message
520
**************************************************/
521
void poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES])
522
0
{
523
0
  unsigned int i,j;
524
525
#if (KYBER_INDCPA_MSGBYTES != KYBER_N/8)
526
#error "KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!"
527
#endif
528
529
0
  for(i=0;i<KYBER_N/8;i++) {
530
0
    for(j=0;j<8;j++) {
531
0
      r->coeffs[8*i+j] = ct_int16_select (((KYBER_Q+1)/2), 0, (msg[i] >> j)&1);
532
0
    }
533
0
  }
534
0
}
535
536
/*************************************************
537
* Name:        poly_tomsg
538
*
539
* Description: Convert polynomial to 32-byte message
540
*
541
* Arguments:   - uint8_t *msg: pointer to output message
542
*              - const poly *a: pointer to input polynomial
543
**************************************************/
544
void poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a)
545
0
{
546
0
  unsigned int i,j;
547
0
  uint32_t t;
548
549
0
  for(i=0;i<KYBER_N/8;i++) {
550
0
    msg[i] = 0;
551
0
    for(j=0;j<8;j++) {
552
0
      t  = a->coeffs[8*i+j];
553
      /* t += ((int16_t)t >> 15) & KYBER_Q; */
554
      /* t  = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1; */
555
0
      t <<= 1;
556
0
      t += 1665;
557
0
      t *= 80635;
558
0
      t >>= 28;
559
0
      t &= 1;
560
0
      msg[i] |= t << j;
561
0
    }
562
0
  }
563
0
}
564
565
/*************************************************
566
* Name:        poly_getnoise_eta1
567
*
568
* Description: Sample a polynomial deterministically from a seed and a nonce,
569
*              with output polynomial close to centered binomial distribution
570
*              with parameter KYBER_ETA1
571
*
572
* Arguments:   - poly *r: pointer to output polynomial
573
*              - const uint8_t *seed: pointer to input seed
574
*                                     (of length KYBER_SYMBYTES bytes)
575
*              - uint8_t nonce: one-byte input nonce
576
**************************************************/
577
#if !defined(KYBER_K) || KYBER_K == 2
578
void poly_getnoise_eta1_2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
579
0
{
580
0
  uint8_t buf[KYBER_ETA1_2*KYBER_N/4];
581
0
  prf(buf, sizeof(buf), seed, nonce);
582
0
  cbd3(r, buf);
583
0
}
584
#endif
585
586
#if !defined(KYBER_K) || KYBER_K == 3 || KYBER_K == 4
587
void poly_getnoise_eta1_3_4(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
588
0
{
589
0
  uint8_t buf[KYBER_ETA1_3_4*KYBER_N/4];
590
0
  prf(buf, sizeof(buf), seed, nonce);
591
0
  cbd2(r, buf);
592
0
}
593
#endif
594
595
/*************************************************
596
* Name:        poly_getnoise_eta2
597
*
598
* Description: Sample a polynomial deterministically from a seed and a nonce,
599
*              with output polynomial close to centered binomial distribution
600
*              with parameter KYBER_ETA2
601
*
602
* Arguments:   - poly *r: pointer to output polynomial
603
*              - const uint8_t *seed: pointer to input seed
604
*                                     (of length KYBER_SYMBYTES bytes)
605
*              - uint8_t nonce: one-byte input nonce
606
**************************************************/
607
void poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
608
0
{
609
0
  uint8_t buf[KYBER_ETA2*KYBER_N/4];
610
0
  prf(buf, sizeof(buf), seed, nonce);
611
0
  cbd2(r, buf);
612
0
}
613
614
615
/*************************************************
616
* Name:        poly_ntt
617
*
618
* Description: Computes negacyclic number-theoretic transform (NTT) of
619
*              a polynomial in place;
620
*              inputs assumed to be in normal order, output in bitreversed order
621
*
622
* Arguments:   - uint16_t *r: pointer to in/output polynomial
623
**************************************************/
624
void poly_ntt(poly *r)
625
0
{
626
0
  ntt(r->coeffs);
627
0
  poly_reduce(r);
628
0
}
629
630
/*************************************************
631
* Name:        poly_invntt_tomont
632
*
633
* Description: Computes inverse of negacyclic number-theoretic transform (NTT)
634
*              of a polynomial in place;
635
*              inputs assumed to be in bitreversed order, output in normal order
636
*
637
* Arguments:   - uint16_t *a: pointer to in/output polynomial
638
**************************************************/
639
void poly_invntt_tomont(poly *r)
640
0
{
641
0
  invntt(r->coeffs);
642
0
}
643
644
/*************************************************
645
* Name:        poly_basemul_montgomery
646
*
647
* Description: Multiplication of two polynomials in NTT domain
648
*
649
* Arguments:   - poly *r: pointer to output polynomial
650
*              - const poly *a: pointer to first input polynomial
651
*              - const poly *b: pointer to second input polynomial
652
**************************************************/
653
void poly_basemul_montgomery(poly *r, const poly *a, const poly *b)
654
0
{
655
0
  unsigned int i;
656
0
  for(i=0;i<KYBER_N/4;i++) {
657
0
    basemul(&r->coeffs[4*i], &a->coeffs[4*i], &b->coeffs[4*i], zetas[64+i]);
658
0
    basemul(&r->coeffs[4*i+2], &a->coeffs[4*i+2], &b->coeffs[4*i+2], -zetas[64+i]);
659
0
  }
660
0
}
661
662
/*************************************************
663
* Name:        poly_tomont
664
*
665
* Description: Inplace conversion of all coefficients of a polynomial
666
*              from normal domain to Montgomery domain
667
*
668
* Arguments:   - poly *r: pointer to input/output polynomial
669
**************************************************/
670
void poly_tomont(poly *r)
671
0
{
672
0
  unsigned int i;
673
0
  const int16_t f = (1ULL << 32) % KYBER_Q;
674
0
  for(i=0;i<KYBER_N;i++)
675
0
    r->coeffs[i] = montgomery_reduce((int32_t)r->coeffs[i]*f);
676
0
}
677
678
/*************************************************
679
* Name:        poly_reduce
680
*
681
* Description: Applies Barrett reduction to all coefficients of a polynomial
682
*              for details of the Barrett reduction see comments in reduce.c
683
*
684
* Arguments:   - poly *r: pointer to input/output polynomial
685
**************************************************/
686
void poly_reduce(poly *r)
687
0
{
688
0
  unsigned int i;
689
0
  for(i=0;i<KYBER_N;i++)
690
0
    r->coeffs[i] = barrett_reduce(r->coeffs[i]);
691
0
}
692
693
/*************************************************
694
* Name:        poly_add
695
*
696
* Description: Add two polynomials; no modular reduction is performed
697
*
698
* Arguments: - poly *r: pointer to output polynomial
699
*            - const poly *a: pointer to first input polynomial
700
*            - const poly *b: pointer to second input polynomial
701
**************************************************/
702
void poly_add(poly *r, const poly *a, const poly *b)
703
0
{
704
0
  unsigned int i;
705
0
  for(i=0;i<KYBER_N;i++)
706
0
    r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
707
0
}
708
709
/*************************************************
710
* Name:        poly_sub
711
*
712
* Description: Subtract two polynomials; no modular reduction is performed
713
*
714
* Arguments: - poly *r:       pointer to output polynomial
715
*            - const poly *a: pointer to first input polynomial
716
*            - const poly *b: pointer to second input polynomial
717
**************************************************/
718
void poly_sub(poly *r, const poly *a, const poly *b)
719
0
{
720
0
  unsigned int i;
721
0
  for(i=0;i<KYBER_N;i++)
722
0
    r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
723
0
}
724
725
/*************** kyber/ref/reduce.c */
726
727
/*************************************************
728
* Name:        montgomery_reduce
729
*
730
* Description: Montgomery reduction; given a 32-bit integer a, computes
731
*              16-bit integer congruent to a * R^-1 mod q, where R=2^16
732
*
733
* Arguments:   - int32_t a: input integer to be reduced;
734
*                           has to be in {-q2^15,...,q2^15-1}
735
*
736
* Returns:     integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q.
737
**************************************************/
738
int16_t montgomery_reduce(int32_t a)
739
0
{
740
0
  int16_t t;
741
742
0
  t = (int16_t)a*QINV;
743
0
  t = (a - (int32_t)t*KYBER_Q) >> 16;
744
0
  return t;
745
0
}
746
747
/*************************************************
748
* Name:        barrett_reduce
749
*
750
* Description: Barrett reduction; given a 16-bit integer a, computes
751
*              centered representative congruent to a mod q in {-(q-1)/2,...,(q-1)/2}
752
*
753
* Arguments:   - int16_t a: input integer to be reduced
754
*
755
* Returns:     integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
756
**************************************************/
757
0
int16_t barrett_reduce(int16_t a) {
758
0
  int16_t t;
759
0
  const int16_t v = ((1<<26) + KYBER_Q/2)/KYBER_Q;
760
761
0
  t  = ((int32_t)v*a + (1<<25)) >> 26;
762
0
  t *= KYBER_Q;
763
0
  return a - t;
764
0
}