Coverage Report

Created: 2025-07-01 06:49

/src/libssh/src/external/sntrup761.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Derived from public domain source, written by (in alphabetical order):
3
 * - Daniel J. Bernstein
4
 * - Chitchanok Chuengsatiansup
5
 * - Tanja Lange
6
 * - Christine van Vredendaal
7
 */
8
9
#include <string.h>
10
#include <stdint.h>
11
12
#define SNTRUP761_SECRETKEY_SIZE 1763
13
#define SNTRUP761_PUBLICKEY_SIZE 1158
14
#define SNTRUP761_CIPHERTEXT_SIZE 1039
15
#define SNTRUP761_SIZE 32
16
17
typedef void sntrup761_random_func (void *ctx, size_t length, uint8_t *dst);
18
19
void
20
sntrup761_keypair (uint8_t *pk, uint8_t *sk,
21
       void *random_ctx, sntrup761_random_func *random);
22
23
void
24
sntrup761_enc (uint8_t *c, uint8_t *k, const uint8_t *pk,
25
         void *random_ctx, sntrup761_random_func *random);
26
27
void
28
sntrup761_dec (uint8_t *k, const uint8_t *c, const uint8_t *sk);
29
30
extern void crypto_hash_sha512 (unsigned char *out,
31
        const unsigned char *in,
32
        unsigned long long inlen);
