Coverage Report

Created: 2026-05-30 06:08

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