Home | History | Annotate | Line # | Download | only in dist
sntrup761.c revision 1.1
      1  1.1  christos /*  $OpenBSD: sntrup761.c,v 1.5 2021/01/08 02:33:13 dtucker Exp $ */
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Public Domain, Authors:
      5  1.1  christos  * - Daniel J. Bernstein
      6  1.1  christos  * - Chitchanok Chuengsatiansup
      7  1.1  christos  * - Tanja Lange
      8  1.1  christos  * - Christine van Vredendaal
      9  1.1  christos  */
     10  1.1  christos 
     11  1.1  christos #include <string.h>
     12  1.1  christos #include "crypto_api.h"
     13  1.1  christos 
     14  1.1  christos #define int8 crypto_int8
     15  1.1  christos #define uint8 crypto_uint8
     16  1.1  christos #define int16 crypto_int16
     17  1.1  christos #define uint16 crypto_uint16
     18  1.1  christos #define int32 crypto_int32
     19  1.1  christos #define uint32 crypto_uint32
     20  1.1  christos #define int64 crypto_int64
     21  1.1  christos #define uint64 crypto_uint64
     22  1.1  christos 
     23  1.1  christos /* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */
     24  1.1  christos #define int32_MINMAX(a,b) \
     25  1.1  christos do { \
     26  1.1  christos   int64_t ab = (int64_t)b ^ (int64_t)a; \
     27  1.1  christos   int64_t c = (int64_t)b - (int64_t)a; \
     28  1.1  christos   c ^= ab & (c ^ b); \
     29  1.1  christos   c >>= 31; \
     30  1.1  christos   c &= ab; \
     31  1.1  christos   a ^= c; \
     32  1.1  christos   b ^= c; \
     33  1.1  christos } while(0)
     34  1.1  christos 
     35  1.1  christos /* from supercop-20201130/crypto_sort/int32/portable4/sort.c */
     36  1.1  christos 
     37  1.1  christos 
     38  1.1  christos static void crypto_sort_int32(void *array,long long n)
     39  1.1  christos {
     40  1.1  christos   long long top,p,q,r,i,j;
     41  1.1  christos   int32 *x = array;
     42  1.1  christos 
     43  1.1  christos   if (n < 2) return;
     44  1.1  christos   top = 1;
     45  1.1  christos   while (top < n - top) top += top;
     46  1.1  christos 
     47  1.1  christos   for (p = top;p >= 1;p >>= 1) {
     48  1.1  christos     i = 0;
     49  1.1  christos     while (i + 2 * p <= n) {
     50  1.1  christos       for (j = i;j < i + p;++j)
     51  1.1  christos         int32_MINMAX(x[j],x[j+p]);
     52  1.1  christos       i += 2 * p;
     53  1.1  christos     }
     54  1.1  christos     for (j = i;j < n - p;++j)
     55  1.1  christos       int32_MINMAX(x[j],x[j+p]);
     56  1.1  christos 
     57  1.1  christos     i = 0;
     58  1.1  christos     j = 0;
     59  1.1  christos     for (q = top;q > p;q >>= 1) {
     60  1.1  christos       if (j != i) for (;;) {
     61  1.1  christos         if (j == n - q) goto done;
     62  1.1  christos         int32 a = x[j + p];
     63  1.1  christos         for (r = q;r > p;r >>= 1)
     64  1.1  christos           int32_MINMAX(a,x[j + r]);
     65  1.1  christos         x[j + p] = a;
     66  1.1  christos         ++j;
     67  1.1  christos         if (j == i + p) {
     68  1.1  christos           i += 2 * p;
     69  1.1  christos           break;
     70  1.1  christos         }
     71  1.1  christos       }
     72  1.1  christos       while (i + p <= n - q) {
     73  1.1  christos         for (j = i;j < i + p;++j) {
     74  1.1  christos           int32 a = x[j + p];
     75  1.1  christos           for (r = q;r > p;r >>= 1)
     76  1.1  christos             int32_MINMAX(a,x[j+r]);
     77  1.1  christos           x[j + p] = a;
     78  1.1  christos         }
     79  1.1  christos         i += 2 * p;
     80  1.1  christos       }
     81  1.1  christos       /* now i + p > n - q */
     82  1.1  christos       j = i;
     83  1.1  christos       while (j < n - q) {
     84  1.1  christos         int32 a = x[j + p];
     85  1.1  christos         for (r = q;r > p;r >>= 1)
     86  1.1  christos           int32_MINMAX(a,x[j+r]);
     87  1.1  christos         x[j + p] = a;
     88  1.1  christos         ++j;
     89  1.1  christos       }
     90  1.1  christos 
     91  1.1  christos       done: ;
     92  1.1  christos     }
     93  1.1  christos   }
     94  1.1  christos }
     95  1.1  christos 
     96  1.1  christos /* from supercop-20201130/crypto_sort/uint32/useint32/sort.c */
     97  1.1  christos 
     98  1.1  christos /* can save time by vectorizing xor loops */
     99  1.1  christos /* can save time by integrating xor loops with int32_sort */
    100  1.1  christos 
    101  1.1  christos static void crypto_sort_uint32(void *array,long long n)
    102  1.1  christos {
    103  1.1  christos   crypto_uint32 *x = array;
    104  1.1  christos   long long j;
    105  1.1  christos   for (j = 0;j < n;++j) x[j] ^= 0x80000000;
    106  1.1  christos   crypto_sort_int32(array,n);
    107  1.1  christos   for (j = 0;j < n;++j) x[j] ^= 0x80000000;
    108  1.1  christos }
    109  1.1  christos 
    110  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/uint32.c */
    111  1.1  christos 
    112  1.1  christos /*
    113  1.1  christos CPU division instruction typically takes time depending on x.
    114  1.1  christos This software is designed to take time independent of x.
    115  1.1  christos Time still varies depending on m; user must ensure that m is constant.
    116  1.1  christos Time also varies on CPUs where multiplication is variable-time.
    117  1.1  christos There could be more CPU issues.
    118  1.1  christos There could also be compiler issues.
    119  1.1  christos */
    120  1.1  christos 
    121  1.1  christos static void uint32_divmod_uint14(uint32 *q,uint16 *r,uint32 x,uint16 m)
    122  1.1  christos {
    123  1.1  christos   uint32 v = 0x80000000;
    124  1.1  christos   uint32 qpart;
    125  1.1  christos   uint32 mask;
    126  1.1  christos 
    127  1.1  christos   v /= m;
    128  1.1  christos 
    129  1.1  christos   /* caller guarantees m > 0 */
    130  1.1  christos   /* caller guarantees m < 16384 */
    131  1.1  christos   /* vm <= 2^31 <= vm+m-1 */
    132  1.1  christos   /* xvm <= 2^31 x <= xvm+x(m-1) */
    133  1.1  christos 
    134  1.1  christos   *q = 0;
    135  1.1  christos 
    136  1.1  christos   qpart = (x*(uint64)v)>>31;
    137  1.1  christos   /* 2^31 qpart <= xv <= 2^31 qpart + 2^31-1 */
    138  1.1  christos   /* 2^31 qpart m <= xvm <= 2^31 qpart m + (2^31-1)m */
    139  1.1  christos   /* 2^31 qpart m <= 2^31 x <= 2^31 qpart m + (2^31-1)m + x(m-1) */
    140  1.1  christos   /* 0 <= 2^31 newx <= (2^31-1)m + x(m-1) */
    141  1.1  christos   /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
    142  1.1  christos   /* 0 <= newx <= (1-1/2^31)(2^14-1) + (2^32-1)((2^14-1)-1)/2^31 */
    143  1.1  christos 
    144  1.1  christos   x -= qpart*m; *q += qpart;
    145  1.1  christos   /* x <= 49146 */
    146  1.1  christos 
    147  1.1  christos   qpart = (x*(uint64)v)>>31;
    148  1.1  christos   /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */
    149  1.1  christos   /* 0 <= newx <= m + 49146(2^14-1)/2^31 */
    150  1.1  christos   /* 0 <= newx <= m + 0.4 */
    151  1.1  christos   /* 0 <= newx <= m */
    152  1.1  christos 
    153  1.1  christos   x -= qpart*m; *q += qpart;
    154  1.1  christos   /* x <= m */
    155  1.1  christos 
    156  1.1  christos   x -= m; *q += 1;
    157  1.1  christos   mask = -(x>>31);
    158  1.1  christos   x += mask&(uint32)m; *q += mask;
    159  1.1  christos   /* x < m */
    160  1.1  christos 
    161  1.1  christos   *r = x;
    162  1.1  christos }
    163  1.1  christos 
    164  1.1  christos 
    165  1.1  christos static uint16 uint32_mod_uint14(uint32 x,uint16 m)
    166  1.1  christos {
    167  1.1  christos   uint32 q;
    168  1.1  christos   uint16 r;
    169  1.1  christos   uint32_divmod_uint14(&q,&r,x,m);
    170  1.1  christos   return r;
    171  1.1  christos }
    172  1.1  christos 
    173  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/int32.c */
    174  1.1  christos 
    175  1.1  christos static void int32_divmod_uint14(int32 *q,uint16 *r,int32 x,uint16 m)
    176  1.1  christos {
    177  1.1  christos   uint32 uq,uq2;
    178  1.1  christos   uint16 ur,ur2;
    179  1.1  christos   uint32 mask;
    180  1.1  christos 
    181  1.1  christos   uint32_divmod_uint14(&uq,&ur,0x80000000+(uint32)x,m);
    182  1.1  christos   uint32_divmod_uint14(&uq2,&ur2,0x80000000,m);
    183  1.1  christos   ur -= ur2; uq -= uq2;
    184  1.1  christos   mask = -(uint32)(ur>>15);
    185  1.1  christos   ur += mask&m; uq += mask;
    186  1.1  christos   *r = ur; *q = uq;
    187  1.1  christos }
    188  1.1  christos 
    189  1.1  christos 
    190  1.1  christos static uint16 int32_mod_uint14(int32 x,uint16 m)
    191  1.1  christos {
    192  1.1  christos   int32 q;
    193  1.1  christos   uint16 r;
    194  1.1  christos   int32_divmod_uint14(&q,&r,x,m);
    195  1.1  christos   return r;
    196  1.1  christos }
    197  1.1  christos 
    198  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h */
    199  1.1  christos /* pick one of these three: */
    200  1.1  christos #define SIZE761
    201  1.1  christos #undef SIZE653
    202  1.1  christos #undef SIZE857
    203  1.1  christos 
    204  1.1  christos /* pick one of these two: */
    205  1.1  christos #define SNTRUP /* Streamlined NTRU Prime */
    206  1.1  christos #undef LPR /* NTRU LPRime */
    207  1.1  christos 
    208  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/params.h */
    209  1.1  christos #ifndef params_H
    210  1.1  christos #define params_H
    211  1.1  christos 
    212  1.1  christos /* menu of parameter choices: */
    213  1.1  christos 
    214  1.1  christos 
    215  1.1  christos /* what the menu means: */
    216  1.1  christos 
    217  1.1  christos #if defined(SIZE761)
    218  1.1  christos #define p 761
    219  1.1  christos #define q 4591
    220  1.1  christos #define Rounded_bytes 1007
    221  1.1  christos #ifndef LPR
    222  1.1  christos #define Rq_bytes 1158
    223  1.1  christos #define w 286
    224  1.1  christos #else
    225  1.1  christos #define w 250
    226  1.1  christos #define tau0 2156
    227  1.1  christos #define tau1 114
    228  1.1  christos #define tau2 2007
    229  1.1  christos #define tau3 287
    230  1.1  christos #endif
    231  1.1  christos 
    232  1.1  christos #elif defined(SIZE653)
    233  1.1  christos #define p 653
    234  1.1  christos #define q 4621
    235  1.1  christos #define Rounded_bytes 865
    236  1.1  christos #ifndef LPR
    237  1.1  christos #define Rq_bytes 994
    238  1.1  christos #define w 288
    239  1.1  christos #else
    240  1.1  christos #define w 252
    241  1.1  christos #define tau0 2175
    242  1.1  christos #define tau1 113
    243  1.1  christos #define tau2 2031
    244  1.1  christos #define tau3 290
    245  1.1  christos #endif
    246  1.1  christos 
    247  1.1  christos #elif defined(SIZE857)
    248  1.1  christos #define p 857
    249  1.1  christos #define q 5167
    250  1.1  christos #define Rounded_bytes 1152
    251  1.1  christos #ifndef LPR
    252  1.1  christos #define Rq_bytes 1322
    253  1.1  christos #define w 322
    254  1.1  christos #else
    255  1.1  christos #define w 281
    256  1.1  christos #define tau0 2433
    257  1.1  christos #define tau1 101
    258  1.1  christos #define tau2 2265
    259  1.1  christos #define tau3 324
    260  1.1  christos #endif
    261  1.1  christos 
    262  1.1  christos #else
    263  1.1  christos #error "no parameter set defined"
    264  1.1  christos #endif
    265  1.1  christos 
    266  1.1  christos #ifdef LPR
    267  1.1  christos #define I 256
    268  1.1  christos #endif
    269  1.1  christos 
    270  1.1  christos #endif
    271  1.1  christos 
    272  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.h */
    273  1.1  christos #ifndef Decode_H
    274  1.1  christos #define Decode_H
    275  1.1  christos 
    276  1.1  christos 
    277  1.1  christos /* Decode(R,s,M,len) */
    278  1.1  christos /* assumes 0 < M[i] < 16384 */
    279  1.1  christos /* produces 0 <= R[i] < M[i] */
    280  1.1  christos 
    281  1.1  christos #endif
    282  1.1  christos 
    283  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.c */
    284  1.1  christos 
    285  1.1  christos static void Decode(uint16 *out,const unsigned char *S,const uint16 *M,long long len)
    286  1.1  christos {
    287  1.1  christos   if (len == 1) {
    288  1.1  christos     if (M[0] == 1)
    289  1.1  christos       *out = 0;
    290  1.1  christos     else if (M[0] <= 256)
    291  1.1  christos       *out = uint32_mod_uint14(S[0],M[0]);
    292  1.1  christos     else
    293  1.1  christos       *out = uint32_mod_uint14(S[0]+(((uint16)S[1])<<8),M[0]);
    294  1.1  christos   }
    295  1.1  christos   if (len > 1) {
    296  1.1  christos     uint16 R2[(len+1)/2];
    297  1.1  christos     uint16 M2[(len+1)/2];
    298  1.1  christos     uint16 bottomr[len/2];
    299  1.1  christos     uint32 bottomt[len/2];
    300  1.1  christos     long long i;
    301  1.1  christos     for (i = 0;i < len-1;i += 2) {
    302  1.1  christos       uint32 m = M[i]*(uint32) M[i+1];
    303  1.1  christos       if (m > 256*16383) {
    304  1.1  christos         bottomt[i/2] = 256*256;
    305  1.1  christos         bottomr[i/2] = S[0]+256*S[1];
    306  1.1  christos         S += 2;
    307  1.1  christos         M2[i/2] = (((m+255)>>8)+255)>>8;
    308  1.1  christos       } else if (m >= 16384) {
    309  1.1  christos         bottomt[i/2] = 256;
    310  1.1  christos         bottomr[i/2] = S[0];
    311  1.1  christos         S += 1;
    312  1.1  christos         M2[i/2] = (m+255)>>8;
    313  1.1  christos       } else {
    314  1.1  christos         bottomt[i/2] = 1;
    315  1.1  christos         bottomr[i/2] = 0;
    316  1.1  christos         M2[i/2] = m;
    317  1.1  christos       }
    318  1.1  christos     }
    319  1.1  christos     if (i < len)
    320  1.1  christos       M2[i/2] = M[i];
    321  1.1  christos     Decode(R2,S,M2,(len+1)/2);
    322  1.1  christos     for (i = 0;i < len-1;i += 2) {
    323  1.1  christos       uint32 r = bottomr[i/2];
    324  1.1  christos       uint32 r1;
    325  1.1  christos       uint16 r0;
    326  1.1  christos       r += bottomt[i/2]*R2[i/2];
    327  1.1  christos       uint32_divmod_uint14(&r1,&r0,r,M[i]);
    328  1.1  christos       r1 = uint32_mod_uint14(r1,M[i+1]); /* only needed for invalid inputs */
    329  1.1  christos       *out++ = r0;
    330  1.1  christos       *out++ = r1;
    331  1.1  christos     }
    332  1.1  christos     if (i < len)
    333  1.1  christos       *out++ = R2[i/2];
    334  1.1  christos   }
    335  1.1  christos }
    336  1.1  christos 
    337  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.h */
    338  1.1  christos #ifndef Encode_H
    339  1.1  christos #define Encode_H
    340  1.1  christos 
    341  1.1  christos 
    342  1.1  christos /* Encode(s,R,M,len) */
    343  1.1  christos /* assumes 0 <= R[i] < M[i] < 16384 */
    344  1.1  christos 
    345  1.1  christos #endif
    346  1.1  christos 
    347  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.c */
    348  1.1  christos 
    349  1.1  christos /* 0 <= R[i] < M[i] < 16384 */
    350  1.1  christos static void Encode(unsigned char *out,const uint16 *R,const uint16 *M,long long len)
    351  1.1  christos {
    352  1.1  christos   if (len == 1) {
    353  1.1  christos     uint16 r = R[0];
    354  1.1  christos     uint16 m = M[0];
    355  1.1  christos     while (m > 1) {
    356  1.1  christos       *out++ = r;
    357  1.1  christos       r >>= 8;
    358  1.1  christos       m = (m+255)>>8;
    359  1.1  christos     }
    360  1.1  christos   }
    361  1.1  christos   if (len > 1) {
    362  1.1  christos     uint16 R2[(len+1)/2];
    363  1.1  christos     uint16 M2[(len+1)/2];
    364  1.1  christos     long long i;
    365  1.1  christos     for (i = 0;i < len-1;i += 2) {
    366  1.1  christos       uint32 m0 = M[i];
    367  1.1  christos       uint32 r = R[i]+R[i+1]*m0;
    368  1.1  christos       uint32 m = M[i+1]*m0;
    369  1.1  christos       while (m >= 16384) {
    370  1.1  christos         *out++ = r;
    371  1.1  christos         r >>= 8;
    372  1.1  christos         m = (m+255)>>8;
    373  1.1  christos       }
    374  1.1  christos       R2[i/2] = r;
    375  1.1  christos       M2[i/2] = m;
    376  1.1  christos     }
    377  1.1  christos     if (i < len) {
    378  1.1  christos       R2[i/2] = R[i];
    379  1.1  christos       M2[i/2] = M[i];
    380  1.1  christos     }
    381  1.1  christos     Encode(out,R2,M2,(len+1)/2);
    382  1.1  christos   }
    383  1.1  christos }
    384  1.1  christos 
    385  1.1  christos /* from supercop-20201130/crypto_kem/sntrup761/ref/kem.c */
    386  1.1  christos 
    387  1.1  christos #ifdef LPR
    388  1.1  christos #endif
    389  1.1  christos 
    390  1.1  christos 
    391  1.1  christos /* ----- masks */
    392  1.1  christos 
    393  1.1  christos #ifndef LPR
    394  1.1  christos 
    395  1.1  christos /* return -1 if x!=0; else return 0 */
    396  1.1  christos static int int16_nonzero_mask(int16 x)
    397  1.1  christos {
    398  1.1  christos   uint16 u = x; /* 0, else 1...65535 */
    399  1.1  christos   uint32 v = u; /* 0, else 1...65535 */
    400  1.1  christos   v = -v; /* 0, else 2^32-65535...2^32-1 */
    401  1.1  christos   v >>= 31; /* 0, else 1 */
    402  1.1  christos   return -v; /* 0, else -1 */
    403  1.1  christos }
    404  1.1  christos 
    405  1.1  christos #endif
    406  1.1  christos 
    407  1.1  christos /* return -1 if x<0; otherwise return 0 */
    408  1.1  christos static int int16_negative_mask(int16 x)
    409  1.1  christos {
    410  1.1  christos   uint16 u = x;
    411  1.1  christos   u >>= 15;
    412  1.1  christos   return -(int) u;
    413  1.1  christos   /* alternative with gcc -fwrapv: */
    414  1.1  christos   /* x>>15 compiles to CPU's arithmetic right shift */
    415  1.1  christos }
    416  1.1  christos 
    417  1.1  christos /* ----- arithmetic mod 3 */
    418  1.1  christos 
    419  1.1  christos typedef int8 small;
    420  1.1  christos 
    421  1.1  christos /* F3 is always represented as -1,0,1 */
    422  1.1  christos /* so ZZ_fromF3 is a no-op */
    423  1.1  christos 
    424  1.1  christos /* x must not be close to top int16 */
    425  1.1  christos static small F3_freeze(int16 x)
    426  1.1  christos {
    427  1.1  christos   return int32_mod_uint14(x+1,3)-1;
    428  1.1  christos }
    429  1.1  christos 
    430  1.1  christos /* ----- arithmetic mod q */
    431  1.1  christos 
    432  1.1  christos #define q12 ((q-1)/2)
    433  1.1  christos typedef int16 Fq;
    434  1.1  christos /* always represented as -q12...q12 */
    435  1.1  christos /* so ZZ_fromFq is a no-op */
    436  1.1  christos 
    437  1.1  christos /* x must not be close to top int32 */
    438  1.1  christos static Fq Fq_freeze(int32 x)
    439  1.1  christos {
    440  1.1  christos   return int32_mod_uint14(x+q12,q)-q12;
    441  1.1  christos }
    442  1.1  christos 
    443  1.1  christos #ifndef LPR
    444  1.1  christos 
    445  1.1  christos static Fq Fq_recip(Fq a1)
    446  1.1  christos {
    447  1.1  christos   int i = 1;
    448  1.1  christos   Fq ai = a1;
    449  1.1  christos 
    450  1.1  christos   while (i < q-2) {
    451  1.1  christos     ai = Fq_freeze(a1*(int32)ai);
    452  1.1  christos     i += 1;
    453  1.1  christos   }
    454  1.1  christos   return ai;
    455  1.1  christos }
    456  1.1  christos 
    457  1.1  christos #endif
    458  1.1  christos 
    459  1.1  christos /* ----- Top and Right */
    460  1.1  christos 
    461  1.1  christos #ifdef LPR
    462  1.1  christos #define tau 16
    463  1.1  christos 
    464  1.1  christos static int8 Top(Fq C)
    465  1.1  christos {
    466  1.1  christos   return (tau1*(int32)(C+tau0)+16384)>>15;
    467  1.1  christos }
    468  1.1  christos 
    469  1.1  christos static Fq Right(int8 T)
    470  1.1  christos {
    471  1.1  christos   return Fq_freeze(tau3*(int32)T-tau2);
    472  1.1  christos }
    473  1.1  christos #endif
    474  1.1  christos 
    475  1.1  christos /* ----- small polynomials */
    476  1.1  christos 
    477  1.1  christos #ifndef LPR
    478  1.1  christos 
    479  1.1  christos /* 0 if Weightw_is(r), else -1 */
    480  1.1  christos static int Weightw_mask(small *r)
    481  1.1  christos {
    482  1.1  christos   int weight = 0;
    483  1.1  christos   int i;
    484  1.1  christos 
    485  1.1  christos   for (i = 0;i < p;++i) weight += r[i]&1;
    486  1.1  christos   return int16_nonzero_mask(weight-w);
    487  1.1  christos }
    488  1.1  christos 
    489  1.1  christos /* R3_fromR(R_fromRq(r)) */
    490  1.1  christos static void R3_fromRq(small *out,const Fq *r)
    491  1.1  christos {
    492  1.1  christos   int i;
    493  1.1  christos   for (i = 0;i < p;++i) out[i] = F3_freeze(r[i]);
    494  1.1  christos }
    495  1.1  christos 
    496  1.1  christos /* h = f*g in the ring R3 */
    497  1.1  christos static void R3_mult(small *h,const small *f,const small *g)
    498  1.1  christos {
    499  1.1  christos   small fg[p+p-1];
    500  1.1  christos   small result;
    501  1.1  christos   int i,j;
    502  1.1  christos 
    503  1.1  christos   for (i = 0;i < p;++i) {
    504  1.1  christos     result = 0;
    505  1.1  christos     for (j = 0;j <= i;++j) result = F3_freeze(result+f[j]*g[i-j]);
    506  1.1  christos     fg[i] = result;
    507  1.1  christos   }
    508  1.1  christos   for (i = p;i < p+p-1;++i) {
    509  1.1  christos     result = 0;
    510  1.1  christos     for (j = i-p+1;j < p;++j) result = F3_freeze(result+f[j]*g[i-j]);
    511  1.1  christos     fg[i] = result;
    512  1.1  christos   }
    513  1.1  christos 
    514  1.1  christos   for (i = p+p-2;i >= p;--i) {
    515  1.1  christos     fg[i-p] = F3_freeze(fg[i-p]+fg[i]);
    516  1.1  christos     fg[i-p+1] = F3_freeze(fg[i-p+1]+fg[i]);
    517  1.1  christos   }
    518  1.1  christos 
    519  1.1  christos   for (i = 0;i < p;++i) h[i] = fg[i];
    520  1.1  christos }
    521  1.1  christos 
    522  1.1  christos /* returns 0 if recip succeeded; else -1 */
    523  1.1  christos static int R3_recip(small *out,const small *in)
    524  1.1  christos {
    525  1.1  christos   small f[p+1],g[p+1],v[p+1],r[p+1];
    526  1.1  christos   int i,loop,delta;
    527  1.1  christos   int sign,swap,t;
    528  1.1  christos 
    529  1.1  christos   for (i = 0;i < p+1;++i) v[i] = 0;
    530  1.1  christos   for (i = 0;i < p+1;++i) r[i] = 0;
    531  1.1  christos   r[0] = 1;
    532  1.1  christos   for (i = 0;i < p;++i) f[i] = 0;
    533  1.1  christos   f[0] = 1; f[p-1] = f[p] = -1;
    534  1.1  christos   for (i = 0;i < p;++i) g[p-1-i] = in[i];
    535  1.1  christos   g[p] = 0;
    536  1.1  christos 
    537  1.1  christos   delta = 1;
    538  1.1  christos 
    539  1.1  christos   for (loop = 0;loop < 2*p-1;++loop) {
    540  1.1  christos     for (i = p;i > 0;--i) v[i] = v[i-1];
    541  1.1  christos     v[0] = 0;
    542  1.1  christos 
    543  1.1  christos     sign = -g[0]*f[0];
    544  1.1  christos     swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
    545  1.1  christos     delta ^= swap&(delta^-delta);
    546  1.1  christos     delta += 1;
    547  1.1  christos 
    548  1.1  christos     for (i = 0;i < p+1;++i) {
    549  1.1  christos       t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
    550  1.1  christos       t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
    551  1.1  christos     }
    552  1.1  christos 
    553  1.1  christos     for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]);
    554  1.1  christos     for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]);
    555  1.1  christos 
    556  1.1  christos     for (i = 0;i < p;++i) g[i] = g[i+1];
    557  1.1  christos     g[p] = 0;
    558  1.1  christos   }
    559  1.1  christos 
    560  1.1  christos   sign = f[0];
    561  1.1  christos   for (i = 0;i < p;++i) out[i] = sign*v[p-1-i];
    562  1.1  christos 
    563  1.1  christos   return int16_nonzero_mask(delta);
    564  1.1  christos }
    565  1.1  christos 
    566  1.1  christos #endif
    567  1.1  christos 
    568  1.1  christos /* ----- polynomials mod q */
    569  1.1  christos 
    570  1.1  christos /* h = f*g in the ring Rq */
    571  1.1  christos static void Rq_mult_small(Fq *h,const Fq *f,const small *g)
    572  1.1  christos {
    573  1.1  christos   Fq fg[p+p-1];
    574  1.1  christos   Fq result;
    575  1.1  christos   int i,j;
    576  1.1  christos 
    577  1.1  christos   for (i = 0;i < p;++i) {
    578  1.1  christos     result = 0;
    579  1.1  christos     for (j = 0;j <= i;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
    580  1.1  christos     fg[i] = result;
    581  1.1  christos   }
    582  1.1  christos   for (i = p;i < p+p-1;++i) {
    583  1.1  christos     result = 0;
    584  1.1  christos     for (j = i-p+1;j < p;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
    585  1.1  christos     fg[i] = result;
    586  1.1  christos   }
    587  1.1  christos 
    588  1.1  christos   for (i = p+p-2;i >= p;--i) {
    589  1.1  christos     fg[i-p] = Fq_freeze(fg[i-p]+fg[i]);
    590  1.1  christos     fg[i-p+1] = Fq_freeze(fg[i-p+1]+fg[i]);
    591  1.1  christos   }
    592  1.1  christos 
    593  1.1  christos   for (i = 0;i < p;++i) h[i] = fg[i];
    594  1.1  christos }
    595  1.1  christos 
    596  1.1  christos #ifndef LPR
    597  1.1  christos 
    598  1.1  christos /* h = 3f in Rq */
    599  1.1  christos static void Rq_mult3(Fq *h,const Fq *f)
    600  1.1  christos {
    601  1.1  christos   int i;
    602  1.1  christos 
    603  1.1  christos   for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]);
    604  1.1  christos }
    605  1.1  christos 
    606  1.1  christos /* out = 1/(3*in) in Rq */
    607  1.1  christos /* returns 0 if recip succeeded; else -1 */
    608  1.1  christos static int Rq_recip3(Fq *out,const small *in)
    609  1.1  christos {
    610  1.1  christos   Fq f[p+1],g[p+1],v[p+1],r[p+1];
    611  1.1  christos   int i,loop,delta;
    612  1.1  christos   int swap,t;
    613  1.1  christos   int32 f0,g0;
    614  1.1  christos   Fq scale;
    615  1.1  christos 
    616  1.1  christos   for (i = 0;i < p+1;++i) v[i] = 0;
    617  1.1  christos   for (i = 0;i < p+1;++i) r[i] = 0;
    618  1.1  christos   r[0] = Fq_recip(3);
    619  1.1  christos   for (i = 0;i < p;++i) f[i] = 0;
    620  1.1  christos   f[0] = 1; f[p-1] = f[p] = -1;
    621  1.1  christos   for (i = 0;i < p;++i) g[p-1-i] = in[i];
    622  1.1  christos   g[p] = 0;
    623  1.1  christos 
    624  1.1  christos   delta = 1;
    625  1.1  christos 
    626  1.1  christos   for (loop = 0;loop < 2*p-1;++loop) {
    627  1.1  christos     for (i = p;i > 0;--i) v[i] = v[i-1];
    628  1.1  christos     v[0] = 0;
    629  1.1  christos 
    630  1.1  christos     swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
    631  1.1  christos     delta ^= swap&(delta^-delta);
    632  1.1  christos     delta += 1;
    633  1.1  christos 
    634  1.1  christos     for (i = 0;i < p+1;++i) {
    635  1.1  christos       t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
    636  1.1  christos       t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
    637  1.1  christos     }
    638  1.1  christos 
    639  1.1  christos     f0 = f[0];
    640  1.1  christos     g0 = g[0];
    641  1.1  christos     for (i = 0;i < p+1;++i) g[i] = Fq_freeze(f0*g[i]-g0*f[i]);
    642  1.1  christos     for (i = 0;i < p+1;++i) r[i] = Fq_freeze(f0*r[i]-g0*v[i]);
    643  1.1  christos 
    644  1.1  christos     for (i = 0;i < p;++i) g[i] = g[i+1];
    645  1.1  christos     g[p] = 0;
    646  1.1  christos   }
    647  1.1  christos 
    648  1.1  christos   scale = Fq_recip(f[0]);
    649  1.1  christos   for (i = 0;i < p;++i) out[i] = Fq_freeze(scale*(int32)v[p-1-i]);
    650  1.1  christos 
    651  1.1  christos   return int16_nonzero_mask(delta);
    652  1.1  christos }
    653  1.1  christos 
    654  1.1  christos #endif
    655  1.1  christos 
    656  1.1  christos /* ----- rounded polynomials mod q */
    657  1.1  christos 
    658  1.1  christos static void Round(Fq *out,const Fq *a)
    659  1.1  christos {
    660  1.1  christos   int i;
    661  1.1  christos   for (i = 0;i < p;++i) out[i] = a[i]-F3_freeze(a[i]);
    662  1.1  christos }
    663  1.1  christos 
    664  1.1  christos /* ----- sorting to generate short polynomial */
    665  1.1  christos 
    666  1.1  christos static void Short_fromlist(small *out,const uint32 *in)
    667  1.1  christos {
    668  1.1  christos   uint32 L[p];
    669  1.1  christos   int i;
    670  1.1  christos 
    671  1.1  christos   for (i = 0;i < w;++i) L[i] = in[i]&(uint32)-2;
    672  1.1  christos   for (i = w;i < p;++i) L[i] = (in[i]&(uint32)-3)|1;
    673  1.1  christos   crypto_sort_uint32(L,p);
    674  1.1  christos   for (i = 0;i < p;++i) out[i] = (L[i]&3)-1;
    675  1.1  christos }
    676  1.1  christos 
    677  1.1  christos /* ----- underlying hash function */
    678  1.1  christos 
    679  1.1  christos #define Hash_bytes 32
    680  1.1  christos 
    681  1.1  christos /* e.g., b = 0 means out = Hash0(in) */
    682  1.1  christos static void Hash_prefix(unsigned char *out,int b,const unsigned char *in,int inlen)
    683  1.1  christos {
    684  1.1  christos   unsigned char x[inlen+1];
    685  1.1  christos   unsigned char h[64];
    686  1.1  christos   int i;
    687  1.1  christos 
    688  1.1  christos   x[0] = b;
    689  1.1  christos   for (i = 0;i < inlen;++i) x[i+1] = in[i];
    690  1.1  christos   crypto_hash_sha512(h,x,inlen+1);
    691  1.1  christos   for (i = 0;i < 32;++i) out[i] = h[i];
    692  1.1  christos }
    693  1.1  christos 
    694  1.1  christos /* ----- higher-level randomness */
    695  1.1  christos 
    696  1.1  christos static uint32 urandom32(void)
    697  1.1  christos {
    698  1.1  christos   unsigned char c[4];
    699  1.1  christos   uint32 out[4];
    700  1.1  christos 
    701  1.1  christos   randombytes(c,4);
    702  1.1  christos   out[0] = (uint32)c[0];
    703  1.1  christos   out[1] = ((uint32)c[1])<<8;
    704  1.1  christos   out[2] = ((uint32)c[2])<<16;
    705  1.1  christos   out[3] = ((uint32)c[3])<<24;
    706  1.1  christos   return out[0]+out[1]+out[2]+out[3];
    707  1.1  christos }
    708  1.1  christos 
    709  1.1  christos static void Short_random(small *out)
    710  1.1  christos {
    711  1.1  christos   uint32 L[p];
    712  1.1  christos   int i;
    713  1.1  christos 
    714  1.1  christos   for (i = 0;i < p;++i) L[i] = urandom32();
    715  1.1  christos   Short_fromlist(out,L);
    716  1.1  christos }
    717  1.1  christos 
    718  1.1  christos #ifndef LPR
    719  1.1  christos 
    720  1.1  christos static void Small_random(small *out)
    721  1.1  christos {
    722  1.1  christos   int i;
    723  1.1  christos 
    724  1.1  christos   for (i = 0;i < p;++i) out[i] = (((urandom32()&0x3fffffff)*3)>>30)-1;
    725  1.1  christos }
    726  1.1  christos 
    727  1.1  christos #endif
    728  1.1  christos 
    729  1.1  christos /* ----- Streamlined NTRU Prime Core */
    730  1.1  christos 
    731  1.1  christos #ifndef LPR
    732  1.1  christos 
    733  1.1  christos /* h,(f,ginv) = KeyGen() */
    734  1.1  christos static void KeyGen(Fq *h,small *f,small *ginv)
    735  1.1  christos {
    736  1.1  christos   small g[p];
    737  1.1  christos   Fq finv[p];
    738  1.1  christos 
    739  1.1  christos   for (;;) {
    740  1.1  christos     Small_random(g);
    741  1.1  christos     if (R3_recip(ginv,g) == 0) break;
    742  1.1  christos   }
    743  1.1  christos   Short_random(f);
    744  1.1  christos   Rq_recip3(finv,f); /* always works */
    745  1.1  christos   Rq_mult_small(h,finv,g);
    746  1.1  christos }
    747  1.1  christos 
    748  1.1  christos /* c = Encrypt(r,h) */
    749  1.1  christos static void Encrypt(Fq *c,const small *r,const Fq *h)
    750  1.1  christos {
    751  1.1  christos   Fq hr[p];
    752  1.1  christos 
    753  1.1  christos   Rq_mult_small(hr,h,r);
    754  1.1  christos   Round(c,hr);
    755  1.1  christos }
    756  1.1  christos 
    757  1.1  christos /* r = Decrypt(c,(f,ginv)) */
    758  1.1  christos static void Decrypt(small *r,const Fq *c,const small *f,const small *ginv)
    759  1.1  christos {
    760  1.1  christos   Fq cf[p];
    761  1.1  christos   Fq cf3[p];
    762  1.1  christos   small e[p];
    763  1.1  christos   small ev[p];
    764  1.1  christos   int mask;
    765  1.1  christos   int i;
    766  1.1  christos 
    767  1.1  christos   Rq_mult_small(cf,c,f);
    768  1.1  christos   Rq_mult3(cf3,cf);
    769  1.1  christos   R3_fromRq(e,cf3);
    770  1.1  christos   R3_mult(ev,e,ginv);
    771  1.1  christos 
    772  1.1  christos   mask = Weightw_mask(ev); /* 0 if weight w, else -1 */
    773  1.1  christos   for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1;
    774  1.1  christos   for (i = w;i < p;++i) r[i] = ev[i]&~mask;
    775  1.1  christos }
    776  1.1  christos 
    777  1.1  christos #endif
    778  1.1  christos 
    779  1.1  christos /* ----- NTRU LPRime Core */
    780  1.1  christos 
    781  1.1  christos #ifdef LPR
    782  1.1  christos 
    783  1.1  christos /* (G,A),a = KeyGen(G); leaves G unchanged */
    784  1.1  christos static void KeyGen(Fq *A,small *a,const Fq *G)
    785  1.1  christos {
    786  1.1  christos   Fq aG[p];
    787  1.1  christos 
    788  1.1  christos   Short_random(a);
    789  1.1  christos   Rq_mult_small(aG,G,a);
    790  1.1  christos   Round(A,aG);
    791  1.1  christos }
    792  1.1  christos 
    793  1.1  christos /* B,T = Encrypt(r,(G,A),b) */
    794  1.1  christos static void Encrypt(Fq *B,int8 *T,const int8 *r,const Fq *G,const Fq *A,const small *b)
    795  1.1  christos {
    796  1.1  christos   Fq bG[p];
    797  1.1  christos   Fq bA[p];
    798  1.1  christos   int i;
    799  1.1  christos 
    800  1.1  christos   Rq_mult_small(bG,G,b);
    801  1.1  christos   Round(B,bG);
    802  1.1  christos   Rq_mult_small(bA,A,b);
    803  1.1  christos   for (i = 0;i < I;++i) T[i] = Top(Fq_freeze(bA[i]+r[i]*q12));
    804  1.1  christos }
    805  1.1  christos 
    806  1.1  christos /* r = Decrypt((B,T),a) */
    807  1.1  christos static void Decrypt(int8 *r,const Fq *B,const int8 *T,const small *a)
    808  1.1  christos {
    809  1.1  christos   Fq aB[p];
    810  1.1  christos   int i;
    811  1.1  christos 
    812  1.1  christos   Rq_mult_small(aB,B,a);
    813  1.1  christos   for (i = 0;i < I;++i)
    814  1.1  christos     r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1));
    815  1.1  christos }
    816  1.1  christos 
    817  1.1  christos #endif
    818  1.1  christos 
    819  1.1  christos /* ----- encoding I-bit inputs */
    820  1.1  christos 
    821  1.1  christos #ifdef LPR
    822  1.1  christos 
    823  1.1  christos #define Inputs_bytes (I/8)
    824  1.1  christos typedef int8 Inputs[I]; /* passed by reference */
    825  1.1  christos 
    826  1.1  christos static void Inputs_encode(unsigned char *s,const Inputs r)
    827  1.1  christos {
    828  1.1  christos   int i;
    829  1.1  christos   for (i = 0;i < Inputs_bytes;++i) s[i] = 0;
    830  1.1  christos   for (i = 0;i < I;++i) s[i>>3] |= r[i]<<(i&7);
    831  1.1  christos }
    832  1.1  christos 
    833  1.1  christos #endif
    834  1.1  christos 
    835  1.1  christos /* ----- Expand */
    836  1.1  christos 
    837  1.1  christos #ifdef LPR
    838  1.1  christos 
    839  1.1  christos static const unsigned char aes_nonce[16] = {0};
    840  1.1  christos 
    841  1.1  christos static void Expand(uint32 *L,const unsigned char *k)
    842  1.1  christos {
    843  1.1  christos   int i;
    844  1.1  christos   crypto_stream_aes256ctr((unsigned char *) L,4*p,aes_nonce,k);
    845  1.1  christos   for (i = 0;i < p;++i) {
    846  1.1  christos     uint32 L0 = ((unsigned char *) L)[4*i];
    847  1.1  christos     uint32 L1 = ((unsigned char *) L)[4*i+1];
    848  1.1  christos     uint32 L2 = ((unsigned char *) L)[4*i+2];
    849  1.1  christos     uint32 L3 = ((unsigned char *) L)[4*i+3];
    850  1.1  christos     L[i] = L0+(L1<<8)+(L2<<16)+(L3<<24);
    851  1.1  christos   }
    852  1.1  christos }
    853  1.1  christos 
    854  1.1  christos #endif
    855  1.1  christos 
    856  1.1  christos /* ----- Seeds */
    857  1.1  christos 
    858  1.1  christos #ifdef LPR
    859  1.1  christos 
    860  1.1  christos #define Seeds_bytes 32
    861  1.1  christos 
    862  1.1  christos static void Seeds_random(unsigned char *s)
    863  1.1  christos {
    864  1.1  christos   randombytes(s,Seeds_bytes);
    865  1.1  christos }
    866  1.1  christos 
    867  1.1  christos #endif
    868  1.1  christos 
    869  1.1  christos /* ----- Generator, HashShort */
    870  1.1  christos 
    871  1.1  christos #ifdef LPR
    872  1.1  christos 
    873  1.1  christos /* G = Generator(k) */
    874  1.1  christos static void Generator(Fq *G,const unsigned char *k)
    875  1.1  christos {
    876  1.1  christos   uint32 L[p];
    877  1.1  christos   int i;
    878  1.1  christos 
    879  1.1  christos   Expand(L,k);
    880  1.1  christos   for (i = 0;i < p;++i) G[i] = uint32_mod_uint14(L[i],q)-q12;
    881  1.1  christos }
    882  1.1  christos 
    883  1.1  christos /* out = HashShort(r) */
    884  1.1  christos static void HashShort(small *out,const Inputs r)
    885  1.1  christos {
    886  1.1  christos   unsigned char s[Inputs_bytes];
    887  1.1  christos   unsigned char h[Hash_bytes];
    888  1.1  christos   uint32 L[p];
    889  1.1  christos 
    890  1.1  christos   Inputs_encode(s,r);
    891  1.1  christos   Hash_prefix(h,5,s,sizeof s);
    892  1.1  christos   Expand(L,h);
    893  1.1  christos   Short_fromlist(out,L);
    894  1.1  christos }
    895  1.1  christos 
    896  1.1  christos #endif
    897  1.1  christos 
    898  1.1  christos /* ----- NTRU LPRime Expand */
    899  1.1  christos 
    900  1.1  christos #ifdef LPR
    901  1.1  christos 
    902  1.1  christos /* (S,A),a = XKeyGen() */
    903  1.1  christos static void XKeyGen(unsigned char *S,Fq *A,small *a)
    904  1.1  christos {
    905  1.1  christos   Fq G[p];
    906  1.1  christos 
    907  1.1  christos   Seeds_random(S);
    908  1.1  christos   Generator(G,S);
    909  1.1  christos   KeyGen(A,a,G);
    910  1.1  christos }
    911  1.1  christos 
    912  1.1  christos /* B,T = XEncrypt(r,(S,A)) */
    913  1.1  christos static void XEncrypt(Fq *B,int8 *T,const int8 *r,const unsigned char *S,const Fq *A)
    914  1.1  christos {
    915  1.1  christos   Fq G[p];
    916  1.1  christos   small b[p];
    917  1.1  christos 
    918  1.1  christos   Generator(G,S);
    919  1.1  christos   HashShort(b,r);
    920  1.1  christos   Encrypt(B,T,r,G,A,b);
    921  1.1  christos }
    922  1.1  christos 
    923  1.1  christos #define XDecrypt Decrypt
    924  1.1  christos 
    925  1.1  christos #endif
    926  1.1  christos 
    927  1.1  christos /* ----- encoding small polynomials (including short polynomials) */
    928  1.1  christos 
    929  1.1  christos #define Small_bytes ((p+3)/4)
    930  1.1  christos 
    931  1.1  christos /* these are the only functions that rely on p mod 4 = 1 */
    932  1.1  christos 
    933  1.1  christos static void Small_encode(unsigned char *s,const small *f)
    934  1.1  christos {
    935  1.1  christos   small x;
    936  1.1  christos   int i;
    937  1.1  christos 
    938  1.1  christos   for (i = 0;i < p/4;++i) {
    939  1.1  christos     x = *f++ + 1;
    940  1.1  christos     x += (*f++ + 1)<<2;
    941  1.1  christos     x += (*f++ + 1)<<4;
    942  1.1  christos     x += (*f++ + 1)<<6;
    943  1.1  christos     *s++ = x;
    944  1.1  christos   }
    945  1.1  christos   x = *f++ + 1;
    946  1.1  christos   *s++ = x;
    947  1.1  christos }
    948  1.1  christos 
    949  1.1  christos static void Small_decode(small *f,const unsigned char *s)
    950  1.1  christos {
    951  1.1  christos   unsigned char x;
    952  1.1  christos   int i;
    953  1.1  christos 
    954  1.1  christos   for (i = 0;i < p/4;++i) {
    955  1.1  christos     x = *s++;
    956  1.1  christos     *f++ = ((small)(x&3))-1; x >>= 2;
    957  1.1  christos     *f++ = ((small)(x&3))-1; x >>= 2;
    958  1.1  christos     *f++ = ((small)(x&3))-1; x >>= 2;
    959  1.1  christos     *f++ = ((small)(x&3))-1;
    960  1.1  christos   }
    961  1.1  christos   x = *s++;
    962  1.1  christos   *f++ = ((small)(x&3))-1;
    963  1.1  christos }
    964  1.1  christos 
    965  1.1  christos /* ----- encoding general polynomials */
    966  1.1  christos 
    967  1.1  christos #ifndef LPR
    968  1.1  christos 
    969  1.1  christos static void Rq_encode(unsigned char *s,const Fq *r)
    970  1.1  christos {
    971  1.1  christos   uint16 R[p],M[p];
    972  1.1  christos   int i;
    973  1.1  christos 
    974  1.1  christos   for (i = 0;i < p;++i) R[i] = r[i]+q12;
    975  1.1  christos   for (i = 0;i < p;++i) M[i] = q;
    976  1.1  christos   Encode(s,R,M,p);
    977  1.1  christos }
    978  1.1  christos 
    979  1.1  christos static void Rq_decode(Fq *r,const unsigned char *s)
    980  1.1  christos {
    981  1.1  christos   uint16 R[p],M[p];
    982  1.1  christos   int i;
    983  1.1  christos 
    984  1.1  christos   for (i = 0;i < p;++i) M[i] = q;
    985  1.1  christos   Decode(R,s,M,p);
    986  1.1  christos   for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12;
    987  1.1  christos }
    988  1.1  christos 
    989  1.1  christos #endif
    990  1.1  christos 
    991  1.1  christos /* ----- encoding rounded polynomials */
    992  1.1  christos 
    993  1.1  christos static void Rounded_encode(unsigned char *s,const Fq *r)
    994  1.1  christos {
    995  1.1  christos   uint16 R[p],M[p];
    996  1.1  christos   int i;
    997  1.1  christos 
    998  1.1  christos   for (i = 0;i < p;++i) R[i] = ((r[i]+q12)*10923)>>15;
    999  1.1  christos   for (i = 0;i < p;++i) M[i] = (q+2)/3;
   1000  1.1  christos   Encode(s,R,M,p);
   1001  1.1  christos }
   1002  1.1  christos 
   1003  1.1  christos static void Rounded_decode(Fq *r,const unsigned char *s)
   1004  1.1  christos {
   1005  1.1  christos   uint16 R[p],M[p];
   1006  1.1  christos   int i;
   1007  1.1  christos 
   1008  1.1  christos   for (i = 0;i < p;++i) M[i] = (q+2)/3;
   1009  1.1  christos   Decode(R,s,M,p);
   1010  1.1  christos   for (i = 0;i < p;++i) r[i] = R[i]*3-q12;
   1011  1.1  christos }
   1012  1.1  christos 
   1013  1.1  christos /* ----- encoding top polynomials */
   1014  1.1  christos 
   1015  1.1  christos #ifdef LPR
   1016  1.1  christos 
   1017  1.1  christos #define Top_bytes (I/2)
   1018  1.1  christos 
   1019  1.1  christos static void Top_encode(unsigned char *s,const int8 *T)
   1020  1.1  christos {
   1021  1.1  christos   int i;
   1022  1.1  christos   for (i = 0;i < Top_bytes;++i)
   1023  1.1  christos     s[i] = T[2*i]+(T[2*i+1]<<4);
   1024  1.1  christos }
   1025  1.1  christos 
   1026  1.1  christos static void Top_decode(int8 *T,const unsigned char *s)
   1027  1.1  christos {
   1028  1.1  christos   int i;
   1029  1.1  christos   for (i = 0;i < Top_bytes;++i) {
   1030  1.1  christos     T[2*i] = s[i]&15;
   1031  1.1  christos     T[2*i+1] = s[i]>>4;
   1032  1.1  christos   }
   1033  1.1  christos }
   1034  1.1  christos 
   1035  1.1  christos #endif
   1036  1.1  christos 
   1037  1.1  christos /* ----- Streamlined NTRU Prime Core plus encoding */
   1038  1.1  christos 
   1039  1.1  christos #ifndef LPR
   1040  1.1  christos 
   1041  1.1  christos typedef small Inputs[p]; /* passed by reference */
   1042  1.1  christos #define Inputs_random Short_random
   1043  1.1  christos #define Inputs_encode Small_encode
   1044  1.1  christos #define Inputs_bytes Small_bytes
   1045  1.1  christos 
   1046  1.1  christos #define Ciphertexts_bytes Rounded_bytes
   1047  1.1  christos #define SecretKeys_bytes (2*Small_bytes)
   1048  1.1  christos #define PublicKeys_bytes Rq_bytes
   1049  1.1  christos 
   1050  1.1  christos /* pk,sk = ZKeyGen() */
   1051  1.1  christos static void ZKeyGen(unsigned char *pk,unsigned char *sk)
   1052  1.1  christos {
   1053  1.1  christos   Fq h[p];
   1054  1.1  christos   small f[p],v[p];
   1055  1.1  christos 
   1056  1.1  christos   KeyGen(h,f,v);
   1057  1.1  christos   Rq_encode(pk,h);
   1058  1.1  christos   Small_encode(sk,f); sk += Small_bytes;
   1059  1.1  christos   Small_encode(sk,v);
   1060  1.1  christos }
   1061  1.1  christos 
   1062  1.1  christos /* C = ZEncrypt(r,pk) */
   1063  1.1  christos static void ZEncrypt(unsigned char *C,const Inputs r,const unsigned char *pk)
   1064  1.1  christos {
   1065  1.1  christos   Fq h[p];
   1066  1.1  christos   Fq c[p];
   1067  1.1  christos   Rq_decode(h,pk);
   1068  1.1  christos   Encrypt(c,r,h);
   1069  1.1  christos   Rounded_encode(C,c);
   1070  1.1  christos }
   1071  1.1  christos 
   1072  1.1  christos /* r = ZDecrypt(C,sk) */
   1073  1.1  christos static void ZDecrypt(Inputs r,const unsigned char *C,const unsigned char *sk)
   1074  1.1  christos {
   1075  1.1  christos   small f[p],v[p];
   1076  1.1  christos   Fq c[p];
   1077  1.1  christos 
   1078  1.1  christos   Small_decode(f,sk); sk += Small_bytes;
   1079  1.1  christos   Small_decode(v,sk);
   1080  1.1  christos   Rounded_decode(c,C);
   1081  1.1  christos   Decrypt(r,c,f,v);
   1082  1.1  christos }
   1083  1.1  christos 
   1084  1.1  christos #endif
   1085  1.1  christos 
   1086  1.1  christos /* ----- NTRU LPRime Expand plus encoding */
   1087  1.1  christos 
   1088  1.1  christos #ifdef LPR
   1089  1.1  christos 
   1090  1.1  christos #define Ciphertexts_bytes (Rounded_bytes+Top_bytes)
   1091  1.1  christos #define SecretKeys_bytes Small_bytes
   1092  1.1  christos #define PublicKeys_bytes (Seeds_bytes+Rounded_bytes)
   1093  1.1  christos 
   1094  1.1  christos static void Inputs_random(Inputs r)
   1095  1.1  christos {
   1096  1.1  christos   unsigned char s[Inputs_bytes];
   1097  1.1  christos   int i;
   1098  1.1  christos 
   1099  1.1  christos   randombytes(s,sizeof s);
   1100  1.1  christos   for (i = 0;i < I;++i) r[i] = 1&(s[i>>3]>>(i&7));
   1101  1.1  christos }
   1102  1.1  christos 
   1103  1.1  christos /* pk,sk = ZKeyGen() */
   1104  1.1  christos static void ZKeyGen(unsigned char *pk,unsigned char *sk)
   1105  1.1  christos {
   1106  1.1  christos   Fq A[p];
   1107  1.1  christos   small a[p];
   1108  1.1  christos 
   1109  1.1  christos   XKeyGen(pk,A,a); pk += Seeds_bytes;
   1110  1.1  christos   Rounded_encode(pk,A);
   1111  1.1  christos   Small_encode(sk,a);
   1112  1.1  christos }
   1113  1.1  christos 
   1114  1.1  christos /* c = ZEncrypt(r,pk) */
   1115  1.1  christos static void ZEncrypt(unsigned char *c,const Inputs r,const unsigned char *pk)
   1116  1.1  christos {
   1117  1.1  christos   Fq A[p];
   1118  1.1  christos   Fq B[p];
   1119  1.1  christos   int8 T[I];
   1120  1.1  christos 
   1121  1.1  christos   Rounded_decode(A,pk+Seeds_bytes);
   1122  1.1  christos   XEncrypt(B,T,r,pk,A);
   1123  1.1  christos   Rounded_encode(c,B); c += Rounded_bytes;
   1124  1.1  christos   Top_encode(c,T);
   1125  1.1  christos }
   1126  1.1  christos 
   1127  1.1  christos /* r = ZDecrypt(C,sk) */
   1128  1.1  christos static void ZDecrypt(Inputs r,const unsigned char *c,const unsigned char *sk)
   1129  1.1  christos {
   1130  1.1  christos   small a[p];
   1131  1.1  christos   Fq B[p];
   1132  1.1  christos   int8 T[I];
   1133  1.1  christos 
   1134  1.1  christos   Small_decode(a,sk);
   1135  1.1  christos   Rounded_decode(B,c);
   1136  1.1  christos   Top_decode(T,c+Rounded_bytes);
   1137  1.1  christos   XDecrypt(r,B,T,a);
   1138  1.1  christos }
   1139  1.1  christos 
   1140  1.1  christos #endif
   1141  1.1  christos 
   1142  1.1  christos /* ----- confirmation hash */
   1143  1.1  christos 
   1144  1.1  christos #define Confirm_bytes 32
   1145  1.1  christos 
   1146  1.1  christos /* h = HashConfirm(r,pk,cache); cache is Hash4(pk) */
   1147  1.1  christos static void HashConfirm(unsigned char *h,const unsigned char *r,const unsigned char *pk,const unsigned char *cache)
   1148  1.1  christos {
   1149  1.1  christos #ifndef LPR
   1150  1.1  christos   unsigned char x[Hash_bytes*2];
   1151  1.1  christos   int i;
   1152  1.1  christos 
   1153  1.1  christos   Hash_prefix(x,3,r,Inputs_bytes);
   1154  1.1  christos   for (i = 0;i < Hash_bytes;++i) x[Hash_bytes+i] = cache[i];
   1155  1.1  christos #else
   1156  1.1  christos   unsigned char x[Inputs_bytes+Hash_bytes];
   1157  1.1  christos   int i;
   1158  1.1  christos 
   1159  1.1  christos   for (i = 0;i < Inputs_bytes;++i) x[i] = r[i];
   1160  1.1  christos   for (i = 0;i < Hash_bytes;++i) x[Inputs_bytes+i] = cache[i];
   1161  1.1  christos #endif
   1162  1.1  christos   Hash_prefix(h,2,x,sizeof x);
   1163  1.1  christos }
   1164  1.1  christos 
   1165  1.1  christos /* ----- session-key hash */
   1166  1.1  christos 
   1167  1.1  christos /* k = HashSession(b,y,z) */
   1168  1.1  christos static void HashSession(unsigned char *k,int b,const unsigned char *y,const unsigned char *z)
   1169  1.1  christos {
   1170  1.1  christos #ifndef LPR
   1171  1.1  christos   unsigned char x[Hash_bytes+Ciphertexts_bytes+Confirm_bytes];
   1172  1.1  christos   int i;
   1173  1.1  christos 
   1174  1.1  christos   Hash_prefix(x,3,y,Inputs_bytes);
   1175  1.1  christos   for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Hash_bytes+i] = z[i];
   1176  1.1  christos #else
   1177  1.1  christos   unsigned char x[Inputs_bytes+Ciphertexts_bytes+Confirm_bytes];
   1178  1.1  christos   int i;
   1179  1.1  christos 
   1180  1.1  christos   for (i = 0;i < Inputs_bytes;++i) x[i] = y[i];
   1181  1.1  christos   for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Inputs_bytes+i] = z[i];
   1182  1.1  christos #endif
   1183  1.1  christos   Hash_prefix(k,b,x,sizeof x);
   1184  1.1  christos }
   1185  1.1  christos 
   1186  1.1  christos /* ----- Streamlined NTRU Prime and NTRU LPRime */
   1187  1.1  christos 
   1188  1.1  christos /* pk,sk = KEM_KeyGen() */
   1189  1.1  christos static void KEM_KeyGen(unsigned char *pk,unsigned char *sk)
   1190  1.1  christos {
   1191  1.1  christos   int i;
   1192  1.1  christos 
   1193  1.1  christos   ZKeyGen(pk,sk); sk += SecretKeys_bytes;
   1194  1.1  christos   for (i = 0;i < PublicKeys_bytes;++i) *sk++ = pk[i];
   1195  1.1  christos   randombytes(sk,Inputs_bytes); sk += Inputs_bytes;
   1196  1.1  christos   Hash_prefix(sk,4,pk,PublicKeys_bytes);
   1197  1.1  christos }
   1198  1.1  christos 
   1199  1.1  christos /* c,r_enc = Hide(r,pk,cache); cache is Hash4(pk) */
   1200  1.1  christos static void Hide(unsigned char *c,unsigned char *r_enc,const Inputs r,const unsigned char *pk,const unsigned char *cache)
   1201  1.1  christos {
   1202  1.1  christos   Inputs_encode(r_enc,r);
   1203  1.1  christos   ZEncrypt(c,r,pk); c += Ciphertexts_bytes;
   1204  1.1  christos   HashConfirm(c,r_enc,pk,cache);
   1205  1.1  christos }
   1206  1.1  christos 
   1207  1.1  christos /* c,k = Encap(pk) */
   1208  1.1  christos static void Encap(unsigned char *c,unsigned char *k,const unsigned char *pk)
   1209  1.1  christos {
   1210  1.1  christos   Inputs r;
   1211  1.1  christos   unsigned char r_enc[Inputs_bytes];
   1212  1.1  christos   unsigned char cache[Hash_bytes];
   1213  1.1  christos 
   1214  1.1  christos   Hash_prefix(cache,4,pk,PublicKeys_bytes);
   1215  1.1  christos   Inputs_random(r);
   1216  1.1  christos   Hide(c,r_enc,r,pk,cache);
   1217  1.1  christos   HashSession(k,1,r_enc,c);
   1218  1.1  christos }
   1219  1.1  christos 
   1220  1.1  christos /* 0 if matching ciphertext+confirm, else -1 */
   1221  1.1  christos static int Ciphertexts_diff_mask(const unsigned char *c,const unsigned char *c2)
   1222  1.1  christos {
   1223  1.1  christos   uint16 differentbits = 0;
   1224  1.1  christos   int len = Ciphertexts_bytes+Confirm_bytes;
   1225  1.1  christos 
   1226  1.1  christos   while (len-- > 0) differentbits |= (*c++)^(*c2++);
   1227  1.1  christos   return (1&((differentbits-1)>>8))-1;
   1228  1.1  christos }
   1229  1.1  christos 
   1230  1.1  christos /* k = Decap(c,sk) */
   1231  1.1  christos static void Decap(unsigned char *k,const unsigned char *c,const unsigned char *sk)
   1232  1.1  christos {
   1233  1.1  christos   const unsigned char *pk = sk + SecretKeys_bytes;
   1234  1.1  christos   const unsigned char *rho = pk + PublicKeys_bytes;
   1235  1.1  christos   const unsigned char *cache = rho + Inputs_bytes;
   1236  1.1  christos   Inputs r;
   1237  1.1  christos   unsigned char r_enc[Inputs_bytes];
   1238  1.1  christos   unsigned char cnew[Ciphertexts_bytes+Confirm_bytes];
   1239  1.1  christos   int mask;
   1240  1.1  christos   int i;
   1241  1.1  christos 
   1242  1.1  christos   ZDecrypt(r,c,sk);
   1243  1.1  christos   Hide(cnew,r_enc,r,pk,cache);
   1244  1.1  christos   mask = Ciphertexts_diff_mask(c,cnew);
   1245  1.1  christos   for (i = 0;i < Inputs_bytes;++i) r_enc[i] ^= mask&(r_enc[i]^rho[i]);
   1246  1.1  christos   HashSession(k,1+mask,r_enc,c);
   1247  1.1  christos }
   1248  1.1  christos 
   1249  1.1  christos /* ----- crypto_kem API */
   1250  1.1  christos 
   1251  1.1  christos 
   1252  1.1  christos int crypto_kem_sntrup761_keypair(unsigned char *pk,unsigned char *sk)
   1253  1.1  christos {
   1254  1.1  christos   KEM_KeyGen(pk,sk);
   1255  1.1  christos   return 0;
   1256  1.1  christos }
   1257  1.1  christos 
   1258  1.1  christos int crypto_kem_sntrup761_enc(unsigned char *c,unsigned char *k,const unsigned char *pk)
   1259  1.1  christos {
   1260  1.1  christos   Encap(c,k,pk);
   1261  1.1  christos   return 0;
   1262  1.1  christos }
   1263  1.1  christos 
   1264  1.1  christos int crypto_kem_sntrup761_dec(unsigned char *k,const unsigned char *c,const unsigned char *sk)
   1265  1.1  christos {
   1266  1.1  christos   Decap(k,c,sk);
   1267  1.1  christos   return 0;
   1268  1.1  christos }
   1269  1.1  christos 
   1270