33
34
#define MAX_LEN 761
35
36
/* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */
37
0
#define int32_MINMAX(a,b) \
38
0
do { \
39
0
  int64_t ab = (int64_t)b ^ (int64_t)a; \
40
0
  int64_t c = (int64_t)b - (int64_t)a; \
41
0
  c ^= ab & (c ^ b); \
42
0
  c >>= 31; \
43
0
  c &= ab; \
44
0
  a ^= c; \
45
0
  b ^= c; \
46
0
} while(0)
47
48
/* from supercop-20201130/crypto_sort/int32/portable4/sort.c */
49
static void
50
crypto_sort_int32 (void *array, long long n)
51
0
{
52
0
  long long top, p, q, r, i, j;
53
0
  int32_t *x = array;
54
55
0
  if (n < 2)
56
0
    return;
57
0
  top = 1;
58
0
  while (top < n - top)
59
0
    top += top;
60
61
0
  for (p = top; p >= 1; p >>= 1)
62
0
    {
63
0
      i = 0;
64
0
      while (i + 2 * p <= n)
65
0
  {
66
0
    for (j = i; j < i + p; ++j)
67
0
      int32_MINMAX (x[j], x[j + p]);
68
0
    i += 2 * p;
69
0
  }
70
0
      for (j = i; j < n - p; ++j)
71
0
  int32_MINMAX (x[j], x[j + p]);
72
73
0
      i = 0;
74
0
      j = 0;
75
0
      for (q = top; q > p; q >>= 1)
76
0
  {
77
0
    if (j != i)
78
0
      for (;;)
79
0
        {
80
0
    int32_t a;
81
0
    if (j == n - q)
82
0
      goto done;
83
0
    a = x[j + p];
84
0
    for (r = q; r > p; r >>= 1)
85
0
      int32_MINMAX (a, x[j + r]);
86
0
    x[j + p] = a;
87
0
    ++j;
88
0
    if (j == i + p)
89
0
      {
90
0
        i += 2 * p;
91
0
        break;
92
0
      }
93
0
        }
94
0
    while (i + p <= n - q)
95
0
      {
96
0
        for (j = i; j < i + p; ++j)
97
0
    {
98
0
      int32_t a = x[j + p];
99
0
      for (r = q; r > p; r >>= 1)
100
0
        int32_MINMAX (a, x[j + r]);
101
0
      x[j + p] = a;
102
0
    }
103
0
        i += 2 * p;
104
0
      }
105
    /* now i + p > n - q */
106
0
    j = i;
107
0
    while (j < n - q)
108
0
      {
109
0
        int32_t a = x[j + p];
110
0
        for (r = q; r > p; r >>= 1)
111
0
    int32_MINMAX (a, x[j + r]);
112
0
        x[j + p] = a;
113
0
        ++j;
114
0
      }
115
116
0
  done:;
117
0
  }
118
0
    }
119
0
}
120
121
/* from supercop-20201130/crypto_sort/uint32/useint32/sort.c */
122
123
/* can save time by vectorizing xor loops */
124
/* can save time by integrating xor loops with int32_sort */
125
126
static void
127
crypto_sort_uint32 (void *array, long long n)
128
0
{
129
0
  uint32_t *x = array;
130
0
  long long j;
131
0
  for (j = 0; j < n; ++j)
132
0
    x[j] ^= 0x80000000;
133
0
  crypto_sort_int32 (array, n);
134
0
  for (j = 0; j < n; ++j)
135
0
    x[j] ^= 0x80000000;
136
0
}
137
138
/* from supercop-20201130/crypto_kem/sntrup761/ref/uint32.c */
139
140
/*
141
CPU division instruction typically takes time depending on x.
142
This software is designed to take time independent of x.
143
Time still varies depending on m; user must ensure that m is constant.
144
Time also varies on CPUs where multiplication is variable-time.
145
There could be more CPU issues.
146
There could also be compiler issues.
147
*/
148
149
static void
150
uint32_divmod_uint14 (uint32_t * q, uint16_t * r, uint32_t x, uint16_t m)
151
0
{
152
0
  uint32_t v = 0x80000000;
153
0
  uint32_t qpart;
154
0
  uint32_t mask;
155
156
0
  v /= m;
157
158
  /* caller guarantees m > 0 */
159
  /* caller guarantees m < 16384 */
160
  /* vm <= 2^31 <= vm+m-1 */
161
  /* xvm <= 2^31 x <= xvm+x(m-1) */
162
163
0
  *q = 0;
164
165
0
  qpart = (x * (uint64_t) v) >> 31;
166
  /* 2^31 qpart <= xv <= 2^31 qpart + 2^31-1 */
167
  /* 2^31 qpart m <= xvm <= 2^31 qpart m + (2^31-1)m */
168
  /* 2^31 qpart m <= 2^31 x <= 2^31 qpart m + (2^31-1)m + x(m-1) */
169
  /* 0 <= 2^31 newx <= (2^31-1)m + x(m-1) */
170
  /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
171
  /* 0 <= newx <= (1-1/2^31)(2^14-1) + (2^32-1)((2^14-1)-1)/2^31 */
172
173
0
  x -= qpart * m;
174
0
  *q += qpart;
175
  /* x <= 49146 */
176
177
0
  qpart = (x * (uint64_t) v) >> 31;
178
  /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
179
  /* 0 <= newx <= m + 49146(2^14-1)/2^31 */
180
  /* 0 <= newx <= m + 0.4 */
181
  /* 0 <= newx <= m */
182
183
0
  x -= qpart * m;
184
0
  *q += qpart;
185
  /* x <= m */
186
187
0
  x -= m;
188
0
  *q += 1;
189
0
  mask = -(x >> 31);
190
0
  x += mask & (uint32_t) m;
191
0
  *q += mask;
192
  /* x < m */
193
194
0
  *r = x;
195
0
}
196
197
198
static uint16_t
199
uint32_mod_uint14 (uint32_t x, uint16_t m)
200
0
{
201
0
  uint32_t q;
202
0
  uint16_t r;
203
0
  uint32_divmod_uint14 (&q, &r, x, m);
204
0
  return r;
205
0
}
206
207
/* from supercop-20201130/crypto_kem/sntrup761/ref/int32.c */
208
209
static void
210
int32_divmod_uint14 (int32_t * q, uint16_t * r, int32_t x, uint16_t m)
211
0
{
212
0
  uint32_t uq, uq2;
213
0
  uint16_t ur, ur2;
214
0
  uint32_t mask;
215
216
0
  uint32_divmod_uint14 (&uq, &ur, 0x80000000 + (uint32_t) x, m);
217
0
  uint32_divmod_uint14 (&uq2, &ur2, 0x80000000, m);
218
0
  ur -= ur2;
219
0
  uq -= uq2;
220
0
  mask = -(uint32_t) (ur >> 15);
221
0
  ur += mask & m;
222
0
  uq += mask;
223
0
  *r = ur;
224
0
  *q = uq;
225
0
}
226
227
228
static uint16_t
229
int32_mod_uint14 (int32_t x, uint16_t m)
230
0
{
231
0
  int32_t q;
232
0
  uint16_t r;
233
0
  int32_divmod_uint14 (&q, &r, x, m);
234
0
  return r;
235
0
}
236
237
/* from supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h */
238
0
#define p 761
239
0
#define q 4591
240
0
#define Rounded_bytes 1007
241
0
#define Rq_bytes 1158
242
0
#define w 286
243
244
/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.h */
245
246
/* Decode(R,s,M,len) */
247
/* assumes 0 < M[i] < 16384 */
248
/* produces 0 <= R[i] < M[i] */
249
250
/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.c */
251
252
static void
253
Decode (uint16_t * out, const unsigned char *S, const uint16_t * M,
254
  long long len)
