kyber-common.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /* kyber-common.c - the Kyber key encapsulation mechanism (common part)
  2. * Copyright (C) 2024 g10 Code GmbH
  3. *
  4. * This file was modified for use by Libgcrypt.
  5. *
  6. * This file 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. * This file 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. * You can also use this file under the same licence of original code.
  21. * SPDX-License-Identifier: CC0 OR Apache-2.0
  22. *
  23. */
  24. /*
  25. Original code from:
  26. Repository: https://github.com/pq-crystals/kyber.git
  27. Branch: standard
  28. Commit: 11d00ff1f20cfca1f72d819e5a45165c1e0a2816
  29. Licence:
  30. Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
  31. or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
  32. Authors:
  33. Joppe Bos
  34. Léo Ducas
  35. Eike Kiltz
  36. Tancrède Lepoint
  37. Vadim Lyubashevsky
  38. John Schanck
  39. Peter Schwabe
  40. Gregor Seiler
  41. Damien Stehlé
  42. Kyber Home: https://www.pq-crystals.org/kyber/
  43. */
  44. /*
  45. * From original code, following modification was made.
  46. *
  47. * - C++ style comments are changed to C-style.
  48. *
  49. * - Functions "poly_cbd_eta1" "poly_cbd_eta2" are removed.
  50. *
  51. * - Constant "zeta" is static, not available outside.
  52. *
  53. * - "poly_compress" and "poly_decompress" are now two variants _128
  54. * and _160.
  55. *
  56. * - "poly_getnoise_eta1" is now two variants _2 and _3_4.
  57. *
  58. * - "poly_getnoise_eta2" directly uses "cbd2" function.
  59. */
  60. /*************** kyber/ref/cbd.c */
  61. /*************************************************
  62. * Name: load32_littleendian
  63. *
  64. * Description: load 4 bytes into a 32-bit integer
  65. * in little-endian order
  66. *
  67. * Arguments: - const uint8_t *x: pointer to input byte array
  68. *
  69. * Returns 32-bit unsigned integer loaded from x
  70. **************************************************/
  71. static uint32_t load32_littleendian(const uint8_t x[4])
  72. {
  73. uint32_t r;
  74. r = (uint32_t)x[0];
  75. r |= (uint32_t)x[1] << 8;
  76. r |= (uint32_t)x[2] << 16;
  77. r |= (uint32_t)x[3] << 24;
  78. return r;
  79. }
  80. /*************************************************
  81. * Name: load24_littleendian
  82. *
  83. * Description: load 3 bytes into a 32-bit integer
  84. * in little-endian order.
  85. * This function is only needed for Kyber-512
  86. *
  87. * Arguments: - const uint8_t *x: pointer to input byte array
  88. *
  89. * Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
  90. **************************************************/
  91. #if !defined(KYBER_K) || KYBER_K == 2
  92. static uint32_t load24_littleendian(const uint8_t x[3])
  93. {
  94. uint32_t r;
  95. r = (uint32_t)x[0];
  96. r |= (uint32_t)x[1] << 8;
  97. r |= (uint32_t)x[2] << 16;
  98. return r;
  99. }
  100. #endif
  101. /*************************************************
  102. * Name: cbd2
  103. *
  104. * Description: Given an array of uniformly random bytes, compute
  105. * polynomial with coefficients distributed according to
  106. * a centered binomial distribution with parameter eta=2
  107. *
  108. * Arguments: - poly *r: pointer to output polynomial
  109. * - const uint8_t *buf: pointer to input byte array
  110. **************************************************/
  111. static void cbd2(poly *r, const uint8_t buf[2*KYBER_N/4])
  112. {
  113. unsigned int i,j;
  114. uint32_t t,d;
  115. int16_t a,b;
  116. for(i=0;i<KYBER_N/8;i++) {
  117. t = load32_littleendian(buf+4*i);
  118. d = t & 0x55555555;
  119. d += (t>>1) & 0x55555555;
  120. for(j=0;j<8;j++) {
  121. a = (d >> (4*j+0)) & 0x3;
  122. b = (d >> (4*j+2)) & 0x3;
  123. r->coeffs[8*i+j] = a - b;
  124. }
  125. }
  126. }
  127. /*************************************************
  128. * Name: cbd3
  129. *
  130. * Description: Given an array of uniformly random bytes, compute
  131. * polynomial with coefficients distributed according to
  132. * a centered binomial distribution with parameter eta=3.
  133. * This function is only needed for Kyber-512
  134. *
  135. * Arguments: - poly *r: pointer to output polynomial
  136. * - const uint8_t *buf: pointer to input byte array
  137. **************************************************/
  138. #if !defined(KYBER_K) || KYBER_K == 2
  139. static void cbd3(poly *r, const uint8_t buf[3*KYBER_N/4])
  140. {
  141. unsigned int i,j;
  142. uint32_t t,d;
  143. int16_t a,b;
  144. for(i=0;i<KYBER_N/4;i++) {
  145. t = load24_littleendian(buf+3*i);
  146. d = t & 0x00249249;
  147. d += (t>>1) & 0x00249249;
  148. d += (t>>2) & 0x00249249;
  149. for(j=0;j<4;j++) {
  150. a = (d >> (6*j+0)) & 0x7;
  151. b = (d >> (6*j+3)) & 0x7;
  152. r->coeffs[4*i+j] = a - b;
  153. }
  154. }
  155. }
  156. #endif
  157. /*************** kyber/ref/indcpa.c */
  158. /*************************************************
  159. * Name: rej_uniform
  160. *
  161. * Description: Run rejection sampling on uniform random bytes to generate
  162. * uniform random integers mod q
  163. *
  164. * Arguments: - int16_t *r: pointer to output buffer
  165. * - unsigned int len: requested number of 16-bit integers (uniform mod q)
  166. * - const uint8_t *buf: pointer to input buffer (assumed to be uniformly random bytes)
  167. * - unsigned int buflen: length of input buffer in bytes
  168. *
  169. * Returns number of sampled 16-bit integers (at most len)
  170. **************************************************/
  171. static unsigned int rej_uniform(int16_t *r,
  172. unsigned int len,
  173. const uint8_t *buf,
  174. unsigned int buflen)
  175. {
  176. unsigned int ctr, pos;
  177. uint16_t val0, val1;
  178. ctr = pos = 0;
  179. while(ctr < len && pos + 3 <= buflen) {
  180. val0 = ((buf[pos+0] >> 0) | ((uint16_t)buf[pos+1] << 8)) & 0xFFF;
  181. val1 = ((buf[pos+1] >> 4) | ((uint16_t)buf[pos+2] << 4)) & 0xFFF;
  182. pos += 3;
  183. if(val0 < KYBER_Q)
  184. r[ctr++] = val0;
  185. if(ctr < len && val1 < KYBER_Q)
  186. r[ctr++] = val1;
  187. }
  188. return ctr;
  189. }
  190. /*************** kyber/ref/ntt.c */
  191. /* Code to generate zetas and zetas_inv used in the number-theoretic transform:
  192. #define KYBER_ROOT_OF_UNITY 17
  193. static const uint8_t tree[128] = {
  194. 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120,
  195. 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124,
  196. 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122,
  197. 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126,
  198. 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121,
  199. 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125,
  200. 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123,
  201. 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127
  202. };
  203. void init_ntt() {
  204. unsigned int i;
  205. int16_t tmp[128];
  206. tmp[0] = MONT;
  207. for(i=1;i<128;i++)
  208. tmp[i] = fqmul(tmp[i-1],MONT*KYBER_ROOT_OF_UNITY % KYBER_Q);
  209. for(i=0;i<128;i++) {
  210. zetas[i] = tmp[tree[i]];
  211. if(zetas[i] > KYBER_Q/2)
  212. zetas[i] -= KYBER_Q;
  213. if(zetas[i] < -KYBER_Q/2)
  214. zetas[i] += KYBER_Q;
  215. }
  216. }
  217. */
  218. static const int16_t zetas[128] = {
  219. -1044, -758, -359, -1517, 1493, 1422, 287, 202,
  220. -171, 622, 1577, 182, 962, -1202, -1474, 1468,
  221. 573, -1325, 264, 383, -829, 1458, -1602, -130,
  222. -681, 1017, 732, 608, -1542, 411, -205, -1571,
  223. 1223, 652, -552, 1015, -1293, 1491, -282, -1544,
  224. 516, -8, -320, -666, -1618, -1162, 126, 1469,
  225. -853, -90, -271, 830, 107, -1421, -247, -951,
  226. -398, 961, -1508, -725, 448, -1065, 677, -1275,
  227. -1103, 430, 555, 843, -1251, 871, 1550, 105,
  228. 422, 587, 177, -235, -291, -460, 1574, 1653,
  229. -246, 778, 1159, -147, -777, 1483, -602, 1119,
  230. -1590, 644, -872, 349, 418, 329, -156, -75,
  231. 817, 1097, 603, 610, 1322, -1285, -1465, 384,
  232. -1215, -136, 1218, -1335, -874, 220, -1187, -1659,
  233. -1185, -1530, -1278, 794, -1510, -854, -870, 478,
  234. -108, -308, 996, 991, 958, -1460, 1522, 1628
  235. };
  236. /*************************************************
  237. * Name: fqmul
  238. *
  239. * Description: Multiplication followed by Montgomery reduction
  240. *
  241. * Arguments: - int16_t a: first factor
  242. * - int16_t b: second factor
  243. *
  244. * Returns 16-bit integer congruent to a*b*R^{-1} mod q
  245. **************************************************/
  246. static int16_t fqmul(int16_t a, int16_t b) {
  247. return montgomery_reduce((int32_t)a*b);
  248. }
  249. /*************************************************
  250. * Name: ntt
  251. *
  252. * Description: Inplace number-theoretic transform (NTT) in Rq.
  253. * input is in standard order, output is in bitreversed order
  254. *
  255. * Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
  256. **************************************************/
  257. void ntt(int16_t r[256]) {
  258. unsigned int len, start, j, k;
  259. int16_t t, zeta;
  260. k = 1;
  261. for(len = 128; len >= 2; len >>= 1) {
  262. for(start = 0; start < 256; start = j + len) {
  263. zeta = zetas[k++];
  264. for(j = start; j < start + len; j++) {
  265. t = fqmul(zeta, r[j + len]);
  266. r[j + len] = r[j] - t;
  267. r[j] = r[j] + t;
  268. }
  269. }
  270. }
  271. }
  272. /*************************************************
  273. * Name: invntt_tomont
  274. *
  275. * Description: Inplace inverse number-theoretic transform in Rq and
  276. * multiplication by Montgomery factor 2^16.
  277. * Input is in bitreversed order, output is in standard order
  278. *
  279. * Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
  280. **************************************************/
  281. void invntt(int16_t r[256]) {
  282. unsigned int start, len, j, k;
  283. int16_t t, zeta;
  284. const int16_t f = 1441; /* mont^2/128 */
  285. k = 127;
  286. for(len = 2; len <= 128; len <<= 1) {
  287. for(start = 0; start < 256; start = j + len) {
  288. zeta = zetas[k--];
  289. for(j = start; j < start + len; j++) {
  290. t = r[j];
  291. r[j] = barrett_reduce(t + r[j + len]);
  292. r[j + len] = r[j + len] - t;
  293. r[j + len] = fqmul(zeta, r[j + len]);
  294. }
  295. }
  296. }
  297. for(j = 0; j < 256; j++)
  298. r[j] = fqmul(r[j], f);
  299. }
  300. /*************************************************
  301. * Name: basemul
  302. *
  303. * Description: Multiplication of polynomials in Zq[X]/(X^2-zeta)
  304. * used for multiplication of elements in Rq in NTT domain
  305. *
  306. * Arguments: - int16_t r[2]: pointer to the output polynomial
  307. * - const int16_t a[2]: pointer to the first factor
  308. * - const int16_t b[2]: pointer to the second factor
  309. * - int16_t zeta: integer defining the reduction polynomial
  310. **************************************************/
  311. void basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta)
  312. {
  313. r[0] = fqmul(a[1], b[1]);
  314. r[0] = fqmul(r[0], zeta);
  315. r[0] += fqmul(a[0], b[0]);
  316. r[1] = fqmul(a[0], b[1]);
  317. r[1] += fqmul(a[1], b[0]);
  318. }
  319. /*************** kyber/ref/poly.c */
  320. /*************************************************
  321. * Name: poly_compress
  322. *
  323. * Description: Compression and subsequent serialization of a polynomial
  324. *
  325. * Arguments: - uint8_t *r: pointer to output byte array
  326. * (of length KYBER_POLYCOMPRESSEDBYTES)
  327. * - const poly *a: pointer to input polynomial
  328. **************************************************/
  329. #if !defined(KYBER_K) || KYBER_K == 2 || KYBER_K == 3
  330. void poly_compress_128(uint8_t r[KYBER_POLYCOMPRESSEDBYTES_2_3], const poly *a)
  331. {
  332. unsigned int i,j;
  333. int32_t u;
  334. uint32_t d0;
  335. uint8_t t[8];
  336. for(i=0;i<KYBER_N/8;i++) {
  337. for(j=0;j<8;j++) {
  338. /* map to positive standard representatives */
  339. u = a->coeffs[8*i+j];
  340. u += (u >> 15) & KYBER_Q;
  341. /* t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15; */
  342. d0 = u << 4;
  343. d0 += 1665;
  344. d0 *= 80635;
  345. d0 >>= 28;
  346. t[j] = d0 & 0xf;
  347. }
  348. r[0] = t[0] | (t[1] << 4);
  349. r[1] = t[2] | (t[3] << 4);
  350. r[2] = t[4] | (t[5] << 4);
  351. r[3] = t[6] | (t[7] << 4);
  352. r += 4;
  353. }
  354. }
  355. #endif
  356. #if !defined(KYBER_K) || KYBER_K == 4
  357. void poly_compress_160(uint8_t r[KYBER_POLYCOMPRESSEDBYTES_4], const poly *a)
  358. {
  359. unsigned int i,j;
  360. int32_t u;
  361. uint32_t d0;
  362. uint8_t t[8];
  363. for(i=0;i<KYBER_N/8;i++) {
  364. for(j=0;j<8;j++) {
  365. /* map to positive standard representatives */
  366. u = a->coeffs[8*i+j];
  367. u += (u >> 15) & KYBER_Q;
  368. /* t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31; */
  369. d0 = u << 5;
  370. d0 += 1664;
  371. d0 *= 40318;
  372. d0 >>= 27;
  373. t[j] = d0 & 0x1f;
  374. }
  375. r[0] = (t[0] >> 0) | (t[1] << 5);
  376. r[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
  377. r[2] = (t[3] >> 1) | (t[4] << 4);
  378. r[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6);
  379. r[4] = (t[6] >> 2) | (t[7] << 3);
  380. r += 5;
  381. }
  382. }
  383. #endif
  384. /*************************************************
  385. * Name: poly_decompress
  386. *
  387. * Description: De-serialization and subsequent decompression of a polynomial;
  388. * approximate inverse of poly_compress
  389. *
  390. * Arguments: - poly *r: pointer to output polynomial
  391. * - const uint8_t *a: pointer to input byte array
  392. * (of length KYBER_POLYCOMPRESSEDBYTES bytes)
  393. **************************************************/
  394. #if !defined(KYBER_K) || KYBER_K == 2 || KYBER_K == 3
  395. void poly_decompress_128(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES_2_3])
  396. {
  397. unsigned int i;
  398. for(i=0;i<KYBER_N/2;i++) {
  399. r->coeffs[2*i+0] = (((uint16_t)(a[0] & 15)*KYBER_Q) + 8) >> 4;
  400. r->coeffs[2*i+1] = (((uint16_t)(a[0] >> 4)*KYBER_Q) + 8) >> 4;
  401. a += 1;
  402. }
  403. }
  404. #endif
  405. #if !defined(KYBER_K) || KYBER_K == 4
  406. void poly_decompress_160(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES_4])
  407. {
  408. unsigned int i;
  409. unsigned int j;
  410. uint8_t t[8];
  411. for(i=0;i<KYBER_N/8;i++) {
  412. t[0] = (a[0] >> 0);
  413. t[1] = (a[0] >> 5) | (a[1] << 3);
  414. t[2] = (a[1] >> 2);
  415. t[3] = (a[1] >> 7) | (a[2] << 1);
  416. t[4] = (a[2] >> 4) | (a[3] << 4);
  417. t[5] = (a[3] >> 1);
  418. t[6] = (a[3] >> 6) | (a[4] << 2);
  419. t[7] = (a[4] >> 3);
  420. a += 5;
  421. for(j=0;j<8;j++)
  422. r->coeffs[8*i+j] = ((uint32_t)(t[j] & 31)*KYBER_Q + 16) >> 5;
  423. }
  424. }
  425. #endif
  426. /*************************************************
  427. * Name: poly_tobytes
  428. *
  429. * Description: Serialization of a polynomial
  430. *
  431. * Arguments: - uint8_t *r: pointer to output byte array
  432. * (needs space for KYBER_POLYBYTES bytes)
  433. * - const poly *a: pointer to input polynomial
  434. **************************************************/
  435. void poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a)
  436. {
  437. unsigned int i;
  438. uint16_t t0, t1;
  439. for(i=0;i<KYBER_N/2;i++) {
  440. /* map to positive standard representatives */
  441. t0 = a->coeffs[2*i];
  442. t0 += ((int16_t)t0 >> 15) & KYBER_Q;
  443. t1 = a->coeffs[2*i+1];
  444. t1 += ((int16_t)t1 >> 15) & KYBER_Q;
  445. r[3*i+0] = (t0 >> 0);
  446. r[3*i+1] = (t0 >> 8) | (t1 << 4);
  447. r[3*i+2] = (t1 >> 4);
  448. }
  449. }
  450. /*************************************************
  451. * Name: poly_frombytes
  452. *
  453. * Description: De-serialization of a polynomial;
  454. * inverse of poly_tobytes
  455. *
  456. * Arguments: - poly *r: pointer to output polynomial
  457. * - const uint8_t *a: pointer to input byte array
  458. * (of KYBER_POLYBYTES bytes)
  459. **************************************************/
  460. void poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES])
  461. {
  462. unsigned int i;
  463. for(i=0;i<KYBER_N/2;i++) {
  464. r->coeffs[2*i] = ((a[3*i+0] >> 0) | ((uint16_t)a[3*i+1] << 8)) & 0xFFF;
  465. r->coeffs[2*i+1] = ((a[3*i+1] >> 4) | ((uint16_t)a[3*i+2] << 4)) & 0xFFF;
  466. }
  467. }
  468. /*************************************************
  469. * Name: poly_frommsg
  470. *
  471. * Description: Convert 32-byte message to polynomial
  472. *
  473. * Arguments: - poly *r: pointer to output polynomial
  474. * - const uint8_t *msg: pointer to input message
  475. **************************************************/
  476. void poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES])
  477. {
  478. unsigned int i,j;
  479. int16_t mask;
  480. #if (KYBER_INDCPA_MSGBYTES != KYBER_N/8)
  481. #error "KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!"
  482. #endif
  483. for(i=0;i<KYBER_N/8;i++) {
  484. for(j=0;j<8;j++) {
  485. mask = -(int16_t)((msg[i] >> j)&1);
  486. r->coeffs[8*i+j] = mask & ((KYBER_Q+1)/2);
  487. }
  488. }
  489. }
  490. /*************************************************
  491. * Name: poly_tomsg
  492. *
  493. * Description: Convert polynomial to 32-byte message
  494. *
  495. * Arguments: - uint8_t *msg: pointer to output message
  496. * - const poly *a: pointer to input polynomial
  497. **************************************************/
  498. void poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a)
  499. {
  500. unsigned int i,j;
  501. uint32_t t;
  502. for(i=0;i<KYBER_N/8;i++) {
  503. msg[i] = 0;
  504. for(j=0;j<8;j++) {
  505. t = a->coeffs[8*i+j];
  506. /* t += ((int16_t)t >> 15) & KYBER_Q; */
  507. /* t = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1; */
  508. t <<= 1;
  509. t += 1665;
  510. t *= 80635;
  511. t >>= 28;
  512. t &= 1;
  513. msg[i] |= t << j;
  514. }
  515. }
  516. }
  517. /*************************************************
  518. * Name: poly_getnoise_eta1
  519. *
  520. * Description: Sample a polynomial deterministically from a seed and a nonce,
  521. * with output polynomial close to centered binomial distribution
  522. * with parameter KYBER_ETA1
  523. *
  524. * Arguments: - poly *r: pointer to output polynomial
  525. * - const uint8_t *seed: pointer to input seed
  526. * (of length KYBER_SYMBYTES bytes)
  527. * - uint8_t nonce: one-byte input nonce
  528. **************************************************/
  529. #if !defined(KYBER_K) || KYBER_K == 2
  530. void poly_getnoise_eta1_2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
  531. {
  532. uint8_t buf[KYBER_ETA1_2*KYBER_N/4];
  533. prf(buf, sizeof(buf), seed, nonce);
  534. cbd3(r, buf);
  535. }
  536. #endif
  537. #if !defined(KYBER_K) || KYBER_K == 3 || KYBER_K == 4
  538. void poly_getnoise_eta1_3_4(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
  539. {
  540. uint8_t buf[KYBER_ETA1_3_4*KYBER_N/4];
  541. prf(buf, sizeof(buf), seed, nonce);
  542. cbd2(r, buf);
  543. }
  544. #endif
  545. /*************************************************
  546. * Name: poly_getnoise_eta2
  547. *
  548. * Description: Sample a polynomial deterministically from a seed and a nonce,
  549. * with output polynomial close to centered binomial distribution
  550. * with parameter KYBER_ETA2
  551. *
  552. * Arguments: - poly *r: pointer to output polynomial
  553. * - const uint8_t *seed: pointer to input seed
  554. * (of length KYBER_SYMBYTES bytes)
  555. * - uint8_t nonce: one-byte input nonce
  556. **************************************************/
  557. void poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
  558. {
  559. uint8_t buf[KYBER_ETA2*KYBER_N/4];
  560. prf(buf, sizeof(buf), seed, nonce);
  561. cbd2(r, buf);
  562. }
  563. /*************************************************
  564. * Name: poly_ntt
  565. *
  566. * Description: Computes negacyclic number-theoretic transform (NTT) of
  567. * a polynomial in place;
  568. * inputs assumed to be in normal order, output in bitreversed order
  569. *
  570. * Arguments: - uint16_t *r: pointer to in/output polynomial
  571. **************************************************/
  572. void poly_ntt(poly *r)
  573. {
  574. ntt(r->coeffs);
  575. poly_reduce(r);
  576. }
  577. /*************************************************
  578. * Name: poly_invntt_tomont
  579. *
  580. * Description: Computes inverse of negacyclic number-theoretic transform (NTT)
  581. * of a polynomial in place;
  582. * inputs assumed to be in bitreversed order, output in normal order
  583. *
  584. * Arguments: - uint16_t *a: pointer to in/output polynomial
  585. **************************************************/
  586. void poly_invntt_tomont(poly *r)
  587. {
  588. invntt(r->coeffs);
  589. }
  590. /*************************************************
  591. * Name: poly_basemul_montgomery
  592. *
  593. * Description: Multiplication of two polynomials in NTT domain
  594. *
  595. * Arguments: - poly *r: pointer to output polynomial
  596. * - const poly *a: pointer to first input polynomial
  597. * - const poly *b: pointer to second input polynomial
  598. **************************************************/
  599. void poly_basemul_montgomery(poly *r, const poly *a, const poly *b)
  600. {
  601. unsigned int i;
  602. for(i=0;i<KYBER_N/4;i++) {
  603. basemul(&r->coeffs[4*i], &a->coeffs[4*i], &b->coeffs[4*i], zetas[64+i]);
  604. basemul(&r->coeffs[4*i+2], &a->coeffs[4*i+2], &b->coeffs[4*i+2], -zetas[64+i]);
  605. }
  606. }
  607. /*************************************************
  608. * Name: poly_tomont
  609. *
  610. * Description: Inplace conversion of all coefficients of a polynomial
  611. * from normal domain to Montgomery domain
  612. *
  613. * Arguments: - poly *r: pointer to input/output polynomial
  614. **************************************************/
  615. void poly_tomont(poly *r)
  616. {
  617. unsigned int i;
  618. const int16_t f = (1ULL << 32) % KYBER_Q;
  619. for(i=0;i<KYBER_N;i++)
  620. r->coeffs[i] = montgomery_reduce((int32_t)r->coeffs[i]*f);
  621. }
  622. /*************************************************
  623. * Name: poly_reduce
  624. *
  625. * Description: Applies Barrett reduction to all coefficients of a polynomial
  626. * for details of the Barrett reduction see comments in reduce.c
  627. *
  628. * Arguments: - poly *r: pointer to input/output polynomial
  629. **************************************************/
  630. void poly_reduce(poly *r)
  631. {
  632. unsigned int i;
  633. for(i=0;i<KYBER_N;i++)
  634. r->coeffs[i] = barrett_reduce(r->coeffs[i]);
  635. }
  636. /*************************************************
  637. * Name: poly_add
  638. *
  639. * Description: Add two polynomials; no modular reduction is performed
  640. *
  641. * Arguments: - poly *r: pointer to output polynomial
  642. * - const poly *a: pointer to first input polynomial
  643. * - const poly *b: pointer to second input polynomial
  644. **************************************************/
  645. void poly_add(poly *r, const poly *a, const poly *b)
  646. {
  647. unsigned int i;
  648. for(i=0;i<KYBER_N;i++)
  649. r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
  650. }
  651. /*************************************************
  652. * Name: poly_sub
  653. *
  654. * Description: Subtract two polynomials; no modular reduction is performed
  655. *
  656. * Arguments: - poly *r: pointer to output polynomial
  657. * - const poly *a: pointer to first input polynomial
  658. * - const poly *b: pointer to second input polynomial
  659. **************************************************/
  660. void poly_sub(poly *r, const poly *a, const poly *b)
  661. {
  662. unsigned int i;
  663. for(i=0;i<KYBER_N;i++)
  664. r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
  665. }
  666. /*************** kyber/ref/reduce.c */
  667. /*************************************************
  668. * Name: montgomery_reduce
  669. *
  670. * Description: Montgomery reduction; given a 32-bit integer a, computes
  671. * 16-bit integer congruent to a * R^-1 mod q, where R=2^16
  672. *
  673. * Arguments: - int32_t a: input integer to be reduced;
  674. * has to be in {-q2^15,...,q2^15-1}
  675. *
  676. * Returns: integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q.
  677. **************************************************/
  678. int16_t montgomery_reduce(int32_t a)
  679. {
  680. int16_t t;
  681. t = (int16_t)a*QINV;
  682. t = (a - (int32_t)t*KYBER_Q) >> 16;
  683. return t;
  684. }
  685. /*************************************************
  686. * Name: barrett_reduce
  687. *
  688. * Description: Barrett reduction; given a 16-bit integer a, computes
  689. * centered representative congruent to a mod q in {-(q-1)/2,...,(q-1)/2}
  690. *
  691. * Arguments: - int16_t a: input integer to be reduced
  692. *
  693. * Returns: integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
  694. **************************************************/
  695. int16_t barrett_reduce(int16_t a) {
  696. int16_t t;
  697. const int16_t v = ((1<<26) + KYBER_Q/2)/KYBER_Q;
  698. t = ((int32_t)v*a + (1<<25)) >> 26;
  699. t *= KYBER_Q;
  700. return a - t;
  701. }