sntrup761.c 25 KB

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