255
0
{
256
0
  if (len == 1)
257
0
    {
258
0
      if (M[0] == 1)
259
0
  *out = 0;
260
0
      else if (M[0] <= 256)
261
0
  *out = uint32_mod_uint14 (S[0], M[0]);
262
0
      else
263
0
  *out = uint32_mod_uint14 (S[0] + (((uint16_t) S[1]) << 8), M[0]);
264
0
    }
265
0
  if (len > 1)
266
0
    {
267
0
      uint16_t R2[(MAX_LEN + 1) / 2];
268
0
      uint16_t M2[(MAX_LEN + 1) / 2];
269
0
      uint16_t bottomr[MAX_LEN / 2];
270
0
      uint32_t bottomt[MAX_LEN / 2];
271
0
      long long i;
272
0
      for (i = 0; i < len - 1; i += 2)
273
0
  {
274
0
    uint32_t m = M[i] * (uint32_t) M[i + 1];
275
0
    if (m > 256 * 16383)
276
0
      {
277
0
        bottomt[i / 2] = 256 * 256;
278
0
        bottomr[i / 2] = S[0] + 256 * S[1];
279
0
        S += 2;
280
0
        M2[i / 2] = (((m + 255) >> 8) + 255) >> 8;
281
0
      }
282
0
    else if (m >= 16384)
283
0
      {
284
0
        bottomt[i / 2] = 256;
285
0
        bottomr[i / 2] = S[0];
286
0
        S += 1;
287
0
        M2[i / 2] = (m + 255) >> 8;
288
0
      }
289
0
    else
290
0
      {
291
0
        bottomt[i / 2] = 1;
292
0
        bottomr[i / 2] = 0;
293
0
        M2[i / 2] = m;
294
0
      }
295
0
  }
296
0
      if (i < len)
297
0
  M2[i / 2] = M[i];
298
0
      Decode (R2, S, M2, (len + 1) / 2);
299
0
      for (i = 0; i < len - 1; i += 2)
300
0
  {
301
0
    uint32_t r = bottomr[i / 2];
302
0
    uint32_t r1;
303
0
    uint16_t r0;
304
0
    r += bottomt[i / 2] * R2[i / 2];
305
0
    uint32_divmod_uint14 (&r1, &r0, r, M[i]);
306
0
    r1 = uint32_mod_uint14 (r1, M[i + 1]);  /* only needed for invalid inputs */
307
0
    *out++ = r0;
308
0
    *out++ = r1;
309
0
  }
310
0
      if (i < len)
311
0
  *out++ = R2[i / 2];
312
0
    }
313
0
}
314
315
/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.h */
316
317
/* Encode(s,R,M,len) */
318
/* assumes 0 <= R[i] < M[i] < 16384 */
319
320
/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.c */
321
322
/* 0 <= R[i] < M[i] < 16384 */
323
static void
324
Encode (unsigned char *out, const uint16_t * R, const uint16_t * M,
325
  long long len)
