kyber512r3_fips202.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /* Based on the public domain implementation in
  2. * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html
  3. * by Ronny Van Keer
  4. * and the public domain "TweetFips202" implementation
  5. * from https://twitter.com/tweetfips202
  6. * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include "kyber512r3_params.h"
  10. #include "kyber512r3_fips202.h"
  11. #define NROUNDS 24
  12. #define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
  13. S2N_ENSURE_PORTABLE_OPTIMIZATIONS
  14. /*************************************************
  15. * Name: load64
  16. *
  17. * Description: Load 8 bytes into uint64_t in little-endian order
  18. *
  19. * Arguments: - const uint8_t *x: pointer to input byte array
  20. *
  21. * Returns the loaded 64-bit unsigned integer
  22. **************************************************/
  23. static uint64_t load64(const uint8_t *x) {
  24. uint64_t r = 0;
  25. for (size_t i = 0; i < 8; ++i) {
  26. r |= (uint64_t)x[i] << 8 * i;
  27. }
  28. return r;
  29. }
  30. /*************************************************
  31. * Name: store64
  32. *
  33. * Description: Store a 64-bit integer to a byte array in little-endian order
  34. *
  35. * Arguments: - uint8_t *x: pointer to the output byte array
  36. * - uint64_t u: input 64-bit unsigned integer
  37. **************************************************/
  38. static void store64(uint8_t *x, uint64_t u) {
  39. for (size_t i = 0; i < 8; ++i) {
  40. x[i] = (uint8_t) (u >> 8 * i);
  41. }
  42. }
  43. /* Keccak round constants */
  44. static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
  45. 0x0000000000000001ULL, 0x0000000000008082ULL,
  46. 0x800000000000808aULL, 0x8000000080008000ULL,
  47. 0x000000000000808bULL, 0x0000000080000001ULL,
  48. 0x8000000080008081ULL, 0x8000000000008009ULL,
  49. 0x000000000000008aULL, 0x0000000000000088ULL,
  50. 0x0000000080008009ULL, 0x000000008000000aULL,
  51. 0x000000008000808bULL, 0x800000000000008bULL,
  52. 0x8000000000008089ULL, 0x8000000000008003ULL,
  53. 0x8000000000008002ULL, 0x8000000000000080ULL,
  54. 0x000000000000800aULL, 0x800000008000000aULL,
  55. 0x8000000080008081ULL, 0x8000000000008080ULL,
  56. 0x0000000080000001ULL, 0x8000000080008008ULL,
  57. };
  58. /*************************************************
  59. * Name: KeccakF1600_StatePermute
  60. *
  61. * Description: The Keccak F1600 Permutation
  62. *
  63. * Arguments: - uint64_t *state: pointer to input/output Keccak state
  64. **************************************************/
  65. static void KeccakF1600_StatePermute(uint64_t *state) {
  66. int round;
  67. uint64_t Aba, Abe, Abi, Abo, Abu;
  68. uint64_t Aga, Age, Agi, Ago, Agu;
  69. uint64_t Aka, Ake, Aki, Ako, Aku;
  70. uint64_t Ama, Ame, Ami, Amo, Amu;
  71. uint64_t Asa, Ase, Asi, Aso, Asu;
  72. /* copyFromState(A, state) */
  73. Aba = state[0];
  74. Abe = state[1];
  75. Abi = state[2];
  76. Abo = state[3];
  77. Abu = state[4];
  78. Aga = state[5];
  79. Age = state[6];
  80. Agi = state[7];
  81. Ago = state[8];
  82. Agu = state[9];
  83. Aka = state[10];
  84. Ake = state[11];
  85. Aki = state[12];
  86. Ako = state[13];
  87. Aku = state[14];
  88. Ama = state[15];
  89. Ame = state[16];
  90. Ami = state[17];
  91. Amo = state[18];
  92. Amu = state[19];
  93. Asa = state[20];
  94. Ase = state[21];
  95. Asi = state[22];
  96. Aso = state[23];
  97. Asu = state[24];
  98. for (round = 0; round < NROUNDS; round += 2) {
  99. uint64_t BCa, BCe, BCi, BCo, BCu;
  100. uint64_t Da, De, Di, Do, Du;
  101. uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
  102. uint64_t Ega, Ege, Egi, Ego, Egu;
  103. uint64_t Eka, Eke, Eki, Eko, Eku;
  104. uint64_t Ema, Eme, Emi, Emo, Emu;
  105. uint64_t Esa, Ese, Esi, Eso, Esu;
  106. /* prepareTheta */
  107. BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
  108. BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
  109. BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
  110. BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
  111. BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
  112. /* thetaRhoPiChiIotaPrepareTheta(round , A, E) */
  113. Da = BCu ^ ROL(BCe, 1);
  114. De = BCa ^ ROL(BCi, 1);
  115. Di = BCe ^ ROL(BCo, 1);
  116. Do = BCi ^ ROL(BCu, 1);
  117. Du = BCo ^ ROL(BCa, 1);
  118. Aba ^= Da;
  119. BCa = Aba;
  120. Age ^= De;
  121. BCe = ROL(Age, 44);
  122. Aki ^= Di;
  123. BCi = ROL(Aki, 43);
  124. Amo ^= Do;
  125. BCo = ROL(Amo, 21);
  126. Asu ^= Du;
  127. BCu = ROL(Asu, 14);
  128. Eba = BCa ^ ((~BCe) & BCi);
  129. Eba ^= KeccakF_RoundConstants[round];
  130. Ebe = BCe ^ ((~BCi) & BCo);
  131. Ebi = BCi ^ ((~BCo) & BCu);
  132. Ebo = BCo ^ ((~BCu) & BCa);
  133. Ebu = BCu ^ ((~BCa) & BCe);
  134. Abo ^= Do;
  135. BCa = ROL(Abo, 28);
  136. Agu ^= Du;
  137. BCe = ROL(Agu, 20);
  138. Aka ^= Da;
  139. BCi = ROL(Aka, 3);
  140. Ame ^= De;
  141. BCo = ROL(Ame, 45);
  142. Asi ^= Di;
  143. BCu = ROL(Asi, 61);
  144. Ega = BCa ^ ((~BCe) & BCi);
  145. Ege = BCe ^ ((~BCi) & BCo);
  146. Egi = BCi ^ ((~BCo) & BCu);
  147. Ego = BCo ^ ((~BCu) & BCa);
  148. Egu = BCu ^ ((~BCa) & BCe);
  149. Abe ^= De;
  150. BCa = ROL(Abe, 1);
  151. Agi ^= Di;
  152. BCe = ROL(Agi, 6);
  153. Ako ^= Do;
  154. BCi = ROL(Ako, 25);
  155. Amu ^= Du;
  156. BCo = ROL(Amu, 8);
  157. Asa ^= Da;
  158. BCu = ROL(Asa, 18);
  159. Eka = BCa ^ ((~BCe) & BCi);
  160. Eke = BCe ^ ((~BCi) & BCo);
  161. Eki = BCi ^ ((~BCo) & BCu);
  162. Eko = BCo ^ ((~BCu) & BCa);
  163. Eku = BCu ^ ((~BCa) & BCe);
  164. Abu ^= Du;
  165. BCa = ROL(Abu, 27);
  166. Aga ^= Da;
  167. BCe = ROL(Aga, 36);
  168. Ake ^= De;
  169. BCi = ROL(Ake, 10);
  170. Ami ^= Di;
  171. BCo = ROL(Ami, 15);
  172. Aso ^= Do;
  173. BCu = ROL(Aso, 56);
  174. Ema = BCa ^ ((~BCe) & BCi);
  175. Eme = BCe ^ ((~BCi) & BCo);
  176. Emi = BCi ^ ((~BCo) & BCu);
  177. Emo = BCo ^ ((~BCu) & BCa);
  178. Emu = BCu ^ ((~BCa) & BCe);
  179. Abi ^= Di;
  180. BCa = ROL(Abi, 62);
  181. Ago ^= Do;
  182. BCe = ROL(Ago, 55);
  183. Aku ^= Du;
  184. BCi = ROL(Aku, 39);
  185. Ama ^= Da;
  186. BCo = ROL(Ama, 41);
  187. Ase ^= De;
  188. BCu = ROL(Ase, 2);
  189. Esa = BCa ^ ((~BCe) & BCi);
  190. Ese = BCe ^ ((~BCi) & BCo);
  191. Esi = BCi ^ ((~BCo) & BCu);
  192. Eso = BCo ^ ((~BCu) & BCa);
  193. Esu = BCu ^ ((~BCa) & BCe);
  194. /* prepareTheta */
  195. BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
  196. BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
  197. BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
  198. BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
  199. BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
  200. /* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
  201. Da = BCu ^ ROL(BCe, 1);
  202. De = BCa ^ ROL(BCi, 1);
  203. Di = BCe ^ ROL(BCo, 1);
  204. Do = BCi ^ ROL(BCu, 1);
  205. Du = BCo ^ ROL(BCa, 1);
  206. Eba ^= Da;
  207. BCa = Eba;
  208. Ege ^= De;
  209. BCe = ROL(Ege, 44);
  210. Eki ^= Di;
  211. BCi = ROL(Eki, 43);
  212. Emo ^= Do;
  213. BCo = ROL(Emo, 21);
  214. Esu ^= Du;
  215. BCu = ROL(Esu, 14);
  216. Aba = BCa ^ ((~BCe) & BCi);
  217. Aba ^= KeccakF_RoundConstants[round + 1];
  218. Abe = BCe ^ ((~BCi) & BCo);
  219. Abi = BCi ^ ((~BCo) & BCu);
  220. Abo = BCo ^ ((~BCu) & BCa);
  221. Abu = BCu ^ ((~BCa) & BCe);
  222. Ebo ^= Do;
  223. BCa = ROL(Ebo, 28);
  224. Egu ^= Du;
  225. BCe = ROL(Egu, 20);
  226. Eka ^= Da;
  227. BCi = ROL(Eka, 3);
  228. Eme ^= De;
  229. BCo = ROL(Eme, 45);
  230. Esi ^= Di;
  231. BCu = ROL(Esi, 61);
  232. Aga = BCa ^ ((~BCe) & BCi);
  233. Age = BCe ^ ((~BCi) & BCo);
  234. Agi = BCi ^ ((~BCo) & BCu);
  235. Ago = BCo ^ ((~BCu) & BCa);
  236. Agu = BCu ^ ((~BCa) & BCe);
  237. Ebe ^= De;
  238. BCa = ROL(Ebe, 1);
  239. Egi ^= Di;
  240. BCe = ROL(Egi, 6);
  241. Eko ^= Do;
  242. BCi = ROL(Eko, 25);
  243. Emu ^= Du;
  244. BCo = ROL(Emu, 8);
  245. Esa ^= Da;
  246. BCu = ROL(Esa, 18);
  247. Aka = BCa ^ ((~BCe) & BCi);
  248. Ake = BCe ^ ((~BCi) & BCo);
  249. Aki = BCi ^ ((~BCo) & BCu);
  250. Ako = BCo ^ ((~BCu) & BCa);
  251. Aku = BCu ^ ((~BCa) & BCe);
  252. Ebu ^= Du;
  253. BCa = ROL(Ebu, 27);
  254. Ega ^= Da;
  255. BCe = ROL(Ega, 36);
  256. Eke ^= De;
  257. BCi = ROL(Eke, 10);
  258. Emi ^= Di;
  259. BCo = ROL(Emi, 15);
  260. Eso ^= Do;
  261. BCu = ROL(Eso, 56);
  262. Ama = BCa ^ ((~BCe) & BCi);
  263. Ame = BCe ^ ((~BCi) & BCo);
  264. Ami = BCi ^ ((~BCo) & BCu);
  265. Amo = BCo ^ ((~BCu) & BCa);
  266. Amu = BCu ^ ((~BCa) & BCe);
  267. Ebi ^= Di;
  268. BCa = ROL(Ebi, 62);
  269. Ego ^= Do;
  270. BCe = ROL(Ego, 55);
  271. Eku ^= Du;
  272. BCi = ROL(Eku, 39);
  273. Ema ^= Da;
  274. BCo = ROL(Ema, 41);
  275. Ese ^= De;
  276. BCu = ROL(Ese, 2);
  277. Asa = BCa ^ ((~BCe) & BCi);
  278. Ase = BCe ^ ((~BCi) & BCo);
  279. Asi = BCi ^ ((~BCo) & BCu);
  280. Aso = BCo ^ ((~BCu) & BCa);
  281. Asu = BCu ^ ((~BCa) & BCe);
  282. }
  283. /* copyToState(state, A) */
  284. state[0] = Aba;
  285. state[1] = Abe;
  286. state[2] = Abi;
  287. state[3] = Abo;
  288. state[4] = Abu;
  289. state[5] = Aga;
  290. state[6] = Age;
  291. state[7] = Agi;
  292. state[8] = Ago;
  293. state[9] = Agu;
  294. state[10] = Aka;
  295. state[11] = Ake;
  296. state[12] = Aki;
  297. state[13] = Ako;
  298. state[14] = Aku;
  299. state[15] = Ama;
  300. state[16] = Ame;
  301. state[17] = Ami;
  302. state[18] = Amo;
  303. state[19] = Amu;
  304. state[20] = Asa;
  305. state[21] = Ase;
  306. state[22] = Asi;
  307. state[23] = Aso;
  308. state[24] = Asu;
  309. }
  310. /*************************************************
  311. * Name: keccak_absorb
  312. *
  313. * Description: Absorb step of Keccak;
  314. * non-incremental, starts by zeroeing the state.
  315. *
  316. * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
  317. * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
  318. * - const uint8_t *m: pointer to input to be absorbed into s
  319. * - size_t mlen: length of input in bytes
  320. * - uint8_t p: domain-separation byte for different
  321. * Keccak-derived functions
  322. **************************************************/
  323. static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m, size_t mlen, uint8_t p) {
  324. size_t i;
  325. uint8_t t[200];
  326. /* Zero state */
  327. for (i = 0; i < 25; ++i) {
  328. s[i] = 0;
  329. }
  330. while (mlen >= r) {
  331. for (i = 0; i < r / 8; ++i) {
  332. s[i] ^= load64(m + 8 * i);
  333. }
  334. KeccakF1600_StatePermute(s);
  335. mlen -= r;
  336. m += r;
  337. }
  338. for (i = 0; i < r; ++i) {
  339. t[i] = 0;
  340. }
  341. for (i = 0; i < mlen; ++i) {
  342. t[i] = m[i];
  343. }
  344. t[i] = p;
  345. t[r - 1] |= 128;
  346. for (i = 0; i < r / 8; ++i) {
  347. s[i] ^= load64(t + 8 * i);
  348. }
  349. }
  350. /*************************************************
  351. * Name: keccak_squeezeblocks
  352. *
  353. * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
  354. * Modifies the state. Can be called multiple times to keep
  355. * squeezing, i.e., is incremental.
  356. *
  357. * Arguments: - uint8_t *h: pointer to output blocks
  358. * - size_t nblocks: number of blocks to be
  359. * squeezed (written to h)
  360. * - uint64_t *s: pointer to input/output Keccak state
  361. * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
  362. **************************************************/
  363. static void keccak_squeezeblocks(uint8_t *h, size_t nblocks, uint64_t *s, uint32_t r) {
  364. while (nblocks > 0) {
  365. KeccakF1600_StatePermute(s);
  366. for (size_t i = 0; i < (r >> 3); i++) {
  367. store64(h + 8 * i, s[i]);
  368. }
  369. h += r;
  370. nblocks--;
  371. }
  372. }
  373. /*************************************************
  374. * Name: shake128_absorb
  375. *
  376. * Description: Absorb step of the SHAKE128 XOF.
  377. * non-incremental, starts by zeroeing the state.
  378. *
  379. * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
  380. * - const uint8_t *input: pointer to input to be absorbed
  381. * into s
  382. * - size_t inlen: length of input in bytes
  383. **************************************************/
  384. void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen) {
  385. keccak_absorb(state->ctx, S2N_KYBER_512_R3_SHAKE128_RATE, input, inlen, 0x1F);
  386. }
  387. /*************************************************
  388. * Name: shake128_squeezeblocks
  389. *
  390. * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
  391. * SHAKE128_RATE bytes each. Modifies the state. Can be called
  392. * multiple times to keep squeezing, i.e., is incremental.
  393. *
  394. * Arguments: - uint8_t *output: pointer to output blocks
  395. * - size_t nblocks: number of blocks to be squeezed
  396. * (written to output)
  397. * - shake128ctx *state: pointer to input/output Keccak state
  398. **************************************************/
  399. void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state) {
  400. keccak_squeezeblocks(output, nblocks, state->ctx, S2N_KYBER_512_R3_SHAKE128_RATE);
  401. }
  402. /*************************************************
  403. * Name: shake256_absorb
  404. *
  405. * Description: Absorb step of the SHAKE256 XOF.
  406. * non-incremental, starts by zeroeing the state.
  407. *
  408. * Arguments: - shake256ctx *state: pointer to (uninitialized) output Keccak state
  409. * - const uint8_t *input: pointer to input to be absorbed
  410. * into s
  411. * - size_t inlen: length of input in bytes
  412. **************************************************/
  413. void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen) {
  414. keccak_absorb(state->ctx, S2N_KYBER_512_R3_SHAKE256_RATE, input, inlen, 0x1F);
  415. }
  416. /*************************************************
  417. * Name: shake256_squeezeblocks
  418. *
  419. * Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
  420. * SHAKE256_RATE bytes each. Modifies the state. Can be called
  421. * multiple times to keep squeezing, i.e., is incremental.
  422. *
  423. * Arguments: - uint8_t *output: pointer to output blocks
  424. * - size_t nblocks: number of blocks to be squeezed
  425. * (written to output)
  426. * - shake256ctx *state: pointer to input/output Keccak state
  427. **************************************************/
  428. void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state) {
  429. keccak_squeezeblocks(output, nblocks, state->ctx, S2N_KYBER_512_R3_SHAKE256_RATE);
  430. }
  431. /*************************************************
  432. * Name: shake256
  433. *
  434. * Description: SHAKE256 XOF with non-incremental API
  435. *
  436. * Arguments: - uint8_t *output: pointer to output
  437. * - size_t outlen: requested output length in bytes
  438. * - const uint8_t *input: pointer to input
  439. * - size_t inlen: length of input in bytes
  440. **************************************************/
  441. void shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen) {
  442. size_t nblocks = outlen / S2N_KYBER_512_R3_SHAKE256_RATE;
  443. uint8_t t[S2N_KYBER_512_R3_SHAKE256_RATE];
  444. shake256ctx s;
  445. shake256_absorb(&s, input, inlen);
  446. shake256_squeezeblocks(output, nblocks, &s);
  447. output += nblocks * S2N_KYBER_512_R3_SHAKE256_RATE;
  448. outlen -= nblocks * S2N_KYBER_512_R3_SHAKE256_RATE;
  449. if (outlen) {
  450. shake256_squeezeblocks(t, 1, &s);
  451. for (size_t i = 0; i < outlen; ++i) {
  452. output[i] = t[i];
  453. }
  454. }
  455. }
  456. /*************************************************
  457. * Name: sha3_256
  458. *
  459. * Description: SHA3-256 with non-incremental API
  460. *
  461. * Arguments: - uint8_t *output: pointer to output
  462. * - const uint8_t *input: pointer to input
  463. * - size_t inlen: length of input in bytes
  464. **************************************************/
  465. void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) {
  466. uint64_t s[25];
  467. uint8_t t[S2N_KYBER_512_R3_SHA3_256_RATE];
  468. /* Absorb input */
  469. keccak_absorb(s, S2N_KYBER_512_R3_SHA3_256_RATE, input, inlen, 0x06);
  470. /* Squeeze output */
  471. keccak_squeezeblocks(t, 1, s, S2N_KYBER_512_R3_SHA3_256_RATE);
  472. for (size_t i = 0; i < 32; i++) {
  473. output[i] = t[i];
  474. }
  475. }
  476. /*************************************************
  477. * Name: sha3_512
  478. *
  479. * Description: SHA3-512 with non-incremental API
  480. *
  481. * Arguments: - uint8_t *output: pointer to output
  482. * - const uint8_t *input: pointer to input
  483. * - size_t inlen: length of input in bytes
  484. **************************************************/
  485. void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) {
  486. uint64_t s[25];
  487. uint8_t t[S2N_KYBER_512_R3_SHA3_512_RATE];
  488. /* Absorb input */
  489. keccak_absorb(s, S2N_KYBER_512_R3_SHA3_512_RATE, input, inlen, 0x06);
  490. /* Squeeze output */
  491. keccak_squeezeblocks(t, 1, s, S2N_KYBER_512_R3_SHA3_512_RATE);
  492. for (size_t i = 0; i < 64; i++) {
  493. output[i] = t[i];
  494. }
  495. }