sntrup761.c 22 KB

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