326
0
{
327
0
  if (len == 1)
328
0
    {
329
0
      uint16_t r = R[0];
330
0
      uint16_t m = M[0];
331
0
      while (m > 1)
332
0
  {
333
0
    *out++ = r;
334
0
    r >>= 8;
335
0
    m = (m + 255) >> 8;
336
0
  }
337
0
    }
338
0
  if (len > 1)
339
0
    {
340
0
      uint16_t R2[(MAX_LEN + 1) / 2];
341
0
      uint16_t M2[(MAX_LEN + 1) / 2];
342
0
      long long i;
343
0
      for (i = 0; i < len - 1; i += 2)
344
0
  {
345
0
    uint32_t m0 = M[i];
346
0
    uint32_t r = R[i] + R[i + 1] * m0;
347
0
    uint32_t m = M[i + 1] * m0;
348
0
    while (m >= 16384)
349
0
      {
350
0
        *out++ = r;
351
0
        r >>= 8;
352
0
        m = (m + 255) >> 8;
353
0
      }
354
0
    R2[i / 2] = r;
355
0
    M2[i / 2] = m;
356
0
  }
357
0
      if (i < len)
358
0
  {
359
0
    R2[i / 2] = R[i];
360
0
    M2[i / 2] = M[i];
361
0
  }
362
0
      Encode (out, R2, M2, (len + 1) / 2);
363
0
    }
364
0
}
365
366
/* from supercop-20201130/crypto_kem/sntrup761/ref/kem.c */
367
368
/* ----- masks */
369
370
/* return -1 if x!=0; else return 0 */
371
static int
372
int16_t_nonzero_mask (int16_t x)
373
0
{
374
0
  uint16_t u = x;   /* 0, else 1...65535 */
375
0
  uint32_t v = u;   /* 0, else 1...65535 */
376
0
  v = -v;     /* 0, else 2^32-65535...2^32-1 */
377
0
  v >>= 31;     /* 0, else 1 */
378
0
  return -v;      /* 0, else -1 */
379
0
}
380
381
/* return -1 if x<0; otherwise return 0 */
382
static int
383
int16_t_negative_mask (int16_t x)
384
0
{
385
0
  uint16_t u = x;
386
0
  u >>= 15;
387
0
  return -(int) u;
388
  /* alternative with gcc -fwrapv: */
389
  /* x>>15 compiles to CPU's arithmetic right shift */
390
0
}
391
392
/* ----- arithmetic mod 3 */
393
394
typedef int8_t small;
395
396
/* F3 is always represented as -1,0,1 */
397
/* so ZZ_fromF3 is a no-op */
398
399
/* x must not be close to top int16_t */
400
static small
401
F3_freeze (int16_t x)
402
0
{
403
0
  return int32_mod_uint14 (x + 1, 3) - 1;
404
0
}
405
406
/* ----- arithmetic mod q */
407
408
0
#define q12 ((q-1)/2)
409
typedef int16_t Fq;
410
/* always represented as -q12...q12 */
411
/* so ZZ_fromFq is a no-op */
412
413
/* x must not be close to top int32 */
414
static Fq
415
Fq_freeze (int32_t x)
416
0
{
417
0
  return int32_mod_uint14 (x + q12, q) - q12;
418
0
}
419
420
static Fq
421
Fq_recip (Fq a1)
422
0
{
423
0
  int i = 1;
424
0
  Fq ai = a1;
425
426
0
  while (i < q - 2)
427
0
    {
428
0
      ai = Fq_freeze (a1 * (int32_t) ai);
429
0
      i += 1;
430
0
    }
431
0
  return ai;
432
0
}
433
434
/* ----- small polynomials */
435
436
/* 0 if Weightw_is(r), else -1 */
437
static int
438
Weightw_mask (small * r)
439
0
{
440
0
  int weight = 0;
441
0
  int i;
442
443
0
  for (i = 0; i < p; ++i)
444
0
    weight += r[i] & 1;
445
0
  return int16_t_nonzero_mask (weight - w);
446
0
}
447
448
/* R3_fromR(R_fromRq(r)) */
449
static void
450
R3_fromRq (small * out, const Fq * r)
451
0
{
452
0
  int i;
453
0
  for (i = 0; i < p; ++i)
454
0
    out[i] = F3_freeze (r[i]);
455
0
}
456
457
/* h = f*g in the ring R3 */
458
static void
459
R3_mult (small * h, const small * f, const small * g)
460
0
{
461
0
  small fg[p + p - 1];
462
0
  small result;
463
0
  int i, j;
464
465
0
  for (i = 0; i < p; ++i)
466
0
    {
467
0
      result = 0;
468
0
      for (j = 0; j <= i; ++j)
469
0
  result = F3_freeze (result + f[j] * g[i - j]);
470
0
      fg[i] = result;
471
0
    }
472
0
  for (i = p; i < p + p - 1; ++i)
473
0
    {
474
0
      result = 0;
475
0
      for (j = i - p + 1; j < p; ++j)
476
0
  result = F3_freeze (result + f[j] * g[i - j]);
477
0
      fg[i] = result;
478
0
    }
479
480
0
  for (i = p + p - 2; i >= p; --i)
481
0
    {
482
0
      fg[i - p] = F3_freeze (fg[i - p] + fg[i]);
483
0
      fg[i - p + 1] = F3_freeze (fg[i - p + 1] + fg[i]);
484
0
    }
485
486
0
  for (i = 0; i < p; ++i)
487
0
    h[i] = fg[i];
488
0
}
489
490
/* returns 0 if recip succeeded; else -1 */
491
static int
492
R3_recip (small * out, const small * in)
493
0
{
494
0
  small f[p + 1], g[p + 1], v[p + 1], r[p + 1];
495
0
  int i, loop, delta;
496
0
  int sign, swap, t;
497
498
0
  for (i = 0; i < p + 1; ++i)
499
0
    v[i] = 0;
500
0
  for (i = 0; i < p + 1; ++i)
501
0
    r[i] = 0;
502
0
  r[0] = 1;
503
0
  for (i = 0; i < p; ++i)
504
0
    f[i] = 0;
505
0
  f[0] = 1;
506
0
  f[p - 1] = f[p] = -1;
507
0
  for (i = 0; i < p; ++i)
508
0
    g[p - 1 - i] = in[i];
509
0
  g[p] = 0;
510
511
0
  delta = 1;
512
513
0
  for (loop = 0; loop < 2 * p - 1; ++loop)
514
0
    {
515
0
      for (i = p; i > 0; --i)
516
0
  v[i] = v[i - 1];
517
0
      v[0] = 0;
518
519
0
      sign = -g[0] * f[0];
520
0
      swap = int16_t_negative_mask (-delta) & int16_t_nonzero_mask (g[0]);
521
0
      delta ^= swap & (delta ^ -delta);
522
0
      delta += 1;
523
524
0
      for (i = 0; i < p + 1; ++i)
525
0
  {
526
0
    t = swap & (f[i] ^ g[i]);
527
0
    f[i] ^= t;
528
0
    g[i] ^= t;
529
0
    t = swap & (v[i] ^ r[i]);
530
0
    v[i] ^= t;
531
0
    r[i] ^= t;
532
0
  }
533
534
0
      for (i = 0; i < p + 1; ++i)
535
0
  g[i] = F3_freeze (g[i] + sign * f[i]);
536
0
      for (i = 0; i < p + 1; ++i)
537
0
  r[i] = F3_freeze (r[i] + sign * v[i]);
538
539
0
      for (i = 0; i < p; ++i)
540
0
  g[i] = g[i + 1];
541
0
      g[p] = 0;
542
0
    }
543
544
0
  sign = f[0];
545
0
  for (i = 0; i < p; ++i)
546
0
    out[i] = sign * v[p - 1 - i];
547
548
0
  return int16_t_nonzero_mask (delta);
549
0
}
550
551
/* ----- polynomials mod q */
552
553
/* h = f*g in the ring Rq */
554
static void
555
Rq_mult_small (Fq * h, const Fq * f, const small * g)
556
0
{
557
0
  Fq fg[p + p - 1];
558
0
  Fq result;
559
0
  int i, j;
560
561
0
  for (i = 0; i < p; ++i)
562
0
    {
563
0
      result = 0;
564
0
      for (j = 0; j <= i; ++j)
565
0
  result = Fq_freeze (result + f[j] * (int32_t) g[i - j]);
566
0
      fg[i] = result;
567
0
    }
568
0
  for (i = p; i < p + p - 1; ++i)
569
0
    {
570
0
      result = 0;
571
0
      for (j = i - p + 1; j < p; ++j)
572
0
  result = Fq_freeze (result + f[j] * (int32_t) g[i - j]);
573
0
      fg[i] = result;
574
0
    }
575
576
0
  for (i = p + p - 2; i >= p; --i)
577
0
    {
578
0
      fg[i - p] = Fq_freeze (fg[i - p] + fg[i]);
579
0
      fg[i - p + 1] = Fq_freeze (fg[i - p + 1] + fg[i]);
580
0
    }
581
582
0
  for (i = 0; i < p; ++i)
583
0
    h[i] = fg[i];
584
0
}
585
586
/* h = 3f in Rq */
587
static void
588
Rq_mult3 (Fq * h, const Fq * f)
589
0
{
590
0
  int i;
591
592
0
  for (i = 0; i < p; ++i)
593
0
    h[i] = Fq_freeze (3 * f[i]);
594
0
}
595
596
/* out = 1/(3*in) in Rq */
597
/* returns 0 if recip succeeded; else -1 */
598
static int
599
Rq_recip3 (Fq * out, const small * in)
600
0
{
601
0
  Fq f[p + 1], g[p + 1], v[p + 1], r[p + 1];
602
0
  int i, loop, delta;
603
0
  int swap, t;
604
0
  int32_t f0, g0;
605
0
  Fq scale;
606
607
0
  for (i = 0; i < p + 1; ++i)
608
0
    v[i] = 0;
609
0
  for (i = 0; i < p + 1; ++i)
610
0
    r[i] = 0;
611
0
  r[0] = Fq_recip (3);
612
0
  for (i = 0; i < p; ++i)
613
0
    f[i] = 0;
614
0
  f[0] = 1;
615
0
  f[p - 1] = f[p] = -1;
616
0
  for (i = 0; i < p; ++i)
617
0
    g[p - 1 - i] = in[i];
618
0
  g[p] = 0;
619
620
0
  delta = 1;
621
622
0
  for (loop = 0; loop < 2 * p - 1; ++loop)
623
0
    {
624
0
      for (i = p; i > 0; --i)
625
0
  v[i] = v[i - 1];
626
0
      v[0] = 0;
627
628
0
      swap = int16_t_negative_mask (-delta) & int16_t_nonzero_mask (g[0]);
629
0
      delta ^= swap & (delta ^ -delta);
630
0
      delta += 1;
631
632
0
      for (i = 0; i < p + 1; ++i)
633
0
  {
634
0
    t = swap & (f[i] ^ g[i]);
635
0
    f[i] ^= t;
636
0
    g[i] ^= t;
637
0
    t = swap & (v[i] ^ r[i]);
638
0
    v[i] ^= t;
639
0
    r[i] ^= t;
640
0
  }
641
642
0
      f0 = f[0];
643
0
      g0 = g[0];
644
0
      for (i = 0; i < p + 1; ++i)
645
0
  g[i] = Fq_freeze (f0 * g[i] - g0 * f[i]);
646
0
      for (i = 0; i < p + 1; ++i)
647
0
  r[i] = Fq_freeze (f0 * r[i] - g0 * v[i]);
648
649
0
      for (i = 0; i < p; ++i)
650
0
  g[i] = g[i + 1];
651
0
      g[p] = 0;
652
0
    }
653
654
0
  scale = Fq_recip (f[0]);
655
0
  for (i = 0; i < p; ++i)
656
0
    out[i] = Fq_freeze (scale * (int32_t) v[p - 1 - i]);
657
658
0
  return int16_t_nonzero_mask (delta);
659
0
}
660
661
/* ----- rounded polynomials mod q */
662
663
static void
664
Round (Fq * out, const Fq * a)
665
0
{
666
0
  int i;
667
0
  for (i = 0; i < p; ++i)
668
0
    out[i] = a[i] - F3_freeze (a[i]);
669
0
}
670
671
/* ----- sorting to generate short polynomial */
672
673
static void
674
Short_fromlist (small * out, const uint32_t * in)
675
0
{
676
0
  uint32_t L[p];
677
0
  int i;
678
679
0
  for (i = 0; i < w; ++i)
680
0
    L[i] = in[i] & (uint32_t) - 2;
681
0
  for (i = w; i < p; ++i)
682
0
    L[i] = (in[i] & (uint32_t) - 3) | 1;
683
0
  crypto_sort_uint32 (L, p);
684
0
  for (i = 0; i < p; ++i)
685
0
    out[i] = (L[i] & 3) - 1;
686
0
}
687
688
/* ----- underlying hash function */
689
690
0
#define Hash_bytes 32
691
692
/* e.g., b = 0 means out = Hash0(in) */
693
static void
694
Hash_prefix (unsigned char *out, int b, const unsigned char *in, int inlen)
695
0
{
696
0
#define MAX_X_LEN 1158
697
0
  unsigned char x[MAX_X_LEN + 1];
698
0
  unsigned char h[64];
699
0
  int i;
700
701
0
  x[0] = b;
702
0
  for (i = 0; i < inlen; ++i)
703
0
    x[i + 1] = in[i];
704
0
  crypto_hash_sha512 (h, x, inlen + 1);
705
0
  for (i = 0; i < 32; ++i)
706
0
    out[i] = h[i];
707
0
}
708
709
/* ----- higher-level randomness */
710
711
static uint32_t
712
urandom32 (void *random_ctx, sntrup761_random_func * random)
713
0
{
714
0
  unsigned char c[4];
715
0
  uint32_t out[4];
716
717
0
  random (random_ctx, 4, c);
718
0
  out[0] = (uint32_t) c[0];
719
0
  out[1] = ((uint32_t) c[1]) << 8;
720
0
  out[2] = ((uint32_t) c[2]) << 16;
721
0
  out[3] = ((uint32_t) c[3]) << 24;
722
0
  return out[0] + out[1] + out[2] + out[3];
723
0
}
724
725
static void
726
Short_random (small * out, void *random_ctx, sntrup761_random_func * random)
727
0
{
728
0
  uint32_t L[p];
729
0
  int i;
730
731
0
  for (i = 0; i < p; ++i)
732
0
    L[i] = urandom32 (random_ctx, random);
733
0
  Short_fromlist (out, L);
734
0
}
735
736
static void
737
Small_random (small * out, void *random_ctx, sntrup761_random_func * random)
738
0
{
739
0
  int i;
740
741
0
  for (i = 0; i < p; ++i)
742
0
    out[i] = (((urandom32 (random_ctx, random) & 0x3fffffff) * 3) >> 30) - 1;
743
0
}
744
745
/* ----- Streamlined NTRU Prime Core */
746
747
/* h,(f,ginv) = KeyGen() */
748
static void
749
KeyGen (Fq * h, small * f, small * ginv, void *random_ctx,
750
  sntrup761_random_func * random)
