diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/aws/s2n/pq-crypto/kyber_r2 | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/pq-crypto/kyber_r2')
20 files changed, 2086 insertions, 2086 deletions
diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.c index b4fc010ca9..4e86526aaa 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.c @@ -1,51 +1,51 @@ -#include "cbd.h" -#include "params.h" - -#include <stddef.h> -#include <stdint.h> - -/************************************************* -* Name: load32_littleendian -* -* Description: load bytes into a 32-bit integer -* in little-endian order -* -* Arguments: - const uint8_t *x: pointer to input byte array -* -* Returns 32-bit unsigned integer loaded from x -**************************************************/ -static uint32_t load32_littleendian(const uint8_t *x) { - uint32_t r; - r = (uint32_t)x[0]; - r |= (uint32_t)x[1] << 8; - r |= (uint32_t)x[2] << 16; - r |= (uint32_t)x[3] << 24; - return r; -} - -/************************************************* -* Name: cbd -* -* Description: Given an array of uniformly random bytes, compute -* polynomial with coefficients distributed according to -* a centered binomial distribution with parameter KYBER_ETA -* specialized for KYBER_ETA=2 -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *buf: pointer to input byte array -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_cbd(poly *r, const uint8_t *buf) { - int16_t a, b; - - for (size_t i = 0; i < KYBER_N / 8; i++) { - uint32_t t = load32_littleendian(buf + 4 * i); - uint32_t d = t & 0x55555555; - d += (t >> 1) & 0x55555555; - - for (size_t j = 0; j < 8; j++) { - a = (d >> 4 * j) & 0x3; - b = (d >> (4 * j + 2)) & 0x3; - r->coeffs[8 * i + j] = a - b; - } - } -} +#include "cbd.h" +#include "params.h" + +#include <stddef.h> +#include <stdint.h> + +/************************************************* +* Name: load32_littleendian +* +* Description: load bytes into a 32-bit integer +* in little-endian order +* +* Arguments: - const uint8_t *x: pointer to input byte array +* +* Returns 32-bit unsigned integer loaded from x +**************************************************/ +static uint32_t load32_littleendian(const uint8_t *x) { + uint32_t r; + r = (uint32_t)x[0]; + r |= (uint32_t)x[1] << 8; + r |= (uint32_t)x[2] << 16; + r |= (uint32_t)x[3] << 24; + return r; +} + +/************************************************* +* Name: cbd +* +* Description: Given an array of uniformly random bytes, compute +* polynomial with coefficients distributed according to +* a centered binomial distribution with parameter KYBER_ETA +* specialized for KYBER_ETA=2 +* +* Arguments: - poly *r: pointer to output polynomial +* - const uint8_t *buf: pointer to input byte array +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_cbd(poly *r, const uint8_t *buf) { + int16_t a, b; + + for (size_t i = 0; i < KYBER_N / 8; i++) { + uint32_t t = load32_littleendian(buf + 4 * i); + uint32_t d = t & 0x55555555; + d += (t >> 1) & 0x55555555; + + for (size_t j = 0; j < 8; j++) { + a = (d >> 4 * j) & 0x3; + b = (d >> (4 * j + 2)) & 0x3; + r->coeffs[8 * i + j] = a - b; + } + } +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.h index 2eb5dc89cc..0891560aab 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/cbd.h @@ -1,8 +1,8 @@ -#ifndef CBD_H -#define CBD_H - -#include "poly.h" - -void PQCLEAN_KYBER512_CLEAN_cbd(poly *r, const uint8_t *buf); - -#endif +#ifndef CBD_H +#define CBD_H + +#include "poly.h" + +void PQCLEAN_KYBER512_CLEAN_cbd(poly *r, const uint8_t *buf); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.c index 2ba848f951..776bb21398 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.c @@ -1,619 +1,619 @@ -/* Based on the public domain implementation in - * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html - * by Ronny Van Keer - * and the public domain "TweetFips202" implementation - * from https://twitter.com/tweetfips202 - * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe - * SPDX-License-Identifier: Public domain - */ - -#include "fips202_kyber_r2.h" -#include "symmetric.h" - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#define PQC_SHAKEINCCTX_BYTES (sizeof(uint64_t)*26) -#define PQC_SHAKECTX_BYTES (sizeof(uint64_t)*25) - -#define NROUNDS 24 -#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset)))) - -/************************************************* - * Name: load64 - * - * Description: Load 8 bytes into uint64_t in little-endian order - * - * Arguments: - const uint8_t *x: pointer to input byte array - * - * Returns the loaded 64-bit unsigned integer - **************************************************/ -static uint64_t load64(const uint8_t *x) { - uint64_t r = 0; - for (size_t i = 0; i < 8; ++i) { - r |= (uint64_t)x[i] << 8 * i; - } - - return r; -} - -/************************************************* - * Name: store64 - * - * Description: Store a 64-bit integer to a byte array in little-endian order - * - * Arguments: - uint8_t *x: pointer to the output byte array - * - uint64_t u: input 64-bit unsigned integer - **************************************************/ -static void store64(uint8_t *x, uint64_t u) { - for (size_t i = 0; i < 8; ++i) { - x[i] = (uint8_t) (u >> 8 * i); - } -} - -/* Keccak round constants */ -static const uint64_t KeccakF_RoundConstants[NROUNDS] = { - 0x0000000000000001ULL, 0x0000000000008082ULL, - 0x800000000000808aULL, 0x8000000080008000ULL, - 0x000000000000808bULL, 0x0000000080000001ULL, - 0x8000000080008081ULL, 0x8000000000008009ULL, - 0x000000000000008aULL, 0x0000000000000088ULL, - 0x0000000080008009ULL, 0x000000008000000aULL, - 0x000000008000808bULL, 0x800000000000008bULL, - 0x8000000000008089ULL, 0x8000000000008003ULL, - 0x8000000000008002ULL, 0x8000000000000080ULL, - 0x000000000000800aULL, 0x800000008000000aULL, - 0x8000000080008081ULL, 0x8000000000008080ULL, - 0x0000000080000001ULL, 0x8000000080008008ULL -}; - -/************************************************* - * Name: KeccakF1600_StatePermute - * - * Description: The Keccak F1600 Permutation - * - * Arguments: - uint64_t *state: pointer to input/output Keccak state - **************************************************/ -static void KeccakF1600_StatePermute(uint64_t *state) { - int round; - - uint64_t Aba, Abe, Abi, Abo, Abu; - uint64_t Aga, Age, Agi, Ago, Agu; - uint64_t Aka, Ake, Aki, Ako, Aku; - uint64_t Ama, Ame, Ami, Amo, Amu; - uint64_t Asa, Ase, Asi, Aso, Asu; - uint64_t BCa, BCe, BCi, BCo, BCu; - - // copyFromState(A, state) - Aba = state[0]; - Abe = state[1]; - Abi = state[2]; - Abo = state[3]; - Abu = state[4]; - Aga = state[5]; - Age = state[6]; - Agi = state[7]; - Ago = state[8]; - Agu = state[9]; - Aka = state[10]; - Ake = state[11]; - Aki = state[12]; - Ako = state[13]; - Aku = state[14]; - Ama = state[15]; - Ame = state[16]; - Ami = state[17]; - Amo = state[18]; - Amu = state[19]; - Asa = state[20]; - Ase = state[21]; - Asi = state[22]; - Aso = state[23]; - Asu = state[24]; - - for (round = 0; round < NROUNDS; round += 2) { - uint64_t Da, De, Di, Do, Du; - uint64_t Eba, Ebe, Ebi, Ebo, Ebu; - uint64_t Ega, Ege, Egi, Ego, Egu; - uint64_t Eka, Eke, Eki, Eko, Eku; - uint64_t Ema, Eme, Emi, Emo, Emu; - uint64_t Esa, Ese, Esi, Eso, Esu; - - // prepareTheta - BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa; - BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase; - BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi; - BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso; - BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu; - - // thetaRhoPiChiIotaPrepareTheta(round , A, E) - Da = BCu ^ ROL(BCe, 1); - De = BCa ^ ROL(BCi, 1); - Di = BCe ^ ROL(BCo, 1); - Do = BCi ^ ROL(BCu, 1); - Du = BCo ^ ROL(BCa, 1); - - Aba ^= Da; - BCa = Aba; - Age ^= De; - BCe = ROL(Age, 44); - Aki ^= Di; - BCi = ROL(Aki, 43); - Amo ^= Do; - BCo = ROL(Amo, 21); - Asu ^= Du; - BCu = ROL(Asu, 14); - Eba = BCa ^ ((~BCe) & BCi); - Eba ^= KeccakF_RoundConstants[round]; - Ebe = BCe ^ ((~BCi) & BCo); - Ebi = BCi ^ ((~BCo) & BCu); - Ebo = BCo ^ ((~BCu) & BCa); - Ebu = BCu ^ ((~BCa) & BCe); - - Abo ^= Do; - BCa = ROL(Abo, 28); - Agu ^= Du; - BCe = ROL(Agu, 20); - Aka ^= Da; - BCi = ROL(Aka, 3); - Ame ^= De; - BCo = ROL(Ame, 45); - Asi ^= Di; - BCu = ROL(Asi, 61); - Ega = BCa ^ ((~BCe) & BCi); - Ege = BCe ^ ((~BCi) & BCo); - Egi = BCi ^ ((~BCo) & BCu); - Ego = BCo ^ ((~BCu) & BCa); - Egu = BCu ^ ((~BCa) & BCe); - - Abe ^= De; - BCa = ROL(Abe, 1); - Agi ^= Di; - BCe = ROL(Agi, 6); - Ako ^= Do; - BCi = ROL(Ako, 25); - Amu ^= Du; - BCo = ROL(Amu, 8); - Asa ^= Da; - BCu = ROL(Asa, 18); - Eka = BCa ^ ((~BCe) & BCi); - Eke = BCe ^ ((~BCi) & BCo); - Eki = BCi ^ ((~BCo) & BCu); - Eko = BCo ^ ((~BCu) & BCa); - Eku = BCu ^ ((~BCa) & BCe); - - Abu ^= Du; - BCa = ROL(Abu, 27); - Aga ^= Da; - BCe = ROL(Aga, 36); - Ake ^= De; - BCi = ROL(Ake, 10); - Ami ^= Di; - BCo = ROL(Ami, 15); - Aso ^= Do; - BCu = ROL(Aso, 56); - Ema = BCa ^ ((~BCe) & BCi); - Eme = BCe ^ ((~BCi) & BCo); - Emi = BCi ^ ((~BCo) & BCu); - Emo = BCo ^ ((~BCu) & BCa); - Emu = BCu ^ ((~BCa) & BCe); - - Abi ^= Di; - BCa = ROL(Abi, 62); - Ago ^= Do; - BCe = ROL(Ago, 55); - Aku ^= Du; - BCi = ROL(Aku, 39); - Ama ^= Da; - BCo = ROL(Ama, 41); - Ase ^= De; - BCu = ROL(Ase, 2); - Esa = BCa ^ ((~BCe) & BCi); - Ese = BCe ^ ((~BCi) & BCo); - Esi = BCi ^ ((~BCo) & BCu); - Eso = BCo ^ ((~BCu) & BCa); - Esu = BCu ^ ((~BCa) & BCe); - - // prepareTheta - BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa; - BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese; - BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi; - BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso; - BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu; - - // thetaRhoPiChiIotaPrepareTheta(round+1, E, A) - Da = BCu ^ ROL(BCe, 1); - De = BCa ^ ROL(BCi, 1); - Di = BCe ^ ROL(BCo, 1); - Do = BCi ^ ROL(BCu, 1); - Du = BCo ^ ROL(BCa, 1); - - Eba ^= Da; - BCa = Eba; - Ege ^= De; - BCe = ROL(Ege, 44); - Eki ^= Di; - BCi = ROL(Eki, 43); - Emo ^= Do; - BCo = ROL(Emo, 21); - Esu ^= Du; - BCu = ROL(Esu, 14); - Aba = BCa ^ ((~BCe) & BCi); - Aba ^= KeccakF_RoundConstants[round + 1]; - Abe = BCe ^ ((~BCi) & BCo); - Abi = BCi ^ ((~BCo) & BCu); - Abo = BCo ^ ((~BCu) & BCa); - Abu = BCu ^ ((~BCa) & BCe); - - Ebo ^= Do; - BCa = ROL(Ebo, 28); - Egu ^= Du; - BCe = ROL(Egu, 20); - Eka ^= Da; - BCi = ROL(Eka, 3); - Eme ^= De; - BCo = ROL(Eme, 45); - Esi ^= Di; - BCu = ROL(Esi, 61); - Aga = BCa ^ ((~BCe) & BCi); - Age = BCe ^ ((~BCi) & BCo); - Agi = BCi ^ ((~BCo) & BCu); - Ago = BCo ^ ((~BCu) & BCa); - Agu = BCu ^ ((~BCa) & BCe); - - Ebe ^= De; - BCa = ROL(Ebe, 1); - Egi ^= Di; - BCe = ROL(Egi, 6); - Eko ^= Do; - BCi = ROL(Eko, 25); - Emu ^= Du; - BCo = ROL(Emu, 8); - Esa ^= Da; - BCu = ROL(Esa, 18); - Aka = BCa ^ ((~BCe) & BCi); - Ake = BCe ^ ((~BCi) & BCo); - Aki = BCi ^ ((~BCo) & BCu); - Ako = BCo ^ ((~BCu) & BCa); - Aku = BCu ^ ((~BCa) & BCe); - - Ebu ^= Du; - BCa = ROL(Ebu, 27); - Ega ^= Da; - BCe = ROL(Ega, 36); - Eke ^= De; - BCi = ROL(Eke, 10); - Emi ^= Di; - BCo = ROL(Emi, 15); - Eso ^= Do; - BCu = ROL(Eso, 56); - Ama = BCa ^ ((~BCe) & BCi); - Ame = BCe ^ ((~BCi) & BCo); - Ami = BCi ^ ((~BCo) & BCu); - Amo = BCo ^ ((~BCu) & BCa); - Amu = BCu ^ ((~BCa) & BCe); - - Ebi ^= Di; - BCa = ROL(Ebi, 62); - Ego ^= Do; - BCe = ROL(Ego, 55); - Eku ^= Du; - BCi = ROL(Eku, 39); - Ema ^= Da; - BCo = ROL(Ema, 41); - Ese ^= De; - BCu = ROL(Ese, 2); - Asa = BCa ^ ((~BCe) & BCi); - Ase = BCe ^ ((~BCi) & BCo); - Asi = BCi ^ ((~BCo) & BCu); - Aso = BCo ^ ((~BCu) & BCa); - Asu = BCu ^ ((~BCa) & BCe); - } - - // copyToState(state, A) - state[0] = Aba; - state[1] = Abe; - state[2] = Abi; - state[3] = Abo; - state[4] = Abu; - state[5] = Aga; - state[6] = Age; - state[7] = Agi; - state[8] = Ago; - state[9] = Agu; - state[10] = Aka; - state[11] = Ake; - state[12] = Aki; - state[13] = Ako; - state[14] = Aku; - state[15] = Ama; - state[16] = Ame; - state[17] = Ami; - state[18] = Amo; - state[19] = Amu; - state[20] = Asa; - state[21] = Ase; - state[22] = Asi; - state[23] = Aso; - state[24] = Asu; -} - -/************************************************* - * Name: keccak_absorb - * - * Description: Absorb step of Keccak; - * non-incremental, starts by zeroeing the state. - * - * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state - * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128) - * - const uint8_t *m: pointer to input to be absorbed into s - * - size_t mlen: length of input in bytes - * - uint8_t p: domain-separation byte for different - * Keccak-derived functions - **************************************************/ -static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m, - size_t mlen, uint8_t p) { - size_t i; - uint8_t t[200]; - - /* Zero state */ - for (i = 0; i < 25; ++i) { - s[i] = 0; - } - - while (mlen >= r) { - for (i = 0; i < r / 8; ++i) { - s[i] ^= load64(m + 8 * i); - } - - KeccakF1600_StatePermute(s); - mlen -= r; - m += r; - } - - for (i = 0; i < r; ++i) { - t[i] = 0; - } - for (i = 0; i < mlen; ++i) { - t[i] = m[i]; - } - t[i] = p; - t[r - 1] |= 128; - for (i = 0; i < r / 8; ++i) { - s[i] ^= load64(t + 8 * i); - } -} - -/************************************************* - * Name: keccak_squeezeblocks - * - * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each. - * Modifies the state. Can be called multiple times to keep - * squeezing, i.e., is incremental. - * - * Arguments: - uint8_t *h: pointer to output blocks - * - size_t nblocks: number of blocks to be - * squeezed (written to h) - * - uint64_t *s: pointer to input/output Keccak state - * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128) - **************************************************/ -static void keccak_squeezeblocks(uint8_t *h, size_t nblocks, - uint64_t *s, uint32_t r) { - while (nblocks > 0) { - KeccakF1600_StatePermute(s); - for (size_t i = 0; i < (r >> 3); i++) { - store64(h + 8 * i, s[i]); - } - h += r; - nblocks--; - } -} - -/************************************************* - * Name: shake128_absorb - * - * Description: Absorb step of the SHAKE128 XOF. - * non-incremental, starts by zeroeing the state. - * - * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state - * - const uint8_t *input: pointer to input to be absorbed - * into s - * - size_t inlen: length of input in bytes - **************************************************/ -void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen) { - state->ctx = malloc(PQC_SHAKECTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } - keccak_absorb(state->ctx, SHAKE128_RATE, input, inlen, 0x1F); -} - -/************************************************* - * Name: shake128_squeezeblocks - * - * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of - * SHAKE128_RATE bytes each. Modifies the state. Can be called - * multiple times to keep squeezing, i.e., is incremental. - * - * Arguments: - uint8_t *output: pointer to output blocks - * - size_t nblocks: number of blocks to be squeezed - * (written to output) - * - shake128ctx *state: pointer to input/output Keccak state - **************************************************/ -void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state) { - keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE128_RATE); -} - -void shake128_ctx_clone(shake128ctx *dest, const shake128ctx *src) { - dest->ctx = malloc(PQC_SHAKECTX_BYTES); - if (dest->ctx == NULL) { - exit(111); - } - memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES); -} - -/** Release the allocated state. Call only once. */ -void shake128_ctx_release(shake128ctx *state) { - free(state->ctx); // IGNORE free-check -} - -/************************************************* - * Name: shake256_absorb - * - * Description: Absorb step of the SHAKE256 XOF. - * non-incremental, starts by zeroeing the state. - * - * Arguments: - shake256ctx *state: pointer to (uninitialized) output Keccak state - * - const uint8_t *input: pointer to input to be absorbed - * into s - * - size_t inlen: length of input in bytes - **************************************************/ -void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen) { - state->ctx = malloc(PQC_SHAKECTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } - keccak_absorb(state->ctx, SHAKE256_RATE, input, inlen, 0x1F); -} - -/************************************************* - * Name: shake256_squeezeblocks - * - * Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of - * SHAKE256_RATE bytes each. Modifies the state. Can be called - * multiple times to keep squeezing, i.e., is incremental. - * - * Arguments: - uint8_t *output: pointer to output blocks - * - size_t nblocks: number of blocks to be squeezed - * (written to output) - * - shake256ctx *state: pointer to input/output Keccak state - **************************************************/ -void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state) { - keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE256_RATE); -} - -void shake256_ctx_clone(shake256ctx *dest, const shake256ctx *src) { - dest->ctx = malloc(PQC_SHAKECTX_BYTES); - if (dest->ctx == NULL) { - exit(111); - } - memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES); -} - -/** Release the allocated state. Call only once. */ -void shake256_ctx_release(shake256ctx *state) { - free(state->ctx); // IGNORE free-check -} - -/************************************************* - * Name: shake128 - * - * Description: SHAKE128 XOF with non-incremental API - * - * Arguments: - uint8_t *output: pointer to output - * - size_t outlen: requested output length in bytes - * - const uint8_t *input: pointer to input - * - size_t inlen: length of input in bytes - **************************************************/ -void shake128(uint8_t *output, size_t outlen, - const uint8_t *input, size_t inlen) { - size_t nblocks = outlen / SHAKE128_RATE; - uint8_t t[SHAKE128_RATE]; - shake128ctx s; - - shake128_absorb(&s, input, inlen); - shake128_squeezeblocks(output, nblocks, &s); - - output += nblocks * SHAKE128_RATE; - outlen -= nblocks * SHAKE128_RATE; - - if (outlen) { - shake128_squeezeblocks(t, 1, &s); - for (size_t i = 0; i < outlen; ++i) { - output[i] = t[i]; - } - } - shake128_ctx_release(&s); -} - -/************************************************* - * Name: shake256 - * - * Description: SHAKE256 XOF with non-incremental API - * - * Arguments: - uint8_t *output: pointer to output - * - size_t outlen: requested output length in bytes - * - const uint8_t *input: pointer to input - * - size_t inlen: length of input in bytes - **************************************************/ -void shake256_kyber(uint8_t *output, size_t outlen, - const uint8_t *input, size_t inlen) { - size_t nblocks = outlen / SHAKE256_RATE; - uint8_t t[SHAKE256_RATE]; - shake256ctx s; - - shake256_absorb(&s, input, inlen); - shake256_squeezeblocks(output, nblocks, &s); - - output += nblocks * SHAKE256_RATE; - outlen -= nblocks * SHAKE256_RATE; - - if (outlen) { - shake256_squeezeblocks(t, 1, &s); - for (size_t i = 0; i < outlen; ++i) { - output[i] = t[i]; - } - } - shake256_ctx_release(&s); -} - -/************************************************* - * Name: sha3_256 - * - * Description: SHA3-256 with non-incremental API - * - * Arguments: - uint8_t *output: pointer to output - * - const uint8_t *input: pointer to input - * - size_t inlen: length of input in bytes - **************************************************/ -void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { - uint64_t s[25]; - uint8_t t[SHA3_256_RATE]; - - /* Absorb input */ - keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06); - - /* Squeeze output */ - keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); - - for (size_t i = 0; i < 32; i++) { - output[i] = t[i]; - } -} - - -/************************************************* - * Name: sha3_512 - * - * Description: SHA3-512 with non-incremental API - * - * Arguments: - uint8_t *output: pointer to output - * - const uint8_t *input: pointer to input - * - size_t inlen: length of input in bytes - **************************************************/ -void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { - uint64_t s[25]; - uint8_t t[SHA3_512_RATE]; - - /* Absorb input */ - keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06); - - /* Squeeze output */ - keccak_squeezeblocks(t, 1, s, SHA3_512_RATE); - - for (size_t i = 0; i < 64; i++) { - output[i] = t[i]; - } -} +/* Based on the public domain implementation in + * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html + * by Ronny Van Keer + * and the public domain "TweetFips202" implementation + * from https://twitter.com/tweetfips202 + * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe + * SPDX-License-Identifier: Public domain + */ + +#include "fips202_kyber_r2.h" +#include "symmetric.h" + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define PQC_SHAKEINCCTX_BYTES (sizeof(uint64_t)*26) +#define PQC_SHAKECTX_BYTES (sizeof(uint64_t)*25) + +#define NROUNDS 24 +#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset)))) + +/************************************************* + * Name: load64 + * + * Description: Load 8 bytes into uint64_t in little-endian order + * + * Arguments: - const uint8_t *x: pointer to input byte array + * + * Returns the loaded 64-bit unsigned integer + **************************************************/ +static uint64_t load64(const uint8_t *x) { + uint64_t r = 0; + for (size_t i = 0; i < 8; ++i) { + r |= (uint64_t)x[i] << 8 * i; + } + + return r; +} + +/************************************************* + * Name: store64 + * + * Description: Store a 64-bit integer to a byte array in little-endian order + * + * Arguments: - uint8_t *x: pointer to the output byte array + * - uint64_t u: input 64-bit unsigned integer + **************************************************/ +static void store64(uint8_t *x, uint64_t u) { + for (size_t i = 0; i < 8; ++i) { + x[i] = (uint8_t) (u >> 8 * i); + } +} + +/* Keccak round constants */ +static const uint64_t KeccakF_RoundConstants[NROUNDS] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL +}; + +/************************************************* + * Name: KeccakF1600_StatePermute + * + * Description: The Keccak F1600 Permutation + * + * Arguments: - uint64_t *state: pointer to input/output Keccak state + **************************************************/ +static void KeccakF1600_StatePermute(uint64_t *state) { + int round; + + uint64_t Aba, Abe, Abi, Abo, Abu; + uint64_t Aga, Age, Agi, Ago, Agu; + uint64_t Aka, Ake, Aki, Ako, Aku; + uint64_t Ama, Ame, Ami, Amo, Amu; + uint64_t Asa, Ase, Asi, Aso, Asu; + uint64_t BCa, BCe, BCi, BCo, BCu; + + // copyFromState(A, state) + Aba = state[0]; + Abe = state[1]; + Abi = state[2]; + Abo = state[3]; + Abu = state[4]; + Aga = state[5]; + Age = state[6]; + Agi = state[7]; + Ago = state[8]; + Agu = state[9]; + Aka = state[10]; + Ake = state[11]; + Aki = state[12]; + Ako = state[13]; + Aku = state[14]; + Ama = state[15]; + Ame = state[16]; + Ami = state[17]; + Amo = state[18]; + Amu = state[19]; + Asa = state[20]; + Ase = state[21]; + Asi = state[22]; + Aso = state[23]; + Asu = state[24]; + + for (round = 0; round < NROUNDS; round += 2) { + uint64_t Da, De, Di, Do, Du; + uint64_t Eba, Ebe, Ebi, Ebo, Ebu; + uint64_t Ega, Ege, Egi, Ego, Egu; + uint64_t Eka, Eke, Eki, Eko, Eku; + uint64_t Ema, Eme, Emi, Emo, Emu; + uint64_t Esa, Ese, Esi, Eso, Esu; + + // prepareTheta + BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa; + BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase; + BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi; + BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso; + BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu; + + // thetaRhoPiChiIotaPrepareTheta(round , A, E) + Da = BCu ^ ROL(BCe, 1); + De = BCa ^ ROL(BCi, 1); + Di = BCe ^ ROL(BCo, 1); + Do = BCi ^ ROL(BCu, 1); + Du = BCo ^ ROL(BCa, 1); + + Aba ^= Da; + BCa = Aba; + Age ^= De; + BCe = ROL(Age, 44); + Aki ^= Di; + BCi = ROL(Aki, 43); + Amo ^= Do; + BCo = ROL(Amo, 21); + Asu ^= Du; + BCu = ROL(Asu, 14); + Eba = BCa ^ ((~BCe) & BCi); + Eba ^= KeccakF_RoundConstants[round]; + Ebe = BCe ^ ((~BCi) & BCo); + Ebi = BCi ^ ((~BCo) & BCu); + Ebo = BCo ^ ((~BCu) & BCa); + Ebu = BCu ^ ((~BCa) & BCe); + + Abo ^= Do; + BCa = ROL(Abo, 28); + Agu ^= Du; + BCe = ROL(Agu, 20); + Aka ^= Da; + BCi = ROL(Aka, 3); + Ame ^= De; + BCo = ROL(Ame, 45); + Asi ^= Di; + BCu = ROL(Asi, 61); + Ega = BCa ^ ((~BCe) & BCi); + Ege = BCe ^ ((~BCi) & BCo); + Egi = BCi ^ ((~BCo) & BCu); + Ego = BCo ^ ((~BCu) & BCa); + Egu = BCu ^ ((~BCa) & BCe); + + Abe ^= De; + BCa = ROL(Abe, 1); + Agi ^= Di; + BCe = ROL(Agi, 6); + Ako ^= Do; + BCi = ROL(Ako, 25); + Amu ^= Du; + BCo = ROL(Amu, 8); + Asa ^= Da; + BCu = ROL(Asa, 18); + Eka = BCa ^ ((~BCe) & BCi); + Eke = BCe ^ ((~BCi) & BCo); + Eki = BCi ^ ((~BCo) & BCu); + Eko = BCo ^ ((~BCu) & BCa); + Eku = BCu ^ ((~BCa) & BCe); + + Abu ^= Du; + BCa = ROL(Abu, 27); + Aga ^= Da; + BCe = ROL(Aga, 36); + Ake ^= De; + BCi = ROL(Ake, 10); + Ami ^= Di; + BCo = ROL(Ami, 15); + Aso ^= Do; + BCu = ROL(Aso, 56); + Ema = BCa ^ ((~BCe) & BCi); + Eme = BCe ^ ((~BCi) & BCo); + Emi = BCi ^ ((~BCo) & BCu); + Emo = BCo ^ ((~BCu) & BCa); + Emu = BCu ^ ((~BCa) & BCe); + + Abi ^= Di; + BCa = ROL(Abi, 62); + Ago ^= Do; + BCe = ROL(Ago, 55); + Aku ^= Du; + BCi = ROL(Aku, 39); + Ama ^= Da; + BCo = ROL(Ama, 41); + Ase ^= De; + BCu = ROL(Ase, 2); + Esa = BCa ^ ((~BCe) & BCi); + Ese = BCe ^ ((~BCi) & BCo); + Esi = BCi ^ ((~BCo) & BCu); + Eso = BCo ^ ((~BCu) & BCa); + Esu = BCu ^ ((~BCa) & BCe); + + // prepareTheta + BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa; + BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese; + BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi; + BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso; + BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu; + + // thetaRhoPiChiIotaPrepareTheta(round+1, E, A) + Da = BCu ^ ROL(BCe, 1); + De = BCa ^ ROL(BCi, 1); + Di = BCe ^ ROL(BCo, 1); + Do = BCi ^ ROL(BCu, 1); + Du = BCo ^ ROL(BCa, 1); + + Eba ^= Da; + BCa = Eba; + Ege ^= De; + BCe = ROL(Ege, 44); + Eki ^= Di; + BCi = ROL(Eki, 43); + Emo ^= Do; + BCo = ROL(Emo, 21); + Esu ^= Du; + BCu = ROL(Esu, 14); + Aba = BCa ^ ((~BCe) & BCi); + Aba ^= KeccakF_RoundConstants[round + 1]; + Abe = BCe ^ ((~BCi) & BCo); + Abi = BCi ^ ((~BCo) & BCu); + Abo = BCo ^ ((~BCu) & BCa); + Abu = BCu ^ ((~BCa) & BCe); + + Ebo ^= Do; + BCa = ROL(Ebo, 28); + Egu ^= Du; + BCe = ROL(Egu, 20); + Eka ^= Da; + BCi = ROL(Eka, 3); + Eme ^= De; + BCo = ROL(Eme, 45); + Esi ^= Di; + BCu = ROL(Esi, 61); + Aga = BCa ^ ((~BCe) & BCi); + Age = BCe ^ ((~BCi) & BCo); + Agi = BCi ^ ((~BCo) & BCu); + Ago = BCo ^ ((~BCu) & BCa); + Agu = BCu ^ ((~BCa) & BCe); + + Ebe ^= De; + BCa = ROL(Ebe, 1); + Egi ^= Di; + BCe = ROL(Egi, 6); + Eko ^= Do; + BCi = ROL(Eko, 25); + Emu ^= Du; + BCo = ROL(Emu, 8); + Esa ^= Da; + BCu = ROL(Esa, 18); + Aka = BCa ^ ((~BCe) & BCi); + Ake = BCe ^ ((~BCi) & BCo); + Aki = BCi ^ ((~BCo) & BCu); + Ako = BCo ^ ((~BCu) & BCa); + Aku = BCu ^ ((~BCa) & BCe); + + Ebu ^= Du; + BCa = ROL(Ebu, 27); + Ega ^= Da; + BCe = ROL(Ega, 36); + Eke ^= De; + BCi = ROL(Eke, 10); + Emi ^= Di; + BCo = ROL(Emi, 15); + Eso ^= Do; + BCu = ROL(Eso, 56); + Ama = BCa ^ ((~BCe) & BCi); + Ame = BCe ^ ((~BCi) & BCo); + Ami = BCi ^ ((~BCo) & BCu); + Amo = BCo ^ ((~BCu) & BCa); + Amu = BCu ^ ((~BCa) & BCe); + + Ebi ^= Di; + BCa = ROL(Ebi, 62); + Ego ^= Do; + BCe = ROL(Ego, 55); + Eku ^= Du; + BCi = ROL(Eku, 39); + Ema ^= Da; + BCo = ROL(Ema, 41); + Ese ^= De; + BCu = ROL(Ese, 2); + Asa = BCa ^ ((~BCe) & BCi); + Ase = BCe ^ ((~BCi) & BCo); + Asi = BCi ^ ((~BCo) & BCu); + Aso = BCo ^ ((~BCu) & BCa); + Asu = BCu ^ ((~BCa) & BCe); + } + + // copyToState(state, A) + state[0] = Aba; + state[1] = Abe; + state[2] = Abi; + state[3] = Abo; + state[4] = Abu; + state[5] = Aga; + state[6] = Age; + state[7] = Agi; + state[8] = Ago; + state[9] = Agu; + state[10] = Aka; + state[11] = Ake; + state[12] = Aki; + state[13] = Ako; + state[14] = Aku; + state[15] = Ama; + state[16] = Ame; + state[17] = Ami; + state[18] = Amo; + state[19] = Amu; + state[20] = Asa; + state[21] = Ase; + state[22] = Asi; + state[23] = Aso; + state[24] = Asu; +} + +/************************************************* + * Name: keccak_absorb + * + * Description: Absorb step of Keccak; + * non-incremental, starts by zeroeing the state. + * + * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state + * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128) + * - const uint8_t *m: pointer to input to be absorbed into s + * - size_t mlen: length of input in bytes + * - uint8_t p: domain-separation byte for different + * Keccak-derived functions + **************************************************/ +static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m, + size_t mlen, uint8_t p) { + size_t i; + uint8_t t[200]; + + /* Zero state */ + for (i = 0; i < 25; ++i) { + s[i] = 0; + } + + while (mlen >= r) { + for (i = 0; i < r / 8; ++i) { + s[i] ^= load64(m + 8 * i); + } + + KeccakF1600_StatePermute(s); + mlen -= r; + m += r; + } + + for (i = 0; i < r; ++i) { + t[i] = 0; + } + for (i = 0; i < mlen; ++i) { + t[i] = m[i]; + } + t[i] = p; + t[r - 1] |= 128; + for (i = 0; i < r / 8; ++i) { + s[i] ^= load64(t + 8 * i); + } +} + +/************************************************* + * Name: keccak_squeezeblocks + * + * Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each. + * Modifies the state. Can be called multiple times to keep + * squeezing, i.e., is incremental. + * + * Arguments: - uint8_t *h: pointer to output blocks + * - size_t nblocks: number of blocks to be + * squeezed (written to h) + * - uint64_t *s: pointer to input/output Keccak state + * - uint32_t r: rate in bytes (e.g., 168 for SHAKE128) + **************************************************/ +static void keccak_squeezeblocks(uint8_t *h, size_t nblocks, + uint64_t *s, uint32_t r) { + while (nblocks > 0) { + KeccakF1600_StatePermute(s); + for (size_t i = 0; i < (r >> 3); i++) { + store64(h + 8 * i, s[i]); + } + h += r; + nblocks--; + } +} + +/************************************************* + * Name: shake128_absorb + * + * Description: Absorb step of the SHAKE128 XOF. + * non-incremental, starts by zeroeing the state. + * + * Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state + * - const uint8_t *input: pointer to input to be absorbed + * into s + * - size_t inlen: length of input in bytes + **************************************************/ +void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen) { + state->ctx = malloc(PQC_SHAKECTX_BYTES); + if (state->ctx == NULL) { + exit(111); + } + keccak_absorb(state->ctx, SHAKE128_RATE, input, inlen, 0x1F); +} + +/************************************************* + * Name: shake128_squeezeblocks + * + * Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of + * SHAKE128_RATE bytes each. Modifies the state. Can be called + * multiple times to keep squeezing, i.e., is incremental. + * + * Arguments: - uint8_t *output: pointer to output blocks + * - size_t nblocks: number of blocks to be squeezed + * (written to output) + * - shake128ctx *state: pointer to input/output Keccak state + **************************************************/ +void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state) { + keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE128_RATE); +} + +void shake128_ctx_clone(shake128ctx *dest, const shake128ctx *src) { + dest->ctx = malloc(PQC_SHAKECTX_BYTES); + if (dest->ctx == NULL) { + exit(111); + } + memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES); +} + +/** Release the allocated state. Call only once. */ +void shake128_ctx_release(shake128ctx *state) { + free(state->ctx); // IGNORE free-check +} + +/************************************************* + * Name: shake256_absorb + * + * Description: Absorb step of the SHAKE256 XOF. + * non-incremental, starts by zeroeing the state. + * + * Arguments: - shake256ctx *state: pointer to (uninitialized) output Keccak state + * - const uint8_t *input: pointer to input to be absorbed + * into s + * - size_t inlen: length of input in bytes + **************************************************/ +void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen) { + state->ctx = malloc(PQC_SHAKECTX_BYTES); + if (state->ctx == NULL) { + exit(111); + } + keccak_absorb(state->ctx, SHAKE256_RATE, input, inlen, 0x1F); +} + +/************************************************* + * Name: shake256_squeezeblocks + * + * Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of + * SHAKE256_RATE bytes each. Modifies the state. Can be called + * multiple times to keep squeezing, i.e., is incremental. + * + * Arguments: - uint8_t *output: pointer to output blocks + * - size_t nblocks: number of blocks to be squeezed + * (written to output) + * - shake256ctx *state: pointer to input/output Keccak state + **************************************************/ +void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state) { + keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE256_RATE); +} + +void shake256_ctx_clone(shake256ctx *dest, const shake256ctx *src) { + dest->ctx = malloc(PQC_SHAKECTX_BYTES); + if (dest->ctx == NULL) { + exit(111); + } + memcpy(dest->ctx, src->ctx, PQC_SHAKECTX_BYTES); +} + +/** Release the allocated state. Call only once. */ +void shake256_ctx_release(shake256ctx *state) { + free(state->ctx); // IGNORE free-check +} + +/************************************************* + * Name: shake128 + * + * Description: SHAKE128 XOF with non-incremental API + * + * Arguments: - uint8_t *output: pointer to output + * - size_t outlen: requested output length in bytes + * - const uint8_t *input: pointer to input + * - size_t inlen: length of input in bytes + **************************************************/ +void shake128(uint8_t *output, size_t outlen, + const uint8_t *input, size_t inlen) { + size_t nblocks = outlen / SHAKE128_RATE; + uint8_t t[SHAKE128_RATE]; + shake128ctx s; + + shake128_absorb(&s, input, inlen); + shake128_squeezeblocks(output, nblocks, &s); + + output += nblocks * SHAKE128_RATE; + outlen -= nblocks * SHAKE128_RATE; + + if (outlen) { + shake128_squeezeblocks(t, 1, &s); + for (size_t i = 0; i < outlen; ++i) { + output[i] = t[i]; + } + } + shake128_ctx_release(&s); +} + +/************************************************* + * Name: shake256 + * + * Description: SHAKE256 XOF with non-incremental API + * + * Arguments: - uint8_t *output: pointer to output + * - size_t outlen: requested output length in bytes + * - const uint8_t *input: pointer to input + * - size_t inlen: length of input in bytes + **************************************************/ +void shake256_kyber(uint8_t *output, size_t outlen, + const uint8_t *input, size_t inlen) { + size_t nblocks = outlen / SHAKE256_RATE; + uint8_t t[SHAKE256_RATE]; + shake256ctx s; + + shake256_absorb(&s, input, inlen); + shake256_squeezeblocks(output, nblocks, &s); + + output += nblocks * SHAKE256_RATE; + outlen -= nblocks * SHAKE256_RATE; + + if (outlen) { + shake256_squeezeblocks(t, 1, &s); + for (size_t i = 0; i < outlen; ++i) { + output[i] = t[i]; + } + } + shake256_ctx_release(&s); +} + +/************************************************* + * Name: sha3_256 + * + * Description: SHA3-256 with non-incremental API + * + * Arguments: - uint8_t *output: pointer to output + * - const uint8_t *input: pointer to input + * - size_t inlen: length of input in bytes + **************************************************/ +void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { + uint64_t s[25]; + uint8_t t[SHA3_256_RATE]; + + /* Absorb input */ + keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06); + + /* Squeeze output */ + keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); + + for (size_t i = 0; i < 32; i++) { + output[i] = t[i]; + } +} + + +/************************************************* + * Name: sha3_512 + * + * Description: SHA3-512 with non-incremental API + * + * Arguments: - uint8_t *output: pointer to output + * - const uint8_t *input: pointer to input + * - size_t inlen: length of input in bytes + **************************************************/ +void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { + uint64_t s[25]; + uint8_t t[SHA3_512_RATE]; + + /* Absorb input */ + keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06); + + /* Squeeze output */ + keccak_squeezeblocks(t, 1, s, SHA3_512_RATE); + + for (size_t i = 0; i < 64; i++) { + output[i] = t[i]; + } +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.h index d9a39e2ec1..80788b3e10 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/fips202_kyber_r2.h @@ -1,36 +1,36 @@ -// SPDX-License-Identifier: MIT - -#ifndef FIPS202_KYBER_R2_H -#define FIPS202_KYBER_R2_H - -#include <stdint.h> -#include <stddef.h> - -/** Data structure for the state of the SHAKE128 non-incremental hashing API. */ -typedef struct { - /** Internal state. */ - void *ctx; -} shake128ctx; - -/** Data structure for the state of the SHAKE256 non-incremental hashing API. */ -typedef struct { - /** Internal state. */ - void *ctx; -} shake256ctx; - -typedef shake128ctx keccak_state; - - -#define SHAKE128_RATE 168 -#define SHAKE256_RATE 136 -#define SHA3_256_RATE 136 -#define SHA3_512_RATE 72 - -void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen); -void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state); -void shake256_kyber(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen); -void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen); -void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen); -void shake128_ctx_release(shake128ctx *state); - -#endif // FIPS202_KYBER_R2_H +// SPDX-License-Identifier: MIT + +#ifndef FIPS202_KYBER_R2_H +#define FIPS202_KYBER_R2_H + +#include <stdint.h> +#include <stddef.h> + +/** Data structure for the state of the SHAKE128 non-incremental hashing API. */ +typedef struct { + /** Internal state. */ + void *ctx; +} shake128ctx; + +/** Data structure for the state of the SHAKE256 non-incremental hashing API. */ +typedef struct { + /** Internal state. */ + void *ctx; +} shake256ctx; + +typedef shake128ctx keccak_state; + + +#define SHAKE128_RATE 168 +#define SHAKE256_RATE 136 +#define SHA3_256_RATE 136 +#define SHA3_512_RATE 72 + +void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen); +void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state); +void shake256_kyber(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen); +void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen); +void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen); +void shake128_ctx_release(shake128ctx *state); + +#endif // FIPS202_KYBER_R2_H diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.c index 233b5d8515..18a980978d 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.c @@ -1,301 +1,301 @@ -#include "indcpa.h" -#include "ntt.h" -#include "params.h" -#include "poly.h" -#include "polyvec.h" -#include "../s2n_pq_random.h" -#include "utils/s2n_safety.h" -#include "symmetric.h" - -#include <stdint.h> - -/************************************************* -* Name: pack_pk -* -* Description: Serialize the public key as concatenation of the -* serialized vector of polynomials pk -* and the public seed used to generate the matrix A. -* -* Arguments: uint8_t *r: pointer to the output serialized public key -* const poly *pk: pointer to the input public-key polynomial -* const uint8_t *seed: pointer to the input public seed -**************************************************/ -static void pack_pk(uint8_t *r, polyvec *pk, const uint8_t *seed) { - PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(r, pk); - for (size_t i = 0; i < KYBER_SYMBYTES; i++) { - r[i + KYBER_POLYVECBYTES] = seed[i]; - } -} - -/************************************************* -* Name: unpack_pk -* -* Description: De-serialize public key from a byte array; -* approximate inverse of pack_pk -* -* Arguments: - polyvec *pk: pointer to output public-key vector of polynomials -* - uint8_t *seed: pointer to output seed to generate matrix A -* - const uint8_t *packedpk: pointer to input serialized public key -**************************************************/ -static void unpack_pk(polyvec *pk, uint8_t *seed, const uint8_t *packedpk) { - PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(pk, packedpk); - for (size_t i = 0; i < KYBER_SYMBYTES; i++) { - seed[i] = packedpk[i + KYBER_POLYVECBYTES]; - } -} - -/************************************************* -* Name: pack_sk -* -* Description: Serialize the secret key -* -* Arguments: - uint8_t *r: pointer to output serialized secret key -* - const polyvec *sk: pointer to input vector of polynomials (secret key) -**************************************************/ -static void pack_sk(uint8_t *r, polyvec *sk) { - PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(r, sk); -} - -/************************************************* -* Name: unpack_sk -* -* Description: De-serialize the secret key; -* inverse of pack_sk -* -* Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key) -* - const uint8_t *packedsk: pointer to input serialized secret key -**************************************************/ -static void unpack_sk(polyvec *sk, const uint8_t *packedsk) { - PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(sk, packedsk); -} - -/************************************************* -* Name: pack_ciphertext -* -* Description: Serialize the ciphertext as concatenation of the -* compressed and serialized vector of polynomials b -* and the compressed and serialized polynomial v -* -* Arguments: uint8_t *r: pointer to the output serialized ciphertext -* const poly *pk: pointer to the input vector of polynomials b -* const uint8_t *seed: pointer to the input polynomial v -**************************************************/ -static void pack_ciphertext(uint8_t *r, polyvec *b, poly *v) { - PQCLEAN_KYBER512_CLEAN_polyvec_compress(r, b); - PQCLEAN_KYBER512_CLEAN_poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v); -} - -/************************************************* -* Name: unpack_ciphertext -* -* Description: De-serialize and decompress ciphertext from a byte array; -* approximate inverse of pack_ciphertext -* -* Arguments: - polyvec *b: pointer to the output vector of polynomials b -* - poly *v: pointer to the output polynomial v -* - const uint8_t *c: pointer to the input serialized ciphertext -**************************************************/ -static void unpack_ciphertext(polyvec *b, poly *v, const uint8_t *c) { - PQCLEAN_KYBER512_CLEAN_polyvec_decompress(b, c); - PQCLEAN_KYBER512_CLEAN_poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES); -} - -/************************************************* -* Name: rej_uniform -* -* Description: Run rejection sampling on uniform random bytes to generate -* uniform random integers mod q -* -* Arguments: - int16_t *r: pointer to output buffer -* - size_t len: requested number of 16-bit integers (uniform mod q) -* - const uint8_t *buf: pointer to input buffer (assumed to be uniform random bytes) -* - size_t buflen: length of input buffer in bytes -* -* Returns number of sampled 16-bit integers (at most len) -**************************************************/ -static size_t rej_uniform(int16_t *r, size_t len, const uint8_t *buf, size_t buflen) { - size_t ctr, pos; - - ctr = pos = 0; - while (ctr < len && pos + 2 <= buflen) { - uint16_t val = (uint16_t)(buf[pos] | ((uint16_t)buf[pos + 1] << 8)); - pos += 2; - - if (val < 19 * KYBER_Q) { - val -= (uint16_t)((val >> 12) * KYBER_Q); // Barrett reduction - r[ctr++] = (int16_t)val; - } - } - - return ctr; -} - -#define gen_a(A,B) gen_matrix(A,B,0) -#define gen_at(A,B) gen_matrix(A,B,1) - -/************************************************* -* Name: gen_matrix -* -* Description: Deterministically generate matrix A (or the transpose of A) -* from a seed. Entries of the matrix are polynomials that look -* uniformly random. Performs rejection sampling on output of -* a XOF -* -* Arguments: - polyvec *a: pointer to ouptput matrix A -* - const uint8_t *seed: pointer to input seed -* - int transposed: boolean deciding whether A or A^T is generated -**************************************************/ -#define MAXNBLOCKS ((530+XOF_BLOCKBYTES)/XOF_BLOCKBYTES) /* 530 is expected number of required bytes */ -static void gen_matrix(polyvec *a, const uint8_t *seed, int transposed) { - size_t ctr; - uint8_t i, j; - uint8_t buf[XOF_BLOCKBYTES * MAXNBLOCKS + 1]; - xof_state state; - - for (i = 0; i < KYBER_K; i++) { - for (j = 0; j < KYBER_K; j++) { - if (transposed) { - xof_absorb(&state, seed, i, j); - } else { - xof_absorb(&state, seed, j, i); - } - - xof_squeezeblocks(buf, MAXNBLOCKS, &state); - ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, MAXNBLOCKS * XOF_BLOCKBYTES); - - while (ctr < KYBER_N) { - xof_squeezeblocks(buf, 1, &state); - ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, XOF_BLOCKBYTES); - } - xof_ctx_release(&state); - } - } -} - -/************************************************* -* Name: indcpa_keypair -* -* Description: Generates public and private key for the CPA-secure -* public-key encryption scheme underlying Kyber -* -* Arguments: - uint8_t *pk: pointer to output public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) -* - uint8_t *sk: pointer to output private key (of length KYBER_INDCPA_SECRETKEYBYTES bytes) -**************************************************/ -int PQCLEAN_KYBER512_CLEAN_indcpa_keypair(uint8_t *pk, uint8_t *sk) { - polyvec a[KYBER_K], e, pkpv, skpv; - uint8_t buf[2 * KYBER_SYMBYTES]; - uint8_t *publicseed = buf; - uint8_t *noiseseed = buf + KYBER_SYMBYTES; - uint8_t nonce = 0; - - GUARD_AS_POSIX(s2n_get_random_bytes(buf, KYBER_SYMBYTES)); - hash_g(buf, buf, KYBER_SYMBYTES); - - gen_a(a, publicseed); - - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_getnoise(skpv.vec + i, noiseseed, nonce++); - } - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_getnoise(e.vec + i, noiseseed, nonce++); - } - - PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&skpv); - PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&e); - - // matrix-vector multiplication - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&pkpv.vec[i], &a[i], &skpv); - PQCLEAN_KYBER512_CLEAN_poly_frommont(&pkpv.vec[i]); - } - - PQCLEAN_KYBER512_CLEAN_polyvec_add(&pkpv, &pkpv, &e); - PQCLEAN_KYBER512_CLEAN_polyvec_reduce(&pkpv); - - pack_sk(sk, &skpv); - pack_pk(pk, &pkpv, publicseed); - return 0; -} - -/************************************************* -* Name: indcpa_enc -* -* Description: Encryption function of the CPA-secure -* public-key encryption scheme underlying Kyber. -* -* Arguments: - uint8_t *c: pointer to output ciphertext (of length KYBER_INDCPA_BYTES bytes) -* - const uint8_t *m: pointer to input message (of length KYBER_INDCPA_MSGBYTES bytes) -* - const uint8_t *pk: pointer to input public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) -* - const uint8_t *coin: pointer to input random coins used as seed (of length KYBER_SYMBYTES bytes) -* to deterministically generate all randomness -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_indcpa_enc(uint8_t *c, - const uint8_t *m, - const uint8_t *pk, - const uint8_t *coins) { - polyvec sp, pkpv, ep, at[KYBER_K], bp; - poly v, k, epp; - uint8_t seed[KYBER_SYMBYTES]; - uint8_t nonce = 0; - - unpack_pk(&pkpv, seed, pk); - PQCLEAN_KYBER512_CLEAN_poly_frommsg(&k, m); - gen_at(at, seed); - - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_getnoise(sp.vec + i, coins, nonce++); - } - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_getnoise(ep.vec + i, coins, nonce++); - } - PQCLEAN_KYBER512_CLEAN_poly_getnoise(&epp, coins, nonce++); - - PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&sp); - - // matrix-vector multiplication - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&bp.vec[i], &at[i], &sp); - } - - PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&v, &pkpv, &sp); - - PQCLEAN_KYBER512_CLEAN_polyvec_invntt(&bp); - PQCLEAN_KYBER512_CLEAN_poly_invntt(&v); - - PQCLEAN_KYBER512_CLEAN_polyvec_add(&bp, &bp, &ep); - PQCLEAN_KYBER512_CLEAN_poly_add(&v, &v, &epp); - PQCLEAN_KYBER512_CLEAN_poly_add(&v, &v, &k); - PQCLEAN_KYBER512_CLEAN_polyvec_reduce(&bp); - PQCLEAN_KYBER512_CLEAN_poly_reduce(&v); - - pack_ciphertext(c, &bp, &v); -} - -/************************************************* -* Name: indcpa_dec -* -* Description: Decryption function of the CPA-secure -* public-key encryption scheme underlying Kyber. -* -* Arguments: - uint8_t *m: pointer to output decrypted message (of length KYBER_INDCPA_MSGBYTES) -* - const uint8_t *c: pointer to input ciphertext (of length KYBER_INDCPA_BYTES) -* - const uint8_t *sk: pointer to input secret key (of length KYBER_INDCPA_SECRETKEYBYTES) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_indcpa_dec(uint8_t *m, - const uint8_t *c, - const uint8_t *sk) { - polyvec bp, skpv; - poly v, mp; - - unpack_ciphertext(&bp, &v, c); - unpack_sk(&skpv, sk); - - PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&bp); - PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&mp, &skpv, &bp); - PQCLEAN_KYBER512_CLEAN_poly_invntt(&mp); - - PQCLEAN_KYBER512_CLEAN_poly_sub(&mp, &v, &mp); - PQCLEAN_KYBER512_CLEAN_poly_reduce(&mp); - - PQCLEAN_KYBER512_CLEAN_poly_tomsg(m, &mp); -} +#include "indcpa.h" +#include "ntt.h" +#include "params.h" +#include "poly.h" +#include "polyvec.h" +#include "../s2n_pq_random.h" +#include "utils/s2n_safety.h" +#include "symmetric.h" + +#include <stdint.h> + +/************************************************* +* Name: pack_pk +* +* Description: Serialize the public key as concatenation of the +* serialized vector of polynomials pk +* and the public seed used to generate the matrix A. +* +* Arguments: uint8_t *r: pointer to the output serialized public key +* const poly *pk: pointer to the input public-key polynomial +* const uint8_t *seed: pointer to the input public seed +**************************************************/ +static void pack_pk(uint8_t *r, polyvec *pk, const uint8_t *seed) { + PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(r, pk); + for (size_t i = 0; i < KYBER_SYMBYTES; i++) { + r[i + KYBER_POLYVECBYTES] = seed[i]; + } +} + +/************************************************* +* Name: unpack_pk +* +* Description: De-serialize public key from a byte array; +* approximate inverse of pack_pk +* +* Arguments: - polyvec *pk: pointer to output public-key vector of polynomials +* - uint8_t *seed: pointer to output seed to generate matrix A +* - const uint8_t *packedpk: pointer to input serialized public key +**************************************************/ +static void unpack_pk(polyvec *pk, uint8_t *seed, const uint8_t *packedpk) { + PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(pk, packedpk); + for (size_t i = 0; i < KYBER_SYMBYTES; i++) { + seed[i] = packedpk[i + KYBER_POLYVECBYTES]; + } +} + +/************************************************* +* Name: pack_sk +* +* Description: Serialize the secret key +* +* Arguments: - uint8_t *r: pointer to output serialized secret key +* - const polyvec *sk: pointer to input vector of polynomials (secret key) +**************************************************/ +static void pack_sk(uint8_t *r, polyvec *sk) { + PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(r, sk); +} + +/************************************************* +* Name: unpack_sk +* +* Description: De-serialize the secret key; +* inverse of pack_sk +* +* Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key) +* - const uint8_t *packedsk: pointer to input serialized secret key +**************************************************/ +static void unpack_sk(polyvec *sk, const uint8_t *packedsk) { + PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(sk, packedsk); +} + +/************************************************* +* Name: pack_ciphertext +* +* Description: Serialize the ciphertext as concatenation of the +* compressed and serialized vector of polynomials b +* and the compressed and serialized polynomial v +* +* Arguments: uint8_t *r: pointer to the output serialized ciphertext +* const poly *pk: pointer to the input vector of polynomials b +* const uint8_t *seed: pointer to the input polynomial v +**************************************************/ +static void pack_ciphertext(uint8_t *r, polyvec *b, poly *v) { + PQCLEAN_KYBER512_CLEAN_polyvec_compress(r, b); + PQCLEAN_KYBER512_CLEAN_poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v); +} + +/************************************************* +* Name: unpack_ciphertext +* +* Description: De-serialize and decompress ciphertext from a byte array; +* approximate inverse of pack_ciphertext +* +* Arguments: - polyvec *b: pointer to the output vector of polynomials b +* - poly *v: pointer to the output polynomial v +* - const uint8_t *c: pointer to the input serialized ciphertext +**************************************************/ +static void unpack_ciphertext(polyvec *b, poly *v, const uint8_t *c) { + PQCLEAN_KYBER512_CLEAN_polyvec_decompress(b, c); + PQCLEAN_KYBER512_CLEAN_poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES); +} + +/************************************************* +* Name: rej_uniform +* +* Description: Run rejection sampling on uniform random bytes to generate +* uniform random integers mod q +* +* Arguments: - int16_t *r: pointer to output buffer +* - size_t len: requested number of 16-bit integers (uniform mod q) +* - const uint8_t *buf: pointer to input buffer (assumed to be uniform random bytes) +* - size_t buflen: length of input buffer in bytes +* +* Returns number of sampled 16-bit integers (at most len) +**************************************************/ +static size_t rej_uniform(int16_t *r, size_t len, const uint8_t *buf, size_t buflen) { + size_t ctr, pos; + + ctr = pos = 0; + while (ctr < len && pos + 2 <= buflen) { + uint16_t val = (uint16_t)(buf[pos] | ((uint16_t)buf[pos + 1] << 8)); + pos += 2; + + if (val < 19 * KYBER_Q) { + val -= (uint16_t)((val >> 12) * KYBER_Q); // Barrett reduction + r[ctr++] = (int16_t)val; + } + } + + return ctr; +} + +#define gen_a(A,B) gen_matrix(A,B,0) +#define gen_at(A,B) gen_matrix(A,B,1) + +/************************************************* +* Name: gen_matrix +* +* Description: Deterministically generate matrix A (or the transpose of A) +* from a seed. Entries of the matrix are polynomials that look +* uniformly random. Performs rejection sampling on output of +* a XOF +* +* Arguments: - polyvec *a: pointer to ouptput matrix A +* - const uint8_t *seed: pointer to input seed +* - int transposed: boolean deciding whether A or A^T is generated +**************************************************/ +#define MAXNBLOCKS ((530+XOF_BLOCKBYTES)/XOF_BLOCKBYTES) /* 530 is expected number of required bytes */ +static void gen_matrix(polyvec *a, const uint8_t *seed, int transposed) { + size_t ctr; + uint8_t i, j; + uint8_t buf[XOF_BLOCKBYTES * MAXNBLOCKS + 1]; + xof_state state; + + for (i = 0; i < KYBER_K; i++) { + for (j = 0; j < KYBER_K; j++) { + if (transposed) { + xof_absorb(&state, seed, i, j); + } else { + xof_absorb(&state, seed, j, i); + } + + xof_squeezeblocks(buf, MAXNBLOCKS, &state); + ctr = rej_uniform(a[i].vec[j].coeffs, KYBER_N, buf, MAXNBLOCKS * XOF_BLOCKBYTES); + + while (ctr < KYBER_N) { + xof_squeezeblocks(buf, 1, &state); + ctr += rej_uniform(a[i].vec[j].coeffs + ctr, KYBER_N - ctr, buf, XOF_BLOCKBYTES); + } + xof_ctx_release(&state); + } + } +} + +/************************************************* +* Name: indcpa_keypair +* +* Description: Generates public and private key for the CPA-secure +* public-key encryption scheme underlying Kyber +* +* Arguments: - uint8_t *pk: pointer to output public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) +* - uint8_t *sk: pointer to output private key (of length KYBER_INDCPA_SECRETKEYBYTES bytes) +**************************************************/ +int PQCLEAN_KYBER512_CLEAN_indcpa_keypair(uint8_t *pk, uint8_t *sk) { + polyvec a[KYBER_K], e, pkpv, skpv; + uint8_t buf[2 * KYBER_SYMBYTES]; + uint8_t *publicseed = buf; + uint8_t *noiseseed = buf + KYBER_SYMBYTES; + uint8_t nonce = 0; + + GUARD_AS_POSIX(s2n_get_random_bytes(buf, KYBER_SYMBYTES)); + hash_g(buf, buf, KYBER_SYMBYTES); + + gen_a(a, publicseed); + + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_getnoise(skpv.vec + i, noiseseed, nonce++); + } + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_getnoise(e.vec + i, noiseseed, nonce++); + } + + PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&skpv); + PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&e); + + // matrix-vector multiplication + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&pkpv.vec[i], &a[i], &skpv); + PQCLEAN_KYBER512_CLEAN_poly_frommont(&pkpv.vec[i]); + } + + PQCLEAN_KYBER512_CLEAN_polyvec_add(&pkpv, &pkpv, &e); + PQCLEAN_KYBER512_CLEAN_polyvec_reduce(&pkpv); + + pack_sk(sk, &skpv); + pack_pk(pk, &pkpv, publicseed); + return 0; +} + +/************************************************* +* Name: indcpa_enc +* +* Description: Encryption function of the CPA-secure +* public-key encryption scheme underlying Kyber. +* +* Arguments: - uint8_t *c: pointer to output ciphertext (of length KYBER_INDCPA_BYTES bytes) +* - const uint8_t *m: pointer to input message (of length KYBER_INDCPA_MSGBYTES bytes) +* - const uint8_t *pk: pointer to input public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) +* - const uint8_t *coin: pointer to input random coins used as seed (of length KYBER_SYMBYTES bytes) +* to deterministically generate all randomness +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_indcpa_enc(uint8_t *c, + const uint8_t *m, + const uint8_t *pk, + const uint8_t *coins) { + polyvec sp, pkpv, ep, at[KYBER_K], bp; + poly v, k, epp; + uint8_t seed[KYBER_SYMBYTES]; + uint8_t nonce = 0; + + unpack_pk(&pkpv, seed, pk); + PQCLEAN_KYBER512_CLEAN_poly_frommsg(&k, m); + gen_at(at, seed); + + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_getnoise(sp.vec + i, coins, nonce++); + } + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_getnoise(ep.vec + i, coins, nonce++); + } + PQCLEAN_KYBER512_CLEAN_poly_getnoise(&epp, coins, nonce++); + + PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&sp); + + // matrix-vector multiplication + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&bp.vec[i], &at[i], &sp); + } + + PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&v, &pkpv, &sp); + + PQCLEAN_KYBER512_CLEAN_polyvec_invntt(&bp); + PQCLEAN_KYBER512_CLEAN_poly_invntt(&v); + + PQCLEAN_KYBER512_CLEAN_polyvec_add(&bp, &bp, &ep); + PQCLEAN_KYBER512_CLEAN_poly_add(&v, &v, &epp); + PQCLEAN_KYBER512_CLEAN_poly_add(&v, &v, &k); + PQCLEAN_KYBER512_CLEAN_polyvec_reduce(&bp); + PQCLEAN_KYBER512_CLEAN_poly_reduce(&v); + + pack_ciphertext(c, &bp, &v); +} + +/************************************************* +* Name: indcpa_dec +* +* Description: Decryption function of the CPA-secure +* public-key encryption scheme underlying Kyber. +* +* Arguments: - uint8_t *m: pointer to output decrypted message (of length KYBER_INDCPA_MSGBYTES) +* - const uint8_t *c: pointer to input ciphertext (of length KYBER_INDCPA_BYTES) +* - const uint8_t *sk: pointer to input secret key (of length KYBER_INDCPA_SECRETKEYBYTES) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_indcpa_dec(uint8_t *m, + const uint8_t *c, + const uint8_t *sk) { + polyvec bp, skpv; + poly v, mp; + + unpack_ciphertext(&bp, &v, c); + unpack_sk(&skpv, sk); + + PQCLEAN_KYBER512_CLEAN_polyvec_ntt(&bp); + PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(&mp, &skpv, &bp); + PQCLEAN_KYBER512_CLEAN_poly_invntt(&mp); + + PQCLEAN_KYBER512_CLEAN_poly_sub(&mp, &v, &mp); + PQCLEAN_KYBER512_CLEAN_poly_reduce(&mp); + + PQCLEAN_KYBER512_CLEAN_poly_tomsg(m, &mp); +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.h index 23328f0970..2311d02a11 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/indcpa.h @@ -1,21 +1,21 @@ -#ifndef INDCPA_H -#define INDCPA_H - -#include <stdint.h> - -int PQCLEAN_KYBER512_CLEAN_indcpa_keypair( - uint8_t *pk, - uint8_t *sk); - -void PQCLEAN_KYBER512_CLEAN_indcpa_enc( - uint8_t *c, - const uint8_t *m, - const uint8_t *pk, - const uint8_t *coins); - -void PQCLEAN_KYBER512_CLEAN_indcpa_dec( - uint8_t *m, - const uint8_t *c, - const uint8_t *sk); - -#endif +#ifndef INDCPA_H +#define INDCPA_H + +#include <stdint.h> + +int PQCLEAN_KYBER512_CLEAN_indcpa_keypair( + uint8_t *pk, + uint8_t *sk); + +void PQCLEAN_KYBER512_CLEAN_indcpa_enc( + uint8_t *c, + const uint8_t *m, + const uint8_t *pk, + const uint8_t *coins); + +void PQCLEAN_KYBER512_CLEAN_indcpa_dec( + uint8_t *m, + const uint8_t *c, + const uint8_t *sk); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/kyber_r2_kem.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/kyber_r2_kem.c index d9b64d4336..d28caa8642 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/kyber_r2_kem.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/kyber_r2_kem.c @@ -1,102 +1,102 @@ -#include "indcpa.h" -#include "params.h" -#include "symmetric.h" -#include "verify.h" - -#include "../s2n_pq_random.h" -#include "utils/s2n_safety.h" -#include "tls/s2n_kem.h" - -#include <stdlib.h> - -/************************************************* -* Name: crypto_kem_keypair -* -* Description: Generates public and private key -* for CCA-secure Kyber key encapsulation mechanism -* -* Arguments: - uint8_t *pk: pointer to output public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) -* - uint8_t *sk: pointer to output private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) -* -* Returns 0 (success) -**************************************************/ -int kyber_512_r2_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - size_t i; - PQCLEAN_KYBER512_CLEAN_indcpa_keypair(pk, sk); - for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++) { - sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i]; - } - hash_h(sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); - GUARD_AS_POSIX(s2n_get_random_bytes(sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES)); /* Value z for pseudo-random output on reject */ - return 0; -} - -/************************************************* -* Name: crypto_kem_enc -* -* Description: Generates cipher text and shared -* secret for given public key -* -* Arguments: - uint8_t *ct: pointer to output cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) -* - uint8_t *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) -* - const uint8_t *pk: pointer to input public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) -* -* Returns 0 (success) -**************************************************/ -int kyber_512_r2_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - uint8_t kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ - uint8_t buf[2 * KYBER_SYMBYTES]; - - GUARD_AS_POSIX(s2n_get_random_bytes(buf, KYBER_SYMBYTES)); - hash_h(buf, buf, KYBER_SYMBYTES); /* Don't release system RNG output */ - - hash_h(buf + KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + contributory KEM */ - hash_g(kr, buf, 2 * KYBER_SYMBYTES); - - PQCLEAN_KYBER512_CLEAN_indcpa_enc(ct, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ - - hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ - kdf(ss, kr, 2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ - return 0; -} - -/************************************************* -* Name: crypto_kem_dec -* -* Description: Generates shared secret for given -* cipher text and private key -* -* Arguments: - uint8_t *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) -* - const uint8_t *ct: pointer to input cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) -* - const uint8_t *sk: pointer to input private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) -* -* Returns 0. -* -* On failure, ss will contain a pseudo-random value. -**************************************************/ -int kyber_512_r2_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - size_t i; - uint8_t fail; - uint8_t cmp[KYBER_CIPHERTEXTBYTES]; - uint8_t buf[2 * KYBER_SYMBYTES]; - uint8_t kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ - const uint8_t *pk = sk + KYBER_INDCPA_SECRETKEYBYTES; - - PQCLEAN_KYBER512_CLEAN_indcpa_dec(buf, ct, sk); - - for (i = 0; i < KYBER_SYMBYTES; i++) { /* Multitarget countermeasure for coins + contributory KEM */ - buf[KYBER_SYMBYTES + i] = sk[KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES + i]; /* Save hash by storing H(pk) in sk */ - } - hash_g(kr, buf, 2 * KYBER_SYMBYTES); - - PQCLEAN_KYBER512_CLEAN_indcpa_enc(cmp, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ - - fail = PQCLEAN_KYBER512_CLEAN_verify(ct, cmp, KYBER_CIPHERTEXTBYTES); - - hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ - - PQCLEAN_KYBER512_CLEAN_cmov(kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES, fail); /* Overwrite pre-k with z on re-encryption failure */ - - kdf(ss, kr, 2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ - return 0; -} +#include "indcpa.h" +#include "params.h" +#include "symmetric.h" +#include "verify.h" + +#include "../s2n_pq_random.h" +#include "utils/s2n_safety.h" +#include "tls/s2n_kem.h" + +#include <stdlib.h> + +/************************************************* +* Name: crypto_kem_keypair +* +* Description: Generates public and private key +* for CCA-secure Kyber key encapsulation mechanism +* +* Arguments: - uint8_t *pk: pointer to output public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) +* - uint8_t *sk: pointer to output private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int kyber_512_r2_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { + size_t i; + PQCLEAN_KYBER512_CLEAN_indcpa_keypair(pk, sk); + for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++) { + sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i]; + } + hash_h(sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); + GUARD_AS_POSIX(s2n_get_random_bytes(sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES)); /* Value z for pseudo-random output on reject */ + return 0; +} + +/************************************************* +* Name: crypto_kem_enc +* +* Description: Generates cipher text and shared +* secret for given public key +* +* Arguments: - uint8_t *ct: pointer to output cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) +* - uint8_t *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) +* - const uint8_t *pk: pointer to input public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int kyber_512_r2_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { + uint8_t kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ + uint8_t buf[2 * KYBER_SYMBYTES]; + + GUARD_AS_POSIX(s2n_get_random_bytes(buf, KYBER_SYMBYTES)); + hash_h(buf, buf, KYBER_SYMBYTES); /* Don't release system RNG output */ + + hash_h(buf + KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + contributory KEM */ + hash_g(kr, buf, 2 * KYBER_SYMBYTES); + + PQCLEAN_KYBER512_CLEAN_indcpa_enc(ct, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ + + hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ + kdf(ss, kr, 2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ + return 0; +} + +/************************************************* +* Name: crypto_kem_dec +* +* Description: Generates shared secret for given +* cipher text and private key +* +* Arguments: - uint8_t *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) +* - const uint8_t *ct: pointer to input cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) +* - const uint8_t *sk: pointer to input private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0. +* +* On failure, ss will contain a pseudo-random value. +**************************************************/ +int kyber_512_r2_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { + size_t i; + uint8_t fail; + uint8_t cmp[KYBER_CIPHERTEXTBYTES]; + uint8_t buf[2 * KYBER_SYMBYTES]; + uint8_t kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ + const uint8_t *pk = sk + KYBER_INDCPA_SECRETKEYBYTES; + + PQCLEAN_KYBER512_CLEAN_indcpa_dec(buf, ct, sk); + + for (i = 0; i < KYBER_SYMBYTES; i++) { /* Multitarget countermeasure for coins + contributory KEM */ + buf[KYBER_SYMBYTES + i] = sk[KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES + i]; /* Save hash by storing H(pk) in sk */ + } + hash_g(kr, buf, 2 * KYBER_SYMBYTES); + + PQCLEAN_KYBER512_CLEAN_indcpa_enc(cmp, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ + + fail = PQCLEAN_KYBER512_CLEAN_verify(ct, cmp, KYBER_CIPHERTEXTBYTES); + + hash_h(kr + KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ + + PQCLEAN_KYBER512_CLEAN_cmov(kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES, fail); /* Overwrite pre-k with z on re-encryption failure */ + + kdf(ss, kr, 2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ + return 0; +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.c index 444664b3e2..68834a255f 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.c @@ -1,155 +1,155 @@ -#include "ntt.h" -#include "params.h" -#include "reduce.h" - -#include <stddef.h> -#include <stdint.h> - -/* Code to generate zetas and zetas_inv used in the number-theoretic transform: - -#define KYBER_ROOT_OF_UNITY 17 - -static const uint16_t tree[128] = { - 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, - 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124, - 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122, - 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126, - 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121, - 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125, - 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123, - 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127}; - - -static int16_t fqmul(int16_t a, int16_t b) { - return montgomery_reduce((int32_t)a*b); -} - -void init_ntt() { - unsigned int i, j, k; - int16_t tmp[128]; - - tmp[0] = MONT; - for(i = 1; i < 128; ++i) - tmp[i] = fqmul(tmp[i-1], KYBER_ROOT_OF_UNITY*MONT % KYBER_Q); - - for(i = 0; i < 128; ++i) - zetas[i] = tmp[tree[i]]; - - k = 0; - for(i = 64; i >= 1; i >>= 1) - for(j = i; j < 2*i; ++j) - zetas_inv[k++] = -tmp[128 - tree[j]]; - - zetas_inv[127] = MONT * (MONT * (KYBER_Q - 1) * ((KYBER_Q - 1)/128) % KYBER_Q) % KYBER_Q; -} - -*/ -const int16_t PQCLEAN_KYBER512_CLEAN_zetas[128] = { - 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962, 2127, 1855, 1468, - 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017, 732, 608, 1787, 411, 3124, 1758, - 1223, 652, 2777, 1015, 2036, 1491, 3047, 1785, 516, 3321, 3009, 2663, 1711, 2167, 126, 1469, - 2476, 3239, 3058, 830, 107, 1908, 3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, - 2226, 430, 555, 843, 2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, - 3083, 778, 1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173, 3254, - 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218, 1994, 2455, 220, 2142, 1670, - 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628 -}; - -const int16_t PQCLEAN_KYBER512_CLEAN_zetas_inv[128] = { - 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535, 1278, 1530, 1185, - 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465, 1285, 2007, 2719, 2726, 2232, 2512, - 75, 156, 3000, 2911, 2980, 872, 2685, 1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, - 1676, 1755, 460, 291, 235, 3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, - 1275, 2652, 1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853, - 1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552, 2677, 2106, - 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871, 829, 2946, 3065, 1325, 2756, - 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171, 3127, 3042, 1907, 1836, 1517, 359, 758, 1441 -}; - - -/************************************************* -* Name: fqmul -* -* Description: Multiplication followed by Montgomery reduction -* -* Arguments: - int16_t a: first factor -* - int16_t b: second factor -* -* Returns 16-bit integer congruent to a*b*R^{-1} mod q -**************************************************/ -static int16_t fqmul(int16_t a, int16_t b) { - return PQCLEAN_KYBER512_CLEAN_montgomery_reduce((int32_t)a * b); -} - -/************************************************* -* Name: ntt -* -* Description: Inplace number-theoretic transform (NTT) in Rq -* input is in standard order, output is in bitreversed order -* -* Arguments: - int16_t poly[256]: pointer to input/output vector of elements of Zq -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_ntt(int16_t poly[256]) { - size_t j, k = 1; - int16_t t, zeta; - - for (size_t len = 128; len >= 2; len >>= 1) { - for (size_t start = 0; start < 256; start = j + len) { - zeta = PQCLEAN_KYBER512_CLEAN_zetas[k++]; - for (j = start; j < start + len; ++j) { - t = fqmul(zeta, poly[j + len]); - poly[j + len] = poly[j] - t; - poly[j] = poly[j] + t; - } - } - } -} - -/************************************************* -* Name: invntt -* -* Description: Inplace inverse number-theoretic transform in Rq -* input is in bitreversed order, output is in standard order -* -* Arguments: - int16_t poly[256]: pointer to input/output vector of elements of Zq -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_invntt(int16_t poly[256]) { - size_t j, k = 0; - int16_t t, zeta; - - for (size_t len = 2; len <= 128; len <<= 1) { - for (size_t start = 0; start < 256; start = j + len) { - zeta = PQCLEAN_KYBER512_CLEAN_zetas_inv[k++]; - for (j = start; j < start + len; ++j) { - t = poly[j]; - poly[j] = PQCLEAN_KYBER512_CLEAN_barrett_reduce(t + poly[j + len]); - poly[j + len] = t - poly[j + len]; - poly[j + len] = fqmul(zeta, poly[j + len]); - } - } - } - - for (j = 0; j < 256; ++j) { - poly[j] = fqmul(poly[j], PQCLEAN_KYBER512_CLEAN_zetas_inv[127]); - } -} - -/************************************************* -* Name: basemul -* -* Description: Multiplication of polynomials in Zq[X]/((X^2-zeta)) -* used for multiplication of elements in Rq in NTT domain -* -* Arguments: - int16_t r[2]: pointer to the output polynomial -* - const int16_t a[2]: pointer to the first factor -* - const int16_t b[2]: pointer to the second factor -* - int16_t zeta: integer defining the reduction polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta) { - r[0] = fqmul(a[1], b[1]); - r[0] = fqmul(r[0], zeta); - r[0] += fqmul(a[0], b[0]); - - r[1] = fqmul(a[0], b[1]); - r[1] += fqmul(a[1], b[0]); -} +#include "ntt.h" +#include "params.h" +#include "reduce.h" + +#include <stddef.h> +#include <stdint.h> + +/* Code to generate zetas and zetas_inv used in the number-theoretic transform: + +#define KYBER_ROOT_OF_UNITY 17 + +static const uint16_t tree[128] = { + 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, + 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124, + 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122, + 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126, + 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121, + 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125, + 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123, + 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127}; + + +static int16_t fqmul(int16_t a, int16_t b) { + return montgomery_reduce((int32_t)a*b); +} + +void init_ntt() { + unsigned int i, j, k; + int16_t tmp[128]; + + tmp[0] = MONT; + for(i = 1; i < 128; ++i) + tmp[i] = fqmul(tmp[i-1], KYBER_ROOT_OF_UNITY*MONT % KYBER_Q); + + for(i = 0; i < 128; ++i) + zetas[i] = tmp[tree[i]]; + + k = 0; + for(i = 64; i >= 1; i >>= 1) + for(j = i; j < 2*i; ++j) + zetas_inv[k++] = -tmp[128 - tree[j]]; + + zetas_inv[127] = MONT * (MONT * (KYBER_Q - 1) * ((KYBER_Q - 1)/128) % KYBER_Q) % KYBER_Q; +} + +*/ +const int16_t PQCLEAN_KYBER512_CLEAN_zetas[128] = { + 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962, 2127, 1855, 1468, + 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017, 732, 608, 1787, 411, 3124, 1758, + 1223, 652, 2777, 1015, 2036, 1491, 3047, 1785, 516, 3321, 3009, 2663, 1711, 2167, 126, 1469, + 2476, 3239, 3058, 830, 107, 1908, 3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, + 2226, 430, 555, 843, 2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, + 3083, 778, 1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173, 3254, + 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218, 1994, 2455, 220, 2142, 1670, + 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628 +}; + +const int16_t PQCLEAN_KYBER512_CLEAN_zetas_inv[128] = { + 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535, 1278, 1530, 1185, + 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465, 1285, 2007, 2719, 2726, 2232, 2512, + 75, 156, 3000, 2911, 2980, 872, 2685, 1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, + 1676, 1755, 460, 291, 235, 3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, + 1275, 2652, 1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853, + 1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552, 2677, 2106, + 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871, 829, 2946, 3065, 1325, 2756, + 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171, 3127, 3042, 1907, 1836, 1517, 359, 758, 1441 +}; + + +/************************************************* +* Name: fqmul +* +* Description: Multiplication followed by Montgomery reduction +* +* Arguments: - int16_t a: first factor +* - int16_t b: second factor +* +* Returns 16-bit integer congruent to a*b*R^{-1} mod q +**************************************************/ +static int16_t fqmul(int16_t a, int16_t b) { + return PQCLEAN_KYBER512_CLEAN_montgomery_reduce((int32_t)a * b); +} + +/************************************************* +* Name: ntt +* +* Description: Inplace number-theoretic transform (NTT) in Rq +* input is in standard order, output is in bitreversed order +* +* Arguments: - int16_t poly[256]: pointer to input/output vector of elements of Zq +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_ntt(int16_t poly[256]) { + size_t j, k = 1; + int16_t t, zeta; + + for (size_t len = 128; len >= 2; len >>= 1) { + for (size_t start = 0; start < 256; start = j + len) { + zeta = PQCLEAN_KYBER512_CLEAN_zetas[k++]; + for (j = start; j < start + len; ++j) { + t = fqmul(zeta, poly[j + len]); + poly[j + len] = poly[j] - t; + poly[j] = poly[j] + t; + } + } + } +} + +/************************************************* +* Name: invntt +* +* Description: Inplace inverse number-theoretic transform in Rq +* input is in bitreversed order, output is in standard order +* +* Arguments: - int16_t poly[256]: pointer to input/output vector of elements of Zq +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_invntt(int16_t poly[256]) { + size_t j, k = 0; + int16_t t, zeta; + + for (size_t len = 2; len <= 128; len <<= 1) { + for (size_t start = 0; start < 256; start = j + len) { + zeta = PQCLEAN_KYBER512_CLEAN_zetas_inv[k++]; + for (j = start; j < start + len; ++j) { + t = poly[j]; + poly[j] = PQCLEAN_KYBER512_CLEAN_barrett_reduce(t + poly[j + len]); + poly[j + len] = t - poly[j + len]; + poly[j + len] = fqmul(zeta, poly[j + len]); + } + } + } + + for (j = 0; j < 256; ++j) { + poly[j] = fqmul(poly[j], PQCLEAN_KYBER512_CLEAN_zetas_inv[127]); + } +} + +/************************************************* +* Name: basemul +* +* Description: Multiplication of polynomials in Zq[X]/((X^2-zeta)) +* used for multiplication of elements in Rq in NTT domain +* +* Arguments: - int16_t r[2]: pointer to the output polynomial +* - const int16_t a[2]: pointer to the first factor +* - const int16_t b[2]: pointer to the second factor +* - int16_t zeta: integer defining the reduction polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta) { + r[0] = fqmul(a[1], b[1]); + r[0] = fqmul(r[0], zeta); + r[0] += fqmul(a[0], b[0]); + + r[1] = fqmul(a[0], b[1]); + r[1] += fqmul(a[1], b[0]); +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.h index 13e976f7d0..bc373f0a5e 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/ntt.h @@ -1,13 +1,13 @@ -#ifndef NTT_H -#define NTT_H - -#include <stdint.h> - -extern const int16_t PQCLEAN_KYBER512_CLEAN_zetas[128]; -extern const int16_t PQCLEAN_KYBER512_CLEAN_zetasinv[128]; - -void PQCLEAN_KYBER512_CLEAN_ntt(int16_t *poly); -void PQCLEAN_KYBER512_CLEAN_invntt(int16_t *poly); -void PQCLEAN_KYBER512_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta); - -#endif +#ifndef NTT_H +#define NTT_H + +#include <stdint.h> + +extern const int16_t PQCLEAN_KYBER512_CLEAN_zetas[128]; +extern const int16_t PQCLEAN_KYBER512_CLEAN_zetasinv[128]; + +void PQCLEAN_KYBER512_CLEAN_ntt(int16_t *poly); +void PQCLEAN_KYBER512_CLEAN_invntt(int16_t *poly); +void PQCLEAN_KYBER512_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/params.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/params.h index d086d4c694..a0ff58a397 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/params.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/params.h @@ -1,32 +1,32 @@ -#ifndef PARAMS_H -#define PARAMS_H - - -/* Don't change parameters below this line */ - -#define KYBER_N 256 -#define KYBER_Q 3329 - -#define KYBER_ETA 2 - -#define KYBER_SYMBYTES 32 /* size in bytes of hashes, and seeds */ -#define KYBER_SSBYTES 32 /* size in bytes of shared key */ - -#define KYBER_POLYBYTES 384 -#define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES) - - -#define KYBER_K 2 -#define KYBER_POLYCOMPRESSEDBYTES 96 -#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 320) - -#define KYBER_INDCPA_MSGBYTES KYBER_SYMBYTES -#define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECBYTES + KYBER_SYMBYTES) -#define KYBER_INDCPA_SECRETKEYBYTES (KYBER_POLYVECBYTES) -#define KYBER_INDCPA_BYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_POLYCOMPRESSEDBYTES) - -#define KYBER_PUBLICKEYBYTES (KYBER_INDCPA_PUBLICKEYBYTES) -#define KYBER_SECRETKEYBYTES (KYBER_INDCPA_SECRETKEYBYTES + KYBER_INDCPA_PUBLICKEYBYTES + 2*KYBER_SYMBYTES) /* 32 bytes of additional space to save H(pk) */ -#define KYBER_CIPHERTEXTBYTES KYBER_INDCPA_BYTES - -#endif +#ifndef PARAMS_H +#define PARAMS_H + + +/* Don't change parameters below this line */ + +#define KYBER_N 256 +#define KYBER_Q 3329 + +#define KYBER_ETA 2 + +#define KYBER_SYMBYTES 32 /* size in bytes of hashes, and seeds */ +#define KYBER_SSBYTES 32 /* size in bytes of shared key */ + +#define KYBER_POLYBYTES 384 +#define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES) + + +#define KYBER_K 2 +#define KYBER_POLYCOMPRESSEDBYTES 96 +#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 320) + +#define KYBER_INDCPA_MSGBYTES KYBER_SYMBYTES +#define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECBYTES + KYBER_SYMBYTES) +#define KYBER_INDCPA_SECRETKEYBYTES (KYBER_POLYVECBYTES) +#define KYBER_INDCPA_BYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_POLYCOMPRESSEDBYTES) + +#define KYBER_PUBLICKEYBYTES (KYBER_INDCPA_PUBLICKEYBYTES) +#define KYBER_SECRETKEYBYTES (KYBER_INDCPA_SECRETKEYBYTES + KYBER_INDCPA_PUBLICKEYBYTES + 2*KYBER_SYMBYTES) /* 32 bytes of additional space to save H(pk) */ +#define KYBER_CIPHERTEXTBYTES KYBER_INDCPA_BYTES + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.c index 694b4e9942..ae1ae7c719 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.c @@ -1,277 +1,277 @@ -#include "cbd.h" -#include "ntt.h" -#include "params.h" -#include "poly.h" -#include "reduce.h" -#include "symmetric.h" - -#include <stdint.h> -/************************************************* -* Name: poly_compress -* -* Description: Compression and subsequent serialization of a polynomial -* -* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYCOMPRESSEDBYTES bytes) -* - const poly *a: pointer to input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_compress(uint8_t *r, poly *a) { - uint8_t t[8]; - size_t k = 0; - - PQCLEAN_KYBER512_CLEAN_poly_csubq(a); - - for (size_t i = 0; i < KYBER_N; i += 8) { - for (size_t j = 0; j < 8; j++) { - t[j] = ((((uint32_t)a->coeffs[i + j] << 3) + KYBER_Q / 2) / KYBER_Q) & 7; - } - - r[k] = (uint8_t)( t[0] | (t[1] << 3) | (t[2] << 6)); - r[k + 1] = (uint8_t)((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)); - r[k + 2] = (uint8_t)((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)); - k += 3; - } -} - -/************************************************* -* Name: poly_decompress -* -* Description: De-serialization and subsequent decompression of a polynomial; -* approximate inverse of poly_compress -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: pointer to input byte array (of length KYBER_POLYCOMPRESSEDBYTES bytes) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_decompress(poly *r, const uint8_t *a) { - for (size_t i = 0; i < KYBER_N; i += 8) { - r->coeffs[i + 0] = (int16_t)( (((a[0] & 7) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 1] = (int16_t)(((((a[0] >> 3) & 7) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 2] = (int16_t)(((((a[0] >> 6) | ((a[1] << 2) & 4)) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 3] = (int16_t)(((((a[1] >> 1) & 7) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 4] = (int16_t)(((((a[1] >> 4) & 7) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 5] = (int16_t)(((((a[1] >> 7) | ((a[2] << 1) & 6)) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 6] = (int16_t)(((((a[2] >> 2) & 7) * KYBER_Q) + 4) >> 3); - r->coeffs[i + 7] = (int16_t)(((((a[2] >> 5)) * KYBER_Q) + 4) >> 3); - a += 3; - } -} - -/************************************************* -* Name: poly_tobytes -* -* Description: Serialization of a polynomial -* -* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYBYTES bytes) -* - const poly *a: pointer to input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_tobytes(uint8_t *r, poly *a) { - PQCLEAN_KYBER512_CLEAN_poly_csubq(a); - - for (size_t i = 0; i < KYBER_N / 2; i++) { - int16_t t0 = a->coeffs[2 * i]; - int16_t t1 = a->coeffs[2 * i + 1]; - r[3 * i] = t0 & 0xff; - r[3 * i + 1] = (uint8_t)((t0 >> 8) | ((t1 & 0xf) << 4)); - r[3 * i + 2] = (uint8_t)(t1 >> 4); - } -} - -/************************************************* -* Name: poly_frombytes -* -* Description: De-serialization of a polynomial; -* inverse of poly_tobytes -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *a: pointer to input byte array (of KYBER_POLYBYTES bytes) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_frombytes(poly *r, const uint8_t *a) { - for (size_t i = 0; i < KYBER_N / 2; i++) { - r->coeffs[2 * i] = (int16_t)(a[3 * i] | ((uint16_t)a[3 * i + 1] & 0x0f) << 8); - r->coeffs[2 * i + 1] = (int16_t)(a[3 * i + 1] >> 4 | ((uint16_t)a[3 * i + 2] & 0xff) << 4); - } -} - -/************************************************* -* Name: poly_getnoise -* -* Description: Sample a polynomial deterministically from a seed and a nonce, -* with output polynomial close to centered binomial distribution -* with parameter KYBER_ETA -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *seed: pointer to input seed (pointing to array of length KYBER_SYMBYTES bytes) -* - uint8_t nonce: one-byte input nonce -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_getnoise(poly *r, const uint8_t *seed, uint8_t nonce) { - uint8_t buf[KYBER_ETA * KYBER_N / 4]; - - prf(buf, KYBER_ETA * KYBER_N / 4, seed, nonce); - PQCLEAN_KYBER512_CLEAN_cbd(r, buf); -} - -/************************************************* -* Name: poly_ntt -* -* Description: Computes negacyclic number-theoretic transform (NTT) of -* a polynomial in place; -* inputs assumed to be in normal order, output in bitreversed order -* -* Arguments: - uint16_t *r: pointer to in/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_ntt(poly *r) { - PQCLEAN_KYBER512_CLEAN_ntt(r->coeffs); - PQCLEAN_KYBER512_CLEAN_poly_reduce(r); -} - -/************************************************* -* Name: poly_invntt -* -* Description: Computes inverse of negacyclic number-theoretic transform (NTT) of -* a polynomial in place; -* inputs assumed to be in bitreversed order, output in normal order -* -* Arguments: - uint16_t *a: pointer to in/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_invntt(poly *r) { - PQCLEAN_KYBER512_CLEAN_invntt(r->coeffs); -} - -/************************************************* -* Name: poly_basemul -* -* Description: Multiplication of two polynomials in NTT domain -* -* Arguments: - poly *r: pointer to output polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_basemul(poly *r, const poly *a, const poly *b) { - for (size_t i = 0; i < KYBER_N / 4; ++i) { - PQCLEAN_KYBER512_CLEAN_basemul( - r->coeffs + 4 * i, - a->coeffs + 4 * i, - b->coeffs + 4 * i, - PQCLEAN_KYBER512_CLEAN_zetas[64 + i]); - PQCLEAN_KYBER512_CLEAN_basemul( - r->coeffs + 4 * i + 2, - a->coeffs + 4 * i + 2, - b->coeffs + 4 * i + 2, - -PQCLEAN_KYBER512_CLEAN_zetas[64 + i]); - } -} - -/************************************************* -* Name: poly_frommont -* -* Description: Inplace conversion of all coefficients of a polynomial -* from Montgomery domain to normal domain -* -* Arguments: - poly *r: pointer to input/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_frommont(poly *r) { - const int16_t f = (1ULL << 32) % KYBER_Q; - - for (size_t i = 0; i < KYBER_N; i++) { - r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_montgomery_reduce( - (int32_t)r->coeffs[i] * f); - } -} - -/************************************************* -* Name: poly_reduce -* -* Description: Applies Barrett reduction to all coefficients of a polynomial -* for details of the Barrett reduction see comments in reduce.c -* -* Arguments: - poly *r: pointer to input/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_reduce(poly *r) { - for (size_t i = 0; i < KYBER_N; i++) { - r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_barrett_reduce(r->coeffs[i]); - } -} - -/************************************************* -* Name: poly_csubq -* -* Description: Applies conditional subtraction of q to each coefficient of a polynomial -* for details of conditional subtraction of q see comments in reduce.c -* -* Arguments: - poly *r: pointer to input/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_csubq(poly *r) { - for (size_t i = 0; i < KYBER_N; i++) { - r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_csubq(r->coeffs[i]); - } -} - -/************************************************* -* Name: poly_add -* -* Description: Add two polynomials -* -* Arguments: - poly *r: pointer to output polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_add(poly *r, const poly *a, const poly *b) { - for (size_t i = 0; i < KYBER_N; i++) { - r->coeffs[i] = a->coeffs[i] + b->coeffs[i]; - } -} - -/************************************************* -* Name: poly_sub -* -* Description: Subtract two polynomials -* -* Arguments: - poly *r: pointer to output polynomial -* - const poly *a: pointer to first input polynomial -* - const poly *b: pointer to second input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_sub(poly *r, const poly *a, const poly *b) { - for (size_t i = 0; i < KYBER_N; i++) { - r->coeffs[i] = a->coeffs[i] - b->coeffs[i]; - } -} - -/************************************************* -* Name: poly_frommsg -* -* Description: Convert 32-byte message to polynomial -* -* Arguments: - poly *r: pointer to output polynomial -* - const uint8_t *msg: pointer to input message -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_SYMBYTES]) { - uint16_t mask; - - for (size_t i = 0; i < KYBER_SYMBYTES; i++) { - for (size_t j = 0; j < 8; j++) { - mask = -((msg[i] >> j) & 1); - r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2); - } - } -} - -/************************************************* -* Name: poly_tomsg -* -* Description: Convert polynomial to 32-byte message -* -* Arguments: - uint8_t *msg: pointer to output message -* - const poly *a: pointer to input polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_poly_tomsg(uint8_t msg[KYBER_SYMBYTES], poly *a) { - uint16_t t; - - PQCLEAN_KYBER512_CLEAN_poly_csubq(a); - - for (size_t i = 0; i < KYBER_SYMBYTES; i++) { - msg[i] = 0; - for (size_t j = 0; j < 8; j++) { - t = (((a->coeffs[8 * i + j] << 1) + KYBER_Q / 2) / KYBER_Q) & 1; - msg[i] |= t << j; - } - } -} +#include "cbd.h" +#include "ntt.h" +#include "params.h" +#include "poly.h" +#include "reduce.h" +#include "symmetric.h" + +#include <stdint.h> +/************************************************* +* Name: poly_compress +* +* Description: Compression and subsequent serialization of a polynomial +* +* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYCOMPRESSEDBYTES bytes) +* - const poly *a: pointer to input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_compress(uint8_t *r, poly *a) { + uint8_t t[8]; + size_t k = 0; + + PQCLEAN_KYBER512_CLEAN_poly_csubq(a); + + for (size_t i = 0; i < KYBER_N; i += 8) { + for (size_t j = 0; j < 8; j++) { + t[j] = ((((uint32_t)a->coeffs[i + j] << 3) + KYBER_Q / 2) / KYBER_Q) & 7; + } + + r[k] = (uint8_t)( t[0] | (t[1] << 3) | (t[2] << 6)); + r[k + 1] = (uint8_t)((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)); + r[k + 2] = (uint8_t)((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)); + k += 3; + } +} + +/************************************************* +* Name: poly_decompress +* +* Description: De-serialization and subsequent decompression of a polynomial; +* approximate inverse of poly_compress +* +* Arguments: - poly *r: pointer to output polynomial +* - const uint8_t *a: pointer to input byte array (of length KYBER_POLYCOMPRESSEDBYTES bytes) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_decompress(poly *r, const uint8_t *a) { + for (size_t i = 0; i < KYBER_N; i += 8) { + r->coeffs[i + 0] = (int16_t)( (((a[0] & 7) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 1] = (int16_t)(((((a[0] >> 3) & 7) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 2] = (int16_t)(((((a[0] >> 6) | ((a[1] << 2) & 4)) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 3] = (int16_t)(((((a[1] >> 1) & 7) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 4] = (int16_t)(((((a[1] >> 4) & 7) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 5] = (int16_t)(((((a[1] >> 7) | ((a[2] << 1) & 6)) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 6] = (int16_t)(((((a[2] >> 2) & 7) * KYBER_Q) + 4) >> 3); + r->coeffs[i + 7] = (int16_t)(((((a[2] >> 5)) * KYBER_Q) + 4) >> 3); + a += 3; + } +} + +/************************************************* +* Name: poly_tobytes +* +* Description: Serialization of a polynomial +* +* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYBYTES bytes) +* - const poly *a: pointer to input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_tobytes(uint8_t *r, poly *a) { + PQCLEAN_KYBER512_CLEAN_poly_csubq(a); + + for (size_t i = 0; i < KYBER_N / 2; i++) { + int16_t t0 = a->coeffs[2 * i]; + int16_t t1 = a->coeffs[2 * i + 1]; + r[3 * i] = t0 & 0xff; + r[3 * i + 1] = (uint8_t)((t0 >> 8) | ((t1 & 0xf) << 4)); + r[3 * i + 2] = (uint8_t)(t1 >> 4); + } +} + +/************************************************* +* Name: poly_frombytes +* +* Description: De-serialization of a polynomial; +* inverse of poly_tobytes +* +* Arguments: - poly *r: pointer to output polynomial +* - const uint8_t *a: pointer to input byte array (of KYBER_POLYBYTES bytes) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_frombytes(poly *r, const uint8_t *a) { + for (size_t i = 0; i < KYBER_N / 2; i++) { + r->coeffs[2 * i] = (int16_t)(a[3 * i] | ((uint16_t)a[3 * i + 1] & 0x0f) << 8); + r->coeffs[2 * i + 1] = (int16_t)(a[3 * i + 1] >> 4 | ((uint16_t)a[3 * i + 2] & 0xff) << 4); + } +} + +/************************************************* +* Name: poly_getnoise +* +* Description: Sample a polynomial deterministically from a seed and a nonce, +* with output polynomial close to centered binomial distribution +* with parameter KYBER_ETA +* +* Arguments: - poly *r: pointer to output polynomial +* - const uint8_t *seed: pointer to input seed (pointing to array of length KYBER_SYMBYTES bytes) +* - uint8_t nonce: one-byte input nonce +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_getnoise(poly *r, const uint8_t *seed, uint8_t nonce) { + uint8_t buf[KYBER_ETA * KYBER_N / 4]; + + prf(buf, KYBER_ETA * KYBER_N / 4, seed, nonce); + PQCLEAN_KYBER512_CLEAN_cbd(r, buf); +} + +/************************************************* +* Name: poly_ntt +* +* Description: Computes negacyclic number-theoretic transform (NTT) of +* a polynomial in place; +* inputs assumed to be in normal order, output in bitreversed order +* +* Arguments: - uint16_t *r: pointer to in/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_ntt(poly *r) { + PQCLEAN_KYBER512_CLEAN_ntt(r->coeffs); + PQCLEAN_KYBER512_CLEAN_poly_reduce(r); +} + +/************************************************* +* Name: poly_invntt +* +* Description: Computes inverse of negacyclic number-theoretic transform (NTT) of +* a polynomial in place; +* inputs assumed to be in bitreversed order, output in normal order +* +* Arguments: - uint16_t *a: pointer to in/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_invntt(poly *r) { + PQCLEAN_KYBER512_CLEAN_invntt(r->coeffs); +} + +/************************************************* +* Name: poly_basemul +* +* Description: Multiplication of two polynomials in NTT domain +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_basemul(poly *r, const poly *a, const poly *b) { + for (size_t i = 0; i < KYBER_N / 4; ++i) { + PQCLEAN_KYBER512_CLEAN_basemul( + r->coeffs + 4 * i, + a->coeffs + 4 * i, + b->coeffs + 4 * i, + PQCLEAN_KYBER512_CLEAN_zetas[64 + i]); + PQCLEAN_KYBER512_CLEAN_basemul( + r->coeffs + 4 * i + 2, + a->coeffs + 4 * i + 2, + b->coeffs + 4 * i + 2, + -PQCLEAN_KYBER512_CLEAN_zetas[64 + i]); + } +} + +/************************************************* +* Name: poly_frommont +* +* Description: Inplace conversion of all coefficients of a polynomial +* from Montgomery domain to normal domain +* +* Arguments: - poly *r: pointer to input/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_frommont(poly *r) { + const int16_t f = (1ULL << 32) % KYBER_Q; + + for (size_t i = 0; i < KYBER_N; i++) { + r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_montgomery_reduce( + (int32_t)r->coeffs[i] * f); + } +} + +/************************************************* +* Name: poly_reduce +* +* Description: Applies Barrett reduction to all coefficients of a polynomial +* for details of the Barrett reduction see comments in reduce.c +* +* Arguments: - poly *r: pointer to input/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_reduce(poly *r) { + for (size_t i = 0; i < KYBER_N; i++) { + r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_barrett_reduce(r->coeffs[i]); + } +} + +/************************************************* +* Name: poly_csubq +* +* Description: Applies conditional subtraction of q to each coefficient of a polynomial +* for details of conditional subtraction of q see comments in reduce.c +* +* Arguments: - poly *r: pointer to input/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_csubq(poly *r) { + for (size_t i = 0; i < KYBER_N; i++) { + r->coeffs[i] = PQCLEAN_KYBER512_CLEAN_csubq(r->coeffs[i]); + } +} + +/************************************************* +* Name: poly_add +* +* Description: Add two polynomials +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_add(poly *r, const poly *a, const poly *b) { + for (size_t i = 0; i < KYBER_N; i++) { + r->coeffs[i] = a->coeffs[i] + b->coeffs[i]; + } +} + +/************************************************* +* Name: poly_sub +* +* Description: Subtract two polynomials +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_sub(poly *r, const poly *a, const poly *b) { + for (size_t i = 0; i < KYBER_N; i++) { + r->coeffs[i] = a->coeffs[i] - b->coeffs[i]; + } +} + +/************************************************* +* Name: poly_frommsg +* +* Description: Convert 32-byte message to polynomial +* +* Arguments: - poly *r: pointer to output polynomial +* - const uint8_t *msg: pointer to input message +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_SYMBYTES]) { + uint16_t mask; + + for (size_t i = 0; i < KYBER_SYMBYTES; i++) { + for (size_t j = 0; j < 8; j++) { + mask = -((msg[i] >> j) & 1); + r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + } + } +} + +/************************************************* +* Name: poly_tomsg +* +* Description: Convert polynomial to 32-byte message +* +* Arguments: - uint8_t *msg: pointer to output message +* - const poly *a: pointer to input polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_poly_tomsg(uint8_t msg[KYBER_SYMBYTES], poly *a) { + uint16_t t; + + PQCLEAN_KYBER512_CLEAN_poly_csubq(a); + + for (size_t i = 0; i < KYBER_SYMBYTES; i++) { + msg[i] = 0; + for (size_t j = 0; j < 8; j++) { + t = (((a->coeffs[8 * i + j] << 1) + KYBER_Q / 2) / KYBER_Q) & 1; + msg[i] |= t << j; + } + } +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.h index ecdc7c2951..90c1655e53 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/poly.h @@ -1,37 +1,37 @@ -#ifndef POLY_H -#define POLY_H - -#include "params.h" - -#include <stdint.h> -/* - * Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial - * coeffs[0] + X*coeffs[1] + X^2*xoeffs[2] + ... + X^{n-1}*coeffs[n-1] - */ -typedef struct { - int16_t coeffs[KYBER_N]; -} poly; - -void PQCLEAN_KYBER512_CLEAN_poly_compress(uint8_t *r, poly *a); -void PQCLEAN_KYBER512_CLEAN_poly_decompress(poly *r, const uint8_t *a); - -void PQCLEAN_KYBER512_CLEAN_poly_tobytes(uint8_t *r, poly *a); -void PQCLEAN_KYBER512_CLEAN_poly_frombytes(poly *r, const uint8_t *a); - -void PQCLEAN_KYBER512_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_SYMBYTES]); -void PQCLEAN_KYBER512_CLEAN_poly_tomsg(uint8_t msg[KYBER_SYMBYTES], poly *a); - -void PQCLEAN_KYBER512_CLEAN_poly_getnoise(poly *r, const uint8_t *seed, uint8_t nonce); - -void PQCLEAN_KYBER512_CLEAN_poly_ntt(poly *r); -void PQCLEAN_KYBER512_CLEAN_poly_invntt(poly *r); -void PQCLEAN_KYBER512_CLEAN_poly_basemul(poly *r, const poly *a, const poly *b); -void PQCLEAN_KYBER512_CLEAN_poly_frommont(poly *r); - -void PQCLEAN_KYBER512_CLEAN_poly_reduce(poly *r); -void PQCLEAN_KYBER512_CLEAN_poly_csubq(poly *r); - -void PQCLEAN_KYBER512_CLEAN_poly_add(poly *r, const poly *a, const poly *b); -void PQCLEAN_KYBER512_CLEAN_poly_sub(poly *r, const poly *a, const poly *b); - -#endif +#ifndef POLY_H +#define POLY_H + +#include "params.h" + +#include <stdint.h> +/* + * Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial + * coeffs[0] + X*coeffs[1] + X^2*xoeffs[2] + ... + X^{n-1}*coeffs[n-1] + */ +typedef struct { + int16_t coeffs[KYBER_N]; +} poly; + +void PQCLEAN_KYBER512_CLEAN_poly_compress(uint8_t *r, poly *a); +void PQCLEAN_KYBER512_CLEAN_poly_decompress(poly *r, const uint8_t *a); + +void PQCLEAN_KYBER512_CLEAN_poly_tobytes(uint8_t *r, poly *a); +void PQCLEAN_KYBER512_CLEAN_poly_frombytes(poly *r, const uint8_t *a); + +void PQCLEAN_KYBER512_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_SYMBYTES]); +void PQCLEAN_KYBER512_CLEAN_poly_tomsg(uint8_t msg[KYBER_SYMBYTES], poly *a); + +void PQCLEAN_KYBER512_CLEAN_poly_getnoise(poly *r, const uint8_t *seed, uint8_t nonce); + +void PQCLEAN_KYBER512_CLEAN_poly_ntt(poly *r); +void PQCLEAN_KYBER512_CLEAN_poly_invntt(poly *r); +void PQCLEAN_KYBER512_CLEAN_poly_basemul(poly *r, const poly *a, const poly *b); +void PQCLEAN_KYBER512_CLEAN_poly_frommont(poly *r); + +void PQCLEAN_KYBER512_CLEAN_poly_reduce(poly *r); +void PQCLEAN_KYBER512_CLEAN_poly_csubq(poly *r); + +void PQCLEAN_KYBER512_CLEAN_poly_add(poly *r, const poly *a, const poly *b); +void PQCLEAN_KYBER512_CLEAN_poly_sub(poly *r, const poly *a, const poly *b); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.c index ab4a352a73..a98efc0502 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.c @@ -1,175 +1,175 @@ -#include "polyvec.h" - -#include "poly.h" - -#include <stddef.h> -#include <stdint.h> -/************************************************* -* Name: polyvec_compress -* -* Description: Compress and serialize vector of polynomials -* -* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYVECCOMPRESSEDBYTES) -* - const polyvec *a: pointer to input vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_compress(uint8_t *r, polyvec *a) { - PQCLEAN_KYBER512_CLEAN_polyvec_csubq(a); - - uint16_t t[4]; - for (size_t i = 0; i < KYBER_K; i++) { - for (size_t j = 0; j < KYBER_N / 4; j++) { - for (size_t k = 0; k < 4; k++) { - t[k] = ((((uint32_t)a->vec[i].coeffs[4 * j + k] << 10) + KYBER_Q / 2) / KYBER_Q) & 0x3ff; - } - - r[5 * j + 0] = (uint8_t)t[0]; - r[5 * j + 1] = (uint8_t)((t[0] >> 8) | ((t[1] & 0x3f) << 2)); - r[5 * j + 2] = (uint8_t)((t[1] >> 6) | ((t[2] & 0x0f) << 4)); - r[5 * j + 3] = (uint8_t)((t[2] >> 4) | ((t[3] & 0x03) << 6)); - r[5 * j + 4] = (uint8_t)((t[3] >> 2)); - } - r += 320; - } -} - -/************************************************* -* Name: polyvec_decompress -* -* Description: De-serialize and decompress vector of polynomials; -* approximate inverse of polyvec_compress -* -* Arguments: - polyvec *r: pointer to output vector of polynomials -* - uint8_t *a: pointer to input byte array (of length KYBER_POLYVECCOMPRESSEDBYTES) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_decompress(polyvec *r, const uint8_t *a) { - for (size_t i = 0; i < KYBER_K; i++) { - for (size_t j = 0; j < KYBER_N / 4; j++) { - r->vec[i].coeffs[4 * j + 0] = (int16_t)( (((a[5 * j + 0] | (((uint32_t)a[5 * j + 1] & 0x03) << 8)) * KYBER_Q) + 512) >> 10); - r->vec[i].coeffs[4 * j + 1] = (int16_t)(((((a[5 * j + 1] >> 2) | (((uint32_t)a[5 * j + 2] & 0x0f) << 6)) * KYBER_Q) + 512) >> 10); - r->vec[i].coeffs[4 * j + 2] = (int16_t)(((((a[5 * j + 2] >> 4) | (((uint32_t)a[5 * j + 3] & 0x3f) << 4)) * KYBER_Q) + 512) >> 10); - r->vec[i].coeffs[4 * j + 3] = (int16_t)(((((a[5 * j + 3] >> 6) | (((uint32_t)a[5 * j + 4] & 0xff) << 2)) * KYBER_Q) + 512) >> 10); - } - a += 320; - } -} - -/************************************************* -* Name: polyvec_tobytes -* -* Description: Serialize vector of polynomials -* -* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYVECBYTES) -* - const polyvec *a: pointer to input vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(uint8_t *r, polyvec *a) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]); - } -} - -/************************************************* -* Name: polyvec_frombytes -* -* Description: De-serialize vector of polynomials; -* inverse of polyvec_tobytes -* -* Arguments: - uint8_t *r: pointer to output byte array -* - const polyvec *a: pointer to input vector of polynomials (of length KYBER_POLYVECBYTES) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t *a) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES); - } -} - -/************************************************* -* Name: polyvec_ntt -* -* Description: Apply forward NTT to all elements of a vector of polynomials -* -* Arguments: - polyvec *r: pointer to in/output vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_ntt(polyvec *r) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_ntt(&r->vec[i]); - } -} - -/************************************************* -* Name: polyvec_invntt -* -* Description: Apply inverse NTT to all elements of a vector of polynomials -* -* Arguments: - polyvec *r: pointer to in/output vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_invntt(polyvec *r) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_invntt(&r->vec[i]); - } -} - -/************************************************* -* Name: polyvec_pointwise_acc -* -* Description: Pointwise multiply elements of a and b and accumulate into r -* -* Arguments: - poly *r: pointer to output polynomial -* - const polyvec *a: pointer to first input vector of polynomials -* - const polyvec *b: pointer to second input vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) { - poly t; - - PQCLEAN_KYBER512_CLEAN_poly_basemul(r, &a->vec[0], &b->vec[0]); - for (size_t i = 1; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_basemul(&t, &a->vec[i], &b->vec[i]); - PQCLEAN_KYBER512_CLEAN_poly_add(r, r, &t); - } - - PQCLEAN_KYBER512_CLEAN_poly_reduce(r); -} - -/************************************************* -* Name: polyvec_reduce -* -* Description: Applies Barrett reduction to each coefficient -* of each element of a vector of polynomials -* for details of the Barrett reduction see comments in reduce.c -* -* Arguments: - poly *r: pointer to input/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_reduce(polyvec *r) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_reduce(&r->vec[i]); - } -} - -/************************************************* -* Name: polyvec_csubq -* -* Description: Applies conditional subtraction of q to each coefficient -* of each element of a vector of polynomials -* for details of conditional subtraction of q see comments in reduce.c -* -* Arguments: - poly *r: pointer to input/output polynomial -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_csubq(polyvec *r) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_csubq(&r->vec[i]); - } -} - -/************************************************* -* Name: polyvec_add -* -* Description: Add vectors of polynomials -* -* Arguments: - polyvec *r: pointer to output vector of polynomials -* - const polyvec *a: pointer to first input vector of polynomials -* - const polyvec *b: pointer to second input vector of polynomials -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) { - for (size_t i = 0; i < KYBER_K; i++) { - PQCLEAN_KYBER512_CLEAN_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]); - } -} +#include "polyvec.h" + +#include "poly.h" + +#include <stddef.h> +#include <stdint.h> +/************************************************* +* Name: polyvec_compress +* +* Description: Compress and serialize vector of polynomials +* +* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYVECCOMPRESSEDBYTES) +* - const polyvec *a: pointer to input vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_compress(uint8_t *r, polyvec *a) { + PQCLEAN_KYBER512_CLEAN_polyvec_csubq(a); + + uint16_t t[4]; + for (size_t i = 0; i < KYBER_K; i++) { + for (size_t j = 0; j < KYBER_N / 4; j++) { + for (size_t k = 0; k < 4; k++) { + t[k] = ((((uint32_t)a->vec[i].coeffs[4 * j + k] << 10) + KYBER_Q / 2) / KYBER_Q) & 0x3ff; + } + + r[5 * j + 0] = (uint8_t)t[0]; + r[5 * j + 1] = (uint8_t)((t[0] >> 8) | ((t[1] & 0x3f) << 2)); + r[5 * j + 2] = (uint8_t)((t[1] >> 6) | ((t[2] & 0x0f) << 4)); + r[5 * j + 3] = (uint8_t)((t[2] >> 4) | ((t[3] & 0x03) << 6)); + r[5 * j + 4] = (uint8_t)((t[3] >> 2)); + } + r += 320; + } +} + +/************************************************* +* Name: polyvec_decompress +* +* Description: De-serialize and decompress vector of polynomials; +* approximate inverse of polyvec_compress +* +* Arguments: - polyvec *r: pointer to output vector of polynomials +* - uint8_t *a: pointer to input byte array (of length KYBER_POLYVECCOMPRESSEDBYTES) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_decompress(polyvec *r, const uint8_t *a) { + for (size_t i = 0; i < KYBER_K; i++) { + for (size_t j = 0; j < KYBER_N / 4; j++) { + r->vec[i].coeffs[4 * j + 0] = (int16_t)( (((a[5 * j + 0] | (((uint32_t)a[5 * j + 1] & 0x03) << 8)) * KYBER_Q) + 512) >> 10); + r->vec[i].coeffs[4 * j + 1] = (int16_t)(((((a[5 * j + 1] >> 2) | (((uint32_t)a[5 * j + 2] & 0x0f) << 6)) * KYBER_Q) + 512) >> 10); + r->vec[i].coeffs[4 * j + 2] = (int16_t)(((((a[5 * j + 2] >> 4) | (((uint32_t)a[5 * j + 3] & 0x3f) << 4)) * KYBER_Q) + 512) >> 10); + r->vec[i].coeffs[4 * j + 3] = (int16_t)(((((a[5 * j + 3] >> 6) | (((uint32_t)a[5 * j + 4] & 0xff) << 2)) * KYBER_Q) + 512) >> 10); + } + a += 320; + } +} + +/************************************************* +* Name: polyvec_tobytes +* +* Description: Serialize vector of polynomials +* +* Arguments: - uint8_t *r: pointer to output byte array (needs space for KYBER_POLYVECBYTES) +* - const polyvec *a: pointer to input vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(uint8_t *r, polyvec *a) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]); + } +} + +/************************************************* +* Name: polyvec_frombytes +* +* Description: De-serialize vector of polynomials; +* inverse of polyvec_tobytes +* +* Arguments: - uint8_t *r: pointer to output byte array +* - const polyvec *a: pointer to input vector of polynomials (of length KYBER_POLYVECBYTES) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t *a) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES); + } +} + +/************************************************* +* Name: polyvec_ntt +* +* Description: Apply forward NTT to all elements of a vector of polynomials +* +* Arguments: - polyvec *r: pointer to in/output vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_ntt(polyvec *r) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_ntt(&r->vec[i]); + } +} + +/************************************************* +* Name: polyvec_invntt +* +* Description: Apply inverse NTT to all elements of a vector of polynomials +* +* Arguments: - polyvec *r: pointer to in/output vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_invntt(polyvec *r) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_invntt(&r->vec[i]); + } +} + +/************************************************* +* Name: polyvec_pointwise_acc +* +* Description: Pointwise multiply elements of a and b and accumulate into r +* +* Arguments: - poly *r: pointer to output polynomial +* - const polyvec *a: pointer to first input vector of polynomials +* - const polyvec *b: pointer to second input vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) { + poly t; + + PQCLEAN_KYBER512_CLEAN_poly_basemul(r, &a->vec[0], &b->vec[0]); + for (size_t i = 1; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_basemul(&t, &a->vec[i], &b->vec[i]); + PQCLEAN_KYBER512_CLEAN_poly_add(r, r, &t); + } + + PQCLEAN_KYBER512_CLEAN_poly_reduce(r); +} + +/************************************************* +* Name: polyvec_reduce +* +* Description: Applies Barrett reduction to each coefficient +* of each element of a vector of polynomials +* for details of the Barrett reduction see comments in reduce.c +* +* Arguments: - poly *r: pointer to input/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_reduce(polyvec *r) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_reduce(&r->vec[i]); + } +} + +/************************************************* +* Name: polyvec_csubq +* +* Description: Applies conditional subtraction of q to each coefficient +* of each element of a vector of polynomials +* for details of conditional subtraction of q see comments in reduce.c +* +* Arguments: - poly *r: pointer to input/output polynomial +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_csubq(polyvec *r) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_csubq(&r->vec[i]); + } +} + +/************************************************* +* Name: polyvec_add +* +* Description: Add vectors of polynomials +* +* Arguments: - polyvec *r: pointer to output vector of polynomials +* - const polyvec *a: pointer to first input vector of polynomials +* - const polyvec *b: pointer to second input vector of polynomials +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) { + for (size_t i = 0; i < KYBER_K; i++) { + PQCLEAN_KYBER512_CLEAN_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]); + } +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.h index 159d1bd29d..5c8c3c30b7 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/polyvec.h @@ -1,29 +1,29 @@ -#ifndef POLYVEC_H -#define POLYVEC_H - -#include "params.h" -#include "poly.h" - -#include <stdint.h> - -typedef struct { - poly vec[KYBER_K]; -} polyvec; - -void PQCLEAN_KYBER512_CLEAN_polyvec_compress(uint8_t *r, polyvec *a); -void PQCLEAN_KYBER512_CLEAN_polyvec_decompress(polyvec *r, const uint8_t *a); - -void PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(uint8_t *r, polyvec *a); -void PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t *a); - -void PQCLEAN_KYBER512_CLEAN_polyvec_ntt(polyvec *r); -void PQCLEAN_KYBER512_CLEAN_polyvec_invntt(polyvec *r); - -void PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b); - -void PQCLEAN_KYBER512_CLEAN_polyvec_reduce(polyvec *r); -void PQCLEAN_KYBER512_CLEAN_polyvec_csubq(polyvec *r); - -void PQCLEAN_KYBER512_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b); - -#endif +#ifndef POLYVEC_H +#define POLYVEC_H + +#include "params.h" +#include "poly.h" + +#include <stdint.h> + +typedef struct { + poly vec[KYBER_K]; +} polyvec; + +void PQCLEAN_KYBER512_CLEAN_polyvec_compress(uint8_t *r, polyvec *a); +void PQCLEAN_KYBER512_CLEAN_polyvec_decompress(polyvec *r, const uint8_t *a); + +void PQCLEAN_KYBER512_CLEAN_polyvec_tobytes(uint8_t *r, polyvec *a); +void PQCLEAN_KYBER512_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t *a); + +void PQCLEAN_KYBER512_CLEAN_polyvec_ntt(polyvec *r); +void PQCLEAN_KYBER512_CLEAN_polyvec_invntt(polyvec *r); + +void PQCLEAN_KYBER512_CLEAN_polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b); + +void PQCLEAN_KYBER512_CLEAN_polyvec_reduce(polyvec *r); +void PQCLEAN_KYBER512_CLEAN_polyvec_csubq(polyvec *r); + +void PQCLEAN_KYBER512_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.c index 60415deefe..4a80fc84e9 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.c @@ -1,61 +1,61 @@ -#include "reduce.h" - -#include "params.h" - -#include <stdint.h> -/************************************************* -* Name: montgomery_reduce -* -* Description: Montgomery reduction; given a 32-bit integer a, computes -* 16-bit integer congruent to a * R^-1 mod q, -* where R=2^16 -* -* Arguments: - int32_t a: input integer to be reduced; has to be in {-q2^15,...,q2^15-1} -* -* Returns: integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q. -**************************************************/ -int16_t PQCLEAN_KYBER512_CLEAN_montgomery_reduce(int32_t a) { - int32_t t; - int16_t u; - - u = (int16_t)(a * (int64_t)QINV); - t = (int32_t)u * KYBER_Q; - t = a - t; - t >>= 16; - return (int16_t)t; -} - -/************************************************* -* Name: barrett_reduce -* -* Description: Barrett reduction; given a 16-bit integer a, computes -* 16-bit integer congruent to a mod q in {0,...,q} -* -* Arguments: - int16_t a: input integer to be reduced -* -* Returns: integer in {0,...,q} congruent to a modulo q. -**************************************************/ -int16_t PQCLEAN_KYBER512_CLEAN_barrett_reduce(int16_t a) { - int32_t t; - const int32_t v = (1U << 26) / KYBER_Q + 1; - - t = v * a; - t >>= 26; - t *= KYBER_Q; - return a - (int16_t)t; -} - -/************************************************* -* Name: csubq -* -* Description: Conditionallly subtract q -* -* Arguments: - int16_t a: input integer -* -* Returns: a - q if a >= q, else a -**************************************************/ -int16_t PQCLEAN_KYBER512_CLEAN_csubq(int16_t a) { - a -= KYBER_Q; - a += (a >> 15) & KYBER_Q; - return a; -} +#include "reduce.h" + +#include "params.h" + +#include <stdint.h> +/************************************************* +* Name: montgomery_reduce +* +* Description: Montgomery reduction; given a 32-bit integer a, computes +* 16-bit integer congruent to a * R^-1 mod q, +* where R=2^16 +* +* Arguments: - int32_t a: input integer to be reduced; has to be in {-q2^15,...,q2^15-1} +* +* Returns: integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q. +**************************************************/ +int16_t PQCLEAN_KYBER512_CLEAN_montgomery_reduce(int32_t a) { + int32_t t; + int16_t u; + + u = (int16_t)(a * (int64_t)QINV); + t = (int32_t)u * KYBER_Q; + t = a - t; + t >>= 16; + return (int16_t)t; +} + +/************************************************* +* Name: barrett_reduce +* +* Description: Barrett reduction; given a 16-bit integer a, computes +* 16-bit integer congruent to a mod q in {0,...,q} +* +* Arguments: - int16_t a: input integer to be reduced +* +* Returns: integer in {0,...,q} congruent to a modulo q. +**************************************************/ +int16_t PQCLEAN_KYBER512_CLEAN_barrett_reduce(int16_t a) { + int32_t t; + const int32_t v = (1U << 26) / KYBER_Q + 1; + + t = v * a; + t >>= 26; + t *= KYBER_Q; + return a - (int16_t)t; +} + +/************************************************* +* Name: csubq +* +* Description: Conditionallly subtract q +* +* Arguments: - int16_t a: input integer +* +* Returns: a - q if a >= q, else a +**************************************************/ +int16_t PQCLEAN_KYBER512_CLEAN_csubq(int16_t a) { + a -= KYBER_Q; + a += (a >> 15) & KYBER_Q; + return a; +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.h index 68a7f570ca..0aeffddaab 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/reduce.h @@ -1,15 +1,15 @@ -#ifndef REDUCE_H -#define REDUCE_H - -#include <stdint.h> - -#define MONT 2285 // 2^16 % Q -#define QINV 62209 // q^(-1) mod 2^16 - -int16_t PQCLEAN_KYBER512_CLEAN_montgomery_reduce(int32_t a); - -int16_t PQCLEAN_KYBER512_CLEAN_barrett_reduce(int16_t a); - -int16_t PQCLEAN_KYBER512_CLEAN_csubq(int16_t a); - -#endif +#ifndef REDUCE_H +#define REDUCE_H + +#include <stdint.h> + +#define MONT 2285 // 2^16 % Q +#define QINV 62209 // q^(-1) mod 2^16 + +int16_t PQCLEAN_KYBER512_CLEAN_montgomery_reduce(int32_t a); + +int16_t PQCLEAN_KYBER512_CLEAN_barrett_reduce(int16_t a); + +int16_t PQCLEAN_KYBER512_CLEAN_csubq(int16_t a); + +#endif diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric-fips202.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric-fips202.c index d482a66682..2596ce444d 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric-fips202.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric-fips202.c @@ -1,63 +1,63 @@ -#include "fips202_kyber_r2.h" -#include "symmetric.h" - -#include <stdlib.h> -/************************************************* -* Name: kyber_shake128_absorb -* -* Description: Absorb step of the SHAKE128 specialized for the Kyber context. - -* Arguments: - keccak_state *s: pointer to (uninitialized) output Keccak state -* - const uint8_t *input: pointer to KYBER_SYMBYTES input to be absorbed into s -* - uint8_t i additional byte of input -* - uint8_t j additional byte of input -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(keccak_state *s, const uint8_t *input, uint8_t x, uint8_t y) { - size_t i; - uint8_t extseed[KYBER_SYMBYTES + 2]; - - for (i = 0; i < KYBER_SYMBYTES; i++) { - extseed[i] = input[i]; - } - extseed[i++] = x; - extseed[i] = y; - shake128_absorb(s, extseed, KYBER_SYMBYTES + 2); -} - -/************************************************* -* Name: kyber_shake128_squeezeblocks -* -* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of SHAKE128_RATE bytes each. -* Modifies the state. Can be called multiple times to keep squeezing, -* i.e., is incremental. -* -* Arguments: - uint8_t *output: pointer to output blocks -* - unsigned long long nblocks: number of blocks to be squeezed (written to output) -* - keccak_state *s: pointer to in/output Keccak state -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(uint8_t *output, size_t nblocks, keccak_state *s) { - shake128_squeezeblocks(output, nblocks, s); -} - -/************************************************* -* Name: shake256_prf -* -* Description: Usage of SHAKE256 as a PRF, concatenates secret and public input -* and then generates outlen bytes of SHAKE256 output -* -* Arguments: - uint8_t *output: pointer to output -* - size_t outlen: number of requested output bytes -* - const uint8_t * key: pointer to the key (of length KYBER_SYMBYTES) -* - const uint8_t nonce: single-byte nonce (public PRF input) -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_shake256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce) { - uint8_t extkey[KYBER_SYMBYTES + 1]; - size_t i; - - for (i = 0; i < KYBER_SYMBYTES; i++) { - extkey[i] = key[i]; - } - extkey[i] = nonce; - - shake256_kyber(output, outlen, extkey, KYBER_SYMBYTES + 1); -} +#include "fips202_kyber_r2.h" +#include "symmetric.h" + +#include <stdlib.h> +/************************************************* +* Name: kyber_shake128_absorb +* +* Description: Absorb step of the SHAKE128 specialized for the Kyber context. + +* Arguments: - keccak_state *s: pointer to (uninitialized) output Keccak state +* - const uint8_t *input: pointer to KYBER_SYMBYTES input to be absorbed into s +* - uint8_t i additional byte of input +* - uint8_t j additional byte of input +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(keccak_state *s, const uint8_t *input, uint8_t x, uint8_t y) { + size_t i; + uint8_t extseed[KYBER_SYMBYTES + 2]; + + for (i = 0; i < KYBER_SYMBYTES; i++) { + extseed[i] = input[i]; + } + extseed[i++] = x; + extseed[i] = y; + shake128_absorb(s, extseed, KYBER_SYMBYTES + 2); +} + +/************************************************* +* Name: kyber_shake128_squeezeblocks +* +* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of SHAKE128_RATE bytes each. +* Modifies the state. Can be called multiple times to keep squeezing, +* i.e., is incremental. +* +* Arguments: - uint8_t *output: pointer to output blocks +* - unsigned long long nblocks: number of blocks to be squeezed (written to output) +* - keccak_state *s: pointer to in/output Keccak state +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(uint8_t *output, size_t nblocks, keccak_state *s) { + shake128_squeezeblocks(output, nblocks, s); +} + +/************************************************* +* Name: shake256_prf +* +* Description: Usage of SHAKE256 as a PRF, concatenates secret and public input +* and then generates outlen bytes of SHAKE256 output +* +* Arguments: - uint8_t *output: pointer to output +* - size_t outlen: number of requested output bytes +* - const uint8_t * key: pointer to the key (of length KYBER_SYMBYTES) +* - const uint8_t nonce: single-byte nonce (public PRF input) +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_shake256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce) { + uint8_t extkey[KYBER_SYMBYTES + 1]; + size_t i; + + for (i = 0; i < KYBER_SYMBYTES; i++) { + extkey[i] = key[i]; + } + extkey[i] = nonce; + + shake256_kyber(output, outlen, extkey, KYBER_SYMBYTES + 1); +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric.h index 26128e2431..ce4befd805 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/symmetric.h @@ -1,30 +1,30 @@ -#ifndef SYMMETRIC_H -#define SYMMETRIC_H - -#include "params.h" - - -#include "fips202_kyber_r2.h" - -#include <stdint.h> -#include <stddef.h> - - -void PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(keccak_state *s, const uint8_t *input, uint8_t x, uint8_t y); -void PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(uint8_t *output, size_t nblocks, keccak_state *s); -void PQCLEAN_KYBER512_CLEAN_shake256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce); - -#define hash_h(OUT, IN, INBYTES) sha3_256(OUT, IN, INBYTES) -#define hash_g(OUT, IN, INBYTES) sha3_512(OUT, IN, INBYTES) -#define xof_absorb(STATE, IN, X, Y) PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(STATE, IN, X, Y) -#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(OUT, OUTBLOCKS, STATE) -#define xof_ctx_release(STATE) shake128_ctx_release(STATE) -#define prf(OUT, OUTBYTES, KEY, NONCE) PQCLEAN_KYBER512_CLEAN_shake256_prf(OUT, OUTBYTES, KEY, NONCE) -#define kdf(OUT, IN, INBYTES) shake256_kyber(OUT, KYBER_SSBYTES, IN, INBYTES) - -#define XOF_BLOCKBYTES 168 - -typedef keccak_state xof_state; - - -#endif /* SYMMETRIC_H */ +#ifndef SYMMETRIC_H +#define SYMMETRIC_H + +#include "params.h" + + +#include "fips202_kyber_r2.h" + +#include <stdint.h> +#include <stddef.h> + + +void PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(keccak_state *s, const uint8_t *input, uint8_t x, uint8_t y); +void PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(uint8_t *output, size_t nblocks, keccak_state *s); +void PQCLEAN_KYBER512_CLEAN_shake256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce); + +#define hash_h(OUT, IN, INBYTES) sha3_256(OUT, IN, INBYTES) +#define hash_g(OUT, IN, INBYTES) sha3_512(OUT, IN, INBYTES) +#define xof_absorb(STATE, IN, X, Y) PQCLEAN_KYBER512_CLEAN_kyber_shake128_absorb(STATE, IN, X, Y) +#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) PQCLEAN_KYBER512_CLEAN_kyber_shake128_squeezeblocks(OUT, OUTBLOCKS, STATE) +#define xof_ctx_release(STATE) shake128_ctx_release(STATE) +#define prf(OUT, OUTBYTES, KEY, NONCE) PQCLEAN_KYBER512_CLEAN_shake256_prf(OUT, OUTBYTES, KEY, NONCE) +#define kdf(OUT, IN, INBYTES) shake256_kyber(OUT, KYBER_SSBYTES, IN, INBYTES) + +#define XOF_BLOCKBYTES 168 + +typedef keccak_state xof_state; + + +#endif /* SYMMETRIC_H */ diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.c b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.c index 149e52d7b0..5fcbf00577 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.c +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.c @@ -1,50 +1,50 @@ -#include "verify.h" - -#include <stddef.h> -#include <stdint.h> - -/************************************************* -* Name: verify -* -* Description: Compare two arrays for equality in constant time. -* -* Arguments: const uint8_t *a: pointer to first byte array -* const uint8_t *b: pointer to second byte array -* size_t len: length of the byte arrays -* -* Returns 0 if the byte arrays are equal, 1 otherwise -**************************************************/ -uint8_t PQCLEAN_KYBER512_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len) { - uint64_t r; - size_t i; - r = 0; - - for (i = 0; i < len; i++) { - r |= a[i] ^ b[i]; - } - - r = (-r) >> 63; - return (uint8_t)r; -} - -/************************************************* -* Name: cmov -* -* Description: Copy len bytes from x to r if b is 1; -* don't modify x if b is 0. Requires b to be in {0,1}; -* assumes two's complement representation of negative integers. -* Runs in constant time. -* -* Arguments: uint8_t *r: pointer to output byte array -* const uint8_t *x: pointer to input byte array -* size_t len: Amount of bytes to be copied -* uint8_t b: Condition bit; has to be in {0,1} -**************************************************/ -void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { - size_t i; - - b = -b; - for (i = 0; i < len; i++) { - r[i] ^= b & (x[i] ^ r[i]); - } -} +#include "verify.h" + +#include <stddef.h> +#include <stdint.h> + +/************************************************* +* Name: verify +* +* Description: Compare two arrays for equality in constant time. +* +* Arguments: const uint8_t *a: pointer to first byte array +* const uint8_t *b: pointer to second byte array +* size_t len: length of the byte arrays +* +* Returns 0 if the byte arrays are equal, 1 otherwise +**************************************************/ +uint8_t PQCLEAN_KYBER512_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len) { + uint64_t r; + size_t i; + r = 0; + + for (i = 0; i < len; i++) { + r |= a[i] ^ b[i]; + } + + r = (-r) >> 63; + return (uint8_t)r; +} + +/************************************************* +* Name: cmov +* +* Description: Copy len bytes from x to r if b is 1; +* don't modify x if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint8_t *r: pointer to output byte array +* const uint8_t *x: pointer to input byte array +* size_t len: Amount of bytes to be copied +* uint8_t b: Condition bit; has to be in {0,1} +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { + size_t i; + + b = -b; + for (i = 0; i < len; i++) { + r[i] ^= b & (x[i] ^ r[i]); + } +} diff --git a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.h b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.h index d95be219df..fc75db0408 100644 --- a/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.h +++ b/contrib/restricted/aws/s2n/pq-crypto/kyber_r2/verify.h @@ -1,11 +1,11 @@ -#ifndef VERIFY_H -#define VERIFY_H - -#include <stddef.h> -#include <stdint.h> - -uint8_t PQCLEAN_KYBER512_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len); - -void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); - -#endif +#ifndef VERIFY_H +#define VERIFY_H + +#include <stddef.h> +#include <stdint.h> + +uint8_t PQCLEAN_KYBER512_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len); + +void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); + +#endif |