751
0
{
752
0
  small g[p];
753
0
  Fq finv[p];
754
755
0
  for (;;)
756
0
    {
757
0
      Small_random (g, random_ctx, random);
758
0
      if (R3_recip (ginv, g) == 0)
759
0
  break;
760
0
    }
761
0
  Short_random (f, random_ctx, random);
762
0
  Rq_recip3 (finv, f);    /* always works */
763
0
  Rq_mult_small (h, finv, g);
764
0
}
765
766
/* c = Encrypt(r,h) */
767
static void
768
Encrypt (Fq * c, const small * r, const Fq * h)
769
0
{
770
0
  Fq hr[p];
771
772
0
  Rq_mult_small (hr, h, r);
773
0
  Round (c, hr);
774
0
}
775
776
/* r = Decrypt(c,(f,ginv)) */
777
static void
778
Decrypt (small * r, const Fq * c, const small * f, const small * ginv)
779
0
{
780
0
  Fq cf[p];
781
0
  Fq cf3[p];
782
0
  small e[p];
783
0
  small ev[p];
784
0
  int mask;
785
0
  int i;
786
787
0
  Rq_mult_small (cf, c, f);
788
0
  Rq_mult3 (cf3, cf);
789
0
  R3_fromRq (e, cf3);
790
0
  R3_mult (ev, e, ginv);
791
792
0
  mask = Weightw_mask (ev); /* 0 if weight w, else -1 */
793
0
  for (i = 0; i < w; ++i)
794
0
    r[i] = ((ev[i] ^ 1) & ~mask) ^ 1;
795
0
  for (i = w; i < p; ++i)
796
0
    r[i] = ev[i] & ~mask;
797
0
}
798
799
/* ----- encoding small polynomials (including short polynomials) */
800
801
0
#define Small_bytes ((p+3)/4)
802
803
/* these are the only functions that rely on p mod 4 = 1 */
804
805
static void
806
Small_encode (unsigned char *s, const small * f)
807
0
{
808
0
  small x;
809
0
  int i;
810
811
0
  for (i = 0; i < p / 4; ++i)
812
0
    {
813
0
      x = *f++ + 1;
814
0
      x += (*f++ + 1) << 2;
815
0
      x += (*f++ + 1) << 4;
816
0
      x += (*f++ + 1) << 6;
817
0
      *s++ = x;
818
0
    }
819
0
  x = *f++ + 1;
820
0
  *s++ = x;
821
0
}
822
823
static void
824
Small_decode (small * f, const unsigned char *s)
825
0
{
826
0
  unsigned char x;
827
0
  int i;
828
829
0
  for (i = 0; i < p / 4; ++i)
830
0
    {
831
0
      x = *s++;
832
0
      *f++ = ((small) (x & 3)) - 1;
833
0
      x >>= 2;
834
0
      *f++ = ((small) (x & 3)) - 1;
835
0
      x >>= 2;
836
0
      *f++ = ((small) (x & 3)) - 1;
837
0
      x >>= 2;
838
0
      *f++ = ((small) (x & 3)) - 1;
839
0
    }
840
0
  x = *s++;
841
0
  *f++ = ((small) (x & 3)) - 1;
842
0
}
843
844
/* ----- encoding general polynomials */
845
846
static void
847
Rq_encode (unsigned char *s, const Fq * r)
848
0
{
849
0
  uint16_t R[p], M[p];
850
0
  int i;
851
852
0
  for (i = 0; i < p; ++i)
853
0
    R[i] = r[i] + q12;
854
0
  for (i = 0; i < p; ++i)
855
0
    M[i] = q;
856
0
  Encode (s, R, M, p);
857
0
}
858
859
static void
860
Rq_decode (Fq * r, const unsigned char *s)
861
0
{
862
0
  uint16_t R[p], M[p];
863
0
  int i;
864
865
0
  for (i = 0; i < p; ++i)
866
0
    M[i] = q;
867
0
  Decode (R, s, M, p);
868
0
  for (i = 0; i < p; ++i)
869
0
    r[i] = ((Fq) R[i]) - q12;
870
0
}
871
872
/* ----- encoding rounded polynomials */
873
874
static void
875
Rounded_encode (unsigned char *s, const Fq * r)
876
0
{
877
0
  uint16_t R[p], M[p];
878
0
  int i;
879
880
0
  for (i = 0; i < p; ++i)
881
0
    R[i] = ((r[i] + q12) * 10923) >> 15;
882
0
  for (i = 0; i < p; ++i)
883
0
    M[i] = (q + 2) / 3;
884
0
  Encode (s, R, M, p);
885
0
}
886
887
static void
888
Rounded_decode (Fq * r, const unsigned char *s)
889
0
{
890
0
  uint16_t R[p], M[p];
891
0
  int i;
892
893
0
  for (i = 0; i < p; ++i)
894
0
    M[i] = (q + 2) / 3;
895
0
  Decode (R, s, M, p);
896
0
  for (i = 0; i < p; ++i)
897
0
    r[i] = R[i] * 3 - q12;
898
0
}
899
900
/* ----- Streamlined NTRU Prime Core plus encoding */
901
902
typedef small Inputs[p];  /* passed by reference */
903
0
#define Inputs_random Short_random
904
0
#define Inputs_encode Small_encode
905
0
#define Inputs_bytes Small_bytes
906
907
0
#define Ciphertexts_bytes Rounded_bytes
908
0
#define SecretKeys_bytes (2*Small_bytes)
909
0
#define PublicKeys_bytes Rq_bytes
910
911
/* pk,sk = ZKeyGen() */
912
static void
913
ZKeyGen (unsigned char *pk, unsigned char *sk, void *random_ctx,
914
   sntrup761_random_func * random)
915
0
{
916
0
  Fq h[p];
917
0
  small f[p], v[p];
918
919
0
  KeyGen (h, f, v, random_ctx, random);
920
0
  Rq_encode (pk, h);
921
0
  Small_encode (sk, f);
922
0
  sk += Small_bytes;
923
0
  Small_encode (sk, v);
924
0
}
925
926
/* C = ZEncrypt(r,pk) */
927
static void
928
ZEncrypt (unsigned char *C, const Inputs r, const unsigned char *pk)
929
0
{
930
0
  Fq h[p];
931
0
  Fq c[p];
932
0
  Rq_decode (h, pk);
933
0
  Encrypt (c, r, h);
934
0
  Rounded_encode (C, c);
935
0
}
936
937
/* r = ZDecrypt(C,sk) */
938
static void
939
ZDecrypt (Inputs r, const unsigned char *C, const unsigned char *sk)
940
0
{
941
0
  small f[p], v[p];
942
0
  Fq c[p];
943
944
0
  Small_decode (f, sk);
945
0
  sk += Small_bytes;
946
0
  Small_decode (v, sk);
947
0
  Rounded_decode (c, C);
948
0
  Decrypt (r, c, f, v);
949
0
}
950
951
/* ----- confirmation hash */
952
953
0
#define Confirm_bytes 32
954
955
/* h = HashConfirm(r,pk,cache); cache is Hash4(pk) */
956
static void
957
HashConfirm (unsigned char *h, const unsigned char *r,
958
       /* const unsigned char *pk, */ const unsigned char *cache)
959
0
{
960
0
  unsigned char x[Hash_bytes * 2];
961
0
  int i;
962
963
0
  Hash_prefix (x, 3, r, Inputs_bytes);
964
0
  for (i = 0; i < Hash_bytes; ++i)
965
0
    x[Hash_bytes + i] = cache[i];
966
0
  Hash_prefix (h, 2, x, sizeof x);
967
0
}
968
969
/* ----- session-key hash */
970
971
/* k = HashSession(b,y,z) */
972
static void
973
HashSession (unsigned char *k, int b, const unsigned char *y,
974
       const unsigned char *z)
975
0
{
976
0
  unsigned char x[Hash_bytes + Ciphertexts_bytes + Confirm_bytes];
977
0
  int i;
978
979
0
  Hash_prefix (x, 3, y, Inputs_bytes);
980
0
  for (i = 0; i < Ciphertexts_bytes + Confirm_bytes; ++i)
981
0
    x[Hash_bytes + i] = z[i];
982
0
  Hash_prefix (k, b, x, sizeof x);
983
0
}
984
985
/* ----- Streamlined NTRU Prime */
986
987
/* pk,sk = KEM_KeyGen() */
988
void
989
sntrup761_keypair (unsigned char *pk, unsigned char *sk, void *random_ctx,
990
       sntrup761_random_func * random)
991
0
{
992
0
  int i;
993
994
0
  ZKeyGen (pk, sk, random_ctx, random);
995
0
  sk += SecretKeys_bytes;
996
0
  for (i = 0; i < PublicKeys_bytes; ++i)
997
0
    *sk++ = pk[i];
998
0
  random (random_ctx, Inputs_bytes, sk);
999
0
  sk += Inputs_bytes;
1000
0
  Hash_prefix (sk, 4, pk, PublicKeys_bytes);
1001
0
}
1002
1003
/* c,r_enc = Hide(r,pk,cache); cache is Hash4(pk) */
1004
static void
1005
Hide (unsigned char *c, unsigned char *r_enc, const Inputs r,
1006
      const unsigned char *pk, const unsigned char *cache)
1007
0
{
1008
0
  Inputs_encode (r_enc, r);
1009
0
  ZEncrypt (c, r, pk);
1010
0
  c += Ciphertexts_bytes;
1011
0
  HashConfirm (c, r_enc, cache);
1012
0
}
1013
1014
/* c,k = Encap(pk) */
1015
void
1016
sntrup761_enc (unsigned char *c, unsigned char *k, const unsigned char *pk,
1017
         void *random_ctx, sntrup761_random_func * random)
1018
0
{
1019
0
  Inputs r;
1020
0
  unsigned char r_enc[Inputs_bytes];
1021
0
  unsigned char cache[Hash_bytes];
1022
1023
0
  Hash_prefix (cache, 4, pk, PublicKeys_bytes);
1024
0
  Inputs_random (r, random_ctx, random);
1025
0
  Hide (c, r_enc, r, pk, cache);
1026
0
  HashSession (k, 1, r_enc, c);
1027
0
}
1028
1029
/* 0 if matching ciphertext+confirm, else -1 */
1030
static int
1031
Ciphertexts_diff_mask (const unsigned char *c, const unsigned char *c2)
1032
0
{
1033
0
  uint16_t differentbits = 0;
1034
0
  int len = Ciphertexts_bytes + Confirm_bytes;
1035
1036
0
  while (len-- > 0)
1037
0
    differentbits |= (*c++) ^ (*c2++);
1038
0
  return (1 & ((differentbits - 1) >> 8)) - 1;
1039
0
}
1040
1041
/* k = Decap(c,sk) */
1042
void
1043
sntrup761_dec (unsigned char *k, const unsigned char *c, const unsigned char *sk)
1044
0
{
1045
0
  const unsigned char *pk = sk + SecretKeys_bytes;
1046
0
  const unsigned char *rho = pk + PublicKeys_bytes;
1047
0
  const unsigned char *cache = rho + Inputs_bytes;
1048
0
  Inputs r;
1049
0
  unsigned char r_enc[Inputs_bytes];
1050
0
  unsigned char cnew[Ciphertexts_bytes + Confirm_bytes];
1051
0
  int mask;
1052
0
  int i;
1053
1054
0
  ZDecrypt (r, c, sk);
1055
0
  Hide (cnew, r_enc, r, pk, cache);
1056
0
  mask = Ciphertexts_diff_mask (c, cnew);
1057
0
  for (i = 0; i < Inputs_bytes; ++i)
1058
0
    r_enc[i] ^= mask & (r_enc[i] ^ rho[i]);
1059
0
  HashSession (k, 1 + mask, r_enc, c);
1060
0
}