diff --git a/crypto/dilithium/ml_dsa.c b/crypto/dilithium/ml_dsa.c index a3a67ff392..1c80a1a524 100644 --- a/crypto/dilithium/ml_dsa.c +++ b/crypto/dilithium/ml_dsa.c @@ -9,7 +9,6 @@ // These includes are required to compile ML-DSA. These can be moved to bcm.c // when ML-DSA is added to the fipsmodule directory. -#include "./pqcrystals_dilithium_ref_common/fips202.c" #include "./pqcrystals_dilithium_ref_common/ntt.c" #include "./pqcrystals_dilithium_ref_common/packing.c" #include "./pqcrystals_dilithium_ref_common/params.c" @@ -18,7 +17,6 @@ #include "./pqcrystals_dilithium_ref_common/reduce.c" #include "./pqcrystals_dilithium_ref_common/rounding.c" #include "./pqcrystals_dilithium_ref_common/sign.c" -#include "./pqcrystals_dilithium_ref_common/symmetric-shake.c" // Note: These methods currently default to using the reference code for // ML-DSA. In a future where AWS-LC has optimized options available, diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/README.md b/crypto/dilithium/pqcrystals_dilithium_ref_common/README.md index db45b8e711..b91cf92d1b 100644 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/README.md +++ b/crypto/dilithium/pqcrystals_dilithium_ref_common/README.md @@ -10,6 +10,7 @@ The code was refactored in [this PR](https://github.com/aws/aws-lc/pull/1910) by that initialize a given structure with values corresponding to a parameter set. This structure is then passed to every function that requires it as a function argument. In addition, the following changes were made to the source code in `pqcrystals_dilithium_ref_common` directory: - `randombytes.{h|c}` are deleted because we are using the randomness generation functions provided by AWS-LC. +- `fips202.{h|c}`, `symmetric.h`, `symmetric-shake.c` are deleted as all SHA3/SHAKE functionality is provided instead by AWS-LC fipsmodule/sha rather than the reference implementation. Calls to `dilithium_shake128_stream_init` and `dilithium_shake256_stream_init` have been inlined. - `sign.c`: calls to `randombytes` function is replaced with calls to `RAND_bytes` and the appropriate header file is included (`openssl/rand.h`). - `ntt.c`, `poly.c`, `reduce.c`, `reduce.h`: have been modified with a code refactor. The function `fqmul` has been added to bring mode code consistency with Kyber/ML-KEM. See https://github.com/aws/aws-lc/pull/1748 for more details on this change. - `reduce.c`: a small fix to documentation has been made on the bounds of `reduce32`. @@ -21,4 +22,4 @@ that initialize a given structure with values corresponding to a parameter set. **Testing** -The KATs were obtained from https://github.com/post-quantum-cryptography/KAT. We select the KATs for the signing mode `hedged`, which derives the signing private random seed (rho) pseudorandomly from the signer's private key, the message to be signed, and a 256-bit string `rnd` which is generated at random. The `pure` variant of these KATs were used, as they provide test vector inputs for "pure" i.e., non-pre-hashed messages. The KAT files have been modified to insert linebreaks between each test vector set. \ No newline at end of file +The KATs were obtained from https://github.com/post-quantum-cryptography/KAT. We select the KATs for the signing mode `hedged`, which derives the signing private random seed (rho) pseudorandomly from the signer's private key, the message to be signed, and a 256-bit string `rnd` which is generated at random. The `pure` variant of these KATs were used, as they provide test vector inputs for "pure" i.e., non-pre-hashed messages. The KAT files have been modified to insert linebreaks between each test vector set. diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.c b/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.c deleted file mode 100644 index 2afe799ea7..0000000000 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.c +++ /dev/null @@ -1,774 +0,0 @@ -/* 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 */ - -#include -#include -#include "fips202.h" - -#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[8]) { - unsigned int i; - uint64_t r = 0; - - for(i=0;i<8;i++) - r |= (uint64_t)x[i] << 8*i; - - return r; -} - -/************************************************* -* Name: store64 -* -* Description: Store a 64-bit integer to array of 8 bytes in little-endian order -* -* Arguments: - uint8_t *x: pointer to the output byte array (allocated) -* - uint64_t u: input 64-bit unsigned integer -**************************************************/ -static void store64(uint8_t x[8], uint64_t u) { - unsigned int i; - - for(i=0;i<8;i++) - x[i] = u >> 8*i; -} - -/* Keccak round constants */ -const uint64_t KeccakF_RoundConstants[NROUNDS] = { - (uint64_t)0x0000000000000001ULL, - (uint64_t)0x0000000000008082ULL, - (uint64_t)0x800000000000808aULL, - (uint64_t)0x8000000080008000ULL, - (uint64_t)0x000000000000808bULL, - (uint64_t)0x0000000080000001ULL, - (uint64_t)0x8000000080008081ULL, - (uint64_t)0x8000000000008009ULL, - (uint64_t)0x000000000000008aULL, - (uint64_t)0x0000000000000088ULL, - (uint64_t)0x0000000080008009ULL, - (uint64_t)0x000000008000000aULL, - (uint64_t)0x000000008000808bULL, - (uint64_t)0x800000000000008bULL, - (uint64_t)0x8000000000008089ULL, - (uint64_t)0x8000000000008003ULL, - (uint64_t)0x8000000000008002ULL, - (uint64_t)0x8000000000000080ULL, - (uint64_t)0x000000000000800aULL, - (uint64_t)0x800000008000000aULL, - (uint64_t)0x8000000080008081ULL, - (uint64_t)0x8000000000008080ULL, - (uint64_t)0x0000000080000001ULL, - (uint64_t)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[25]) -{ - 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; - 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; - - //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) { - // 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 ^= (uint64_t)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 ^= (uint64_t)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_init -* -* Description: Initializes the Keccak state. -* -* Arguments: - uint64_t *s: pointer to Keccak state -**************************************************/ -static void keccak_init(uint64_t s[25]) -{ - unsigned int i; - for(i=0;i<25;i++) - s[i] = 0; -} - -/************************************************* -* Name: keccak_absorb -* -* Description: Absorb step of Keccak; incremental. -* -* Arguments: - uint64_t *s: pointer to Keccak state -* - unsigned int pos: position in current block to be absorbed -* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128) -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -* -* Returns new position pos in current block -**************************************************/ -static unsigned int keccak_absorb(uint64_t s[25], - unsigned int pos, - unsigned int r, - const uint8_t *in, - size_t inlen) -{ - unsigned int i; - - while(pos+inlen >= r) { - for(i=pos;i> 8*(i%8); - outlen -= i-pos; - pos = i; - } - - return pos; -} - - -/************************************************* -* Name: keccak_absorb_once -* -* Description: Absorb step of Keccak; -* non-incremental, starts by zeroeing the state. -* -* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state -* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128) -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -* - uint8_t p: domain-separation byte for different Keccak-derived functions -**************************************************/ -static void keccak_absorb_once(uint64_t s[25], - unsigned int r, - const uint8_t *in, - size_t inlen, - uint8_t p) -{ - unsigned int i; - - for(i=0;i<25;i++) - s[i] = 0; - - while(inlen >= r) { - for(i=0;is); - state->pos = 0; -} - -/************************************************* -* Name: shake128_absorb -* -* Description: Absorb step of the SHAKE128 XOF; incremental. -* -* Arguments: - keccak_state *state: pointer to (initialized) output Keccak state -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -**************************************************/ -void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen) -{ - state->pos = keccak_absorb(state->s, state->pos, SHAKE128_RATE, in, inlen); -} - -/************************************************* -* Name: shake128_finalize -* -* Description: Finalize absorb step of the SHAKE128 XOF. -* -* Arguments: - keccak_state *state: pointer to Keccak state -**************************************************/ -void shake128_finalize(keccak_state *state) -{ - keccak_finalize(state->s, state->pos, SHAKE128_RATE, 0x1F); - state->pos = SHAKE128_RATE; -} - -/************************************************* -* Name: shake128_squeeze -* -* Description: Squeeze step of SHAKE128 XOF. Squeezes arbitraily many -* bytes. Can be called multiple times to keep squeezing. -* -* Arguments: - uint8_t *out: pointer to output blocks -* - size_t outlen : number of bytes to be squeezed (written to output) -* - keccak_state *s: pointer to input/output Keccak state -**************************************************/ -void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state) -{ - state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE128_RATE); -} - -/************************************************* -* Name: shake128_absorb_once -* -* Description: Initialize, absorb into and finalize SHAKE128 XOF; non-incremental. -* -* Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak state -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -**************************************************/ -void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen) -{ - keccak_absorb_once(state->s, SHAKE128_RATE, in, inlen, 0x1F); - state->pos = SHAKE128_RATE; -} - -/************************************************* -* Name: shake128_squeezeblocks -* -* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of -* SHAKE128_RATE bytes each. Can be called multiple times -* to keep squeezing. Assumes new block has not yet been -* started (state->pos = SHAKE128_RATE). -* -* Arguments: - uint8_t *out: pointer to output blocks -* - size_t nblocks: number of blocks to be squeezed (written to output) -* - keccak_state *s: pointer to input/output Keccak state -**************************************************/ -void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state) -{ - keccak_squeezeblocks(out, nblocks, state->s, SHAKE128_RATE); -} - -/************************************************* -* Name: shake256_init -* -* Description: Initilizes Keccak state for use as SHAKE256 XOF -* -* Arguments: - keccak_state *state: pointer to (uninitialized) Keccak state -**************************************************/ -void shake256_init(keccak_state *state) -{ - keccak_init(state->s); - state->pos = 0; -} - -/************************************************* -* Name: shake256_absorb -* -* Description: Absorb step of the SHAKE256 XOF; incremental. -* -* Arguments: - keccak_state *state: pointer to (initialized) output Keccak state -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -**************************************************/ -void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen) -{ - state->pos = keccak_absorb(state->s, state->pos, SHAKE256_RATE, in, inlen); -} - -/************************************************* -* Name: shake256_finalize -* -* Description: Finalize absorb step of the SHAKE256 XOF. -* -* Arguments: - keccak_state *state: pointer to Keccak state -**************************************************/ -void shake256_finalize(keccak_state *state) -{ - keccak_finalize(state->s, state->pos, SHAKE256_RATE, 0x1F); - state->pos = SHAKE256_RATE; -} - -/************************************************* -* Name: shake256_squeeze -* -* Description: Squeeze step of SHAKE256 XOF. Squeezes arbitraily many -* bytes. Can be called multiple times to keep squeezing. -* -* Arguments: - uint8_t *out: pointer to output blocks -* - size_t outlen : number of bytes to be squeezed (written to output) -* - keccak_state *s: pointer to input/output Keccak state -**************************************************/ -void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state) -{ - state->pos = keccak_squeeze(out, outlen, state->s, state->pos, SHAKE256_RATE); -} - -/************************************************* -* Name: shake256_absorb_once -* -* Description: Initialize, absorb into and finalize SHAKE256 XOF; non-incremental. -* -* Arguments: - keccak_state *state: pointer to (uninitialized) output Keccak state -* - const uint8_t *in: pointer to input to be absorbed into s -* - size_t inlen: length of input in bytes -**************************************************/ -void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen) -{ - keccak_absorb_once(state->s, SHAKE256_RATE, in, inlen, 0x1F); - state->pos = SHAKE256_RATE; -} - -/************************************************* -* Name: shake256_squeezeblocks -* -* Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of -* SHAKE256_RATE bytes each. Can be called multiple times -* to keep squeezing. Assumes next block has not yet been -* started (state->pos = SHAKE256_RATE). -* -* Arguments: - uint8_t *out: pointer to output blocks -* - size_t nblocks: number of blocks to be squeezed (written to output) -* - keccak_state *s: pointer to input/output Keccak state -**************************************************/ -void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state) -{ - keccak_squeezeblocks(out, nblocks, state->s, SHAKE256_RATE); -} - -/************************************************* -* Name: shake128 -* -* Description: SHAKE128 XOF with non-incremental API -* -* Arguments: - uint8_t *out: pointer to output -* - size_t outlen: requested output length in bytes -* - const uint8_t *in: pointer to input -* - size_t inlen: length of input in bytes -**************************************************/ -void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) -{ - size_t nblocks; - keccak_state state; - - shake128_absorb_once(&state, in, inlen); - nblocks = outlen/SHAKE128_RATE; - shake128_squeezeblocks(out, nblocks, &state); - outlen -= nblocks*SHAKE128_RATE; - out += nblocks*SHAKE128_RATE; - shake128_squeeze(out, outlen, &state); -} - -/************************************************* -* Name: shake256 -* -* Description: SHAKE256 XOF with non-incremental API -* -* Arguments: - uint8_t *out: pointer to output -* - size_t outlen: requested output length in bytes -* - const uint8_t *in: pointer to input -* - size_t inlen: length of input in bytes -**************************************************/ -void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) -{ - size_t nblocks; - keccak_state state; - - shake256_absorb_once(&state, in, inlen); - nblocks = outlen/SHAKE256_RATE; - shake256_squeezeblocks(out, nblocks, &state); - outlen -= nblocks*SHAKE256_RATE; - out += nblocks*SHAKE256_RATE; - shake256_squeeze(out, outlen, &state); -} - -/************************************************* -* Name: sha3_256 -* -* Description: SHA3-256 with non-incremental API -* -* Arguments: - uint8_t *h: pointer to output (32 bytes) -* - const uint8_t *in: pointer to input -* - size_t inlen: length of input in bytes -**************************************************/ -void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen) -{ - unsigned int i; - uint64_t s[25]; - - keccak_absorb_once(s, SHA3_256_RATE, in, inlen, 0x06); - KeccakF1600_StatePermute(s); - for(i=0;i<4;i++) - store64(h+8*i,s[i]); -} - -/************************************************* -* Name: sha3_512 -* -* Description: SHA3-512 with non-incremental API -* -* Arguments: - uint8_t *h: pointer to output (64 bytes) -* - const uint8_t *in: pointer to input -* - size_t inlen: length of input in bytes -**************************************************/ -void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen) -{ - unsigned int i; - uint64_t s[25]; - - keccak_absorb_once(s, SHA3_512_RATE, in, inlen, 0x06); - KeccakF1600_StatePermute(s); - for(i=0;i<8;i++) - store64(h+8*i,s[i]); -} diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.h b/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.h deleted file mode 100644 index c033ff0958..0000000000 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/fips202.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef FIPS202_H -#define FIPS202_H - -#include -#include -#include - -#define SHAKE128_RATE 168 -#define SHAKE256_RATE 136 -#define SHA3_256_RATE 136 -#define SHA3_512_RATE 72 - -#define FIPS202_PREFIX(s) pqcrystals_dilithium_fips202_ref_##s - -#ifdef BORINGSSL_PREFIX -#define FIPS202_NAMESPACE(s) BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS202_PREFIX(s)) -#else -#define FIPS202_NAMESPACE(s) FIPS202_PREFIX(s) -#endif - -typedef struct { - uint64_t s[25]; - unsigned int pos; -} keccak_state; - -#define KeccakF_RoundConstants FIPS202_NAMESPACE(KeccakF_RoundConstants) -extern const uint64_t KeccakF_RoundConstants[]; - -#define shake128_init FIPS202_NAMESPACE(shake128_init) -void shake128_init(keccak_state *state); -#define shake128_absorb FIPS202_NAMESPACE(shake128_absorb) -void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen); -#define shake128_finalize FIPS202_NAMESPACE(shake128_finalize) -void shake128_finalize(keccak_state *state); -#define shake128_squeeze FIPS202_NAMESPACE(shake128_squeeze) -void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state); -#define shake128_absorb_once FIPS202_NAMESPACE(shake128_absorb_once) -void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen); -#define shake128_squeezeblocks FIPS202_NAMESPACE(shake128_squeezeblocks) -void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state); - -#define shake256_init FIPS202_NAMESPACE(shake256_init) -void shake256_init(keccak_state *state); -#define shake256_absorb FIPS202_NAMESPACE(shake256_absorb) -void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen); -#define shake256_finalize FIPS202_NAMESPACE(shake256_finalize) -void shake256_finalize(keccak_state *state); -#define shake256_squeeze FIPS202_NAMESPACE(shake256_squeeze) -void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state); -#define shake256_absorb_once FIPS202_NAMESPACE(shake256_absorb_once) -void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen); -#define shake256_squeezeblocks FIPS202_NAMESPACE(shake256_squeezeblocks) -void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state); - -#define shake128 FIPS202_NAMESPACE(shake128) -void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen); -#define shake256 FIPS202_NAMESPACE(shake256) -void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen); -#define sha3_256 FIPS202_NAMESPACE(sha3_256) -void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen); -#define sha3_512 FIPS202_NAMESPACE(sha3_512) -void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen); - -#endif diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/params.h b/crypto/dilithium/pqcrystals_dilithium_ref_common/params.h index 2369996c37..2cdbaad391 100644 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/params.h +++ b/crypto/dilithium/pqcrystals_dilithium_ref_common/params.h @@ -42,7 +42,7 @@ typedef struct { #define DILITHIUM_L_MAX (7) #define DILITHIUM_C_TILDE_BYTES_MAX (64) #define DILITHIUM_POLYW1_PACKEDBYTES_MAX (192) -#define DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX ((227 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES) +#define DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX ((227 + SHAKE256_RATE - 1)/SHAKE256_RATE) #define DILITHIUM_POLYZ_PACKEDBYTES_MAX (576) void ml_dsa_44_params_init(ml_dsa_params *params); diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/poly.c b/crypto/dilithium/pqcrystals_dilithium_ref_common/poly.c index c73615fd27..ab257b71ac 100644 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/poly.c +++ b/crypto/dilithium/pqcrystals_dilithium_ref_common/poly.c @@ -4,7 +4,7 @@ #include "ntt.h" #include "reduce.h" #include "rounding.h" -#include "symmetric.h" +#include "../../fipsmodule/sha/internal.h" /************************************************* * Name: poly_reduce @@ -290,18 +290,24 @@ static unsigned int rej_uniform(int32_t *a, * - const uint8_t seed[]: byte array with seed of length SEEDBYTES * - uint16_t nonce: 2-byte nonce **************************************************/ -#define POLY_UNIFORM_NBLOCKS ((768 + STREAM128_BLOCKBYTES - 1)/STREAM128_BLOCKBYTES) +#define POLY_UNIFORM_NBLOCKS ((768 + SHAKE128_RATE - 1)/ SHAKE128_RATE) void poly_uniform(poly *a, const uint8_t seed[SEEDBYTES], uint16_t nonce) { unsigned int i, ctr, off; - unsigned int buflen = POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES; - uint8_t buf[POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES + 2]; - stream128_state state; + unsigned int buflen = POLY_UNIFORM_NBLOCKS*SHAKE128_RATE; + uint8_t buf[POLY_UNIFORM_NBLOCKS*SHAKE128_RATE + 2]; + KECCAK1600_CTX state; - stream128_init(&state, seed, nonce); - stream128_squeezeblocks(buf, POLY_UNIFORM_NBLOCKS, &state); + uint8_t t[2]; + t[0] = nonce & 0xff; + t[1] = nonce >> 8; + + SHAKE_Init(&state, SHAKE128_BLOCKSIZE); + SHA3_Update(&state, seed, SEEDBYTES); + SHA3_Update(&state, t, 2); + SHAKE_Final(buf, &state, POLY_UNIFORM_NBLOCKS * SHAKE128_BLOCKSIZE); ctr = rej_uniform(a->coeffs, N, buf, buflen); @@ -310,8 +316,8 @@ void poly_uniform(poly *a, for(i = 0; i < off; ++i) buf[i] = buf[buflen - off + i]; - stream128_squeezeblocks(buf + off, 1, &state); - buflen = STREAM128_BLOCKBYTES + off; + SHAKE_Final(buf + off, &state, POLY_UNIFORM_NBLOCKS * SHAKE128_BLOCKSIZE); + buflen = SHAKE128_RATE + off; ctr += rej_uniform(a->coeffs + ctr, N - ctr, buf, buflen); } /* FIPS 204. Section 3.6.3 Destruction of intermediate values. */ @@ -392,18 +398,24 @@ void poly_uniform_eta(ml_dsa_params *params, uint16_t nonce) { unsigned int ctr; - unsigned int buflen = DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX*STREAM256_BLOCKBYTES; - uint8_t buf[DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX*STREAM256_BLOCKBYTES]; - stream256_state state; + unsigned int buflen = DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX * SHAKE256_RATE; + uint8_t buf[DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX * SHAKE256_RATE]; + KECCAK1600_CTX state; + + uint8_t t[2]; + t[0] = nonce & 0xff; + t[1] = nonce >> 8; - stream256_init(&state, seed, nonce); - stream256_squeezeblocks(buf, DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, seed, CRHBYTES); + SHA3_Update(&state, t, 2); + SHAKE_Final(buf, &state, DILITHIUM_POLY_UNIFORM_ETA_NBLOCKS_MAX * SHAKE256_BLOCKSIZE); ctr = rej_eta(params, a->coeffs, N, buf, buflen); while(ctr < N) { - stream256_squeezeblocks(buf, 1, &state); - ctr += rej_eta(params, a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES); + SHAKE_Final(buf, &state, SHAKE256_BLOCKSIZE); + ctr += rej_eta(params, a->coeffs + ctr, N - ctr, buf, SHAKE256_RATE); } /* FIPS 204. Section 3.6.3 Destruction of intermediate values. */ OPENSSL_cleanse(buf, sizeof(buf)); @@ -422,17 +434,24 @@ void poly_uniform_eta(ml_dsa_params *params, * - const uint8_t seed[]: byte array with seed of length CRHBYTES * - uint16_t nonce: 16-bit nonce **************************************************/ -#define POLY_UNIFORM_GAMMA1_NBLOCKS ((DILITHIUM_POLYZ_PACKEDBYTES_MAX + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES) +#define POLY_UNIFORM_GAMMA1_NBLOCKS ((DILITHIUM_POLYZ_PACKEDBYTES_MAX + SHAKE256_RATE - 1) / SHAKE256_RATE) void poly_uniform_gamma1(ml_dsa_params *params, poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce) { - uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS*STREAM256_BLOCKBYTES]; - stream256_state state; + uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS * SHAKE256_RATE]; + KECCAK1600_CTX state; + + uint8_t t[2]; + t[0] = nonce & 0xff; + t[1] = nonce >> 8; + + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, seed, CRHBYTES); + SHA3_Update(&state, t, 2); - stream256_init(&state, seed, nonce); - stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS, &state); + SHAKE_Final(buf, &state, POLY_UNIFORM_GAMMA1_NBLOCKS * SHAKE256_BLOCKSIZE); polyz_unpack(params, a, buf); /* FIPS 204. Section 3.6.3 Destruction of intermediate values. */ OPENSSL_cleanse(buf, sizeof(buf)); @@ -454,12 +473,11 @@ void poly_challenge(ml_dsa_params *params, poly *c, const uint8_t *seed) { unsigned int i, b, pos; uint64_t signs; uint8_t buf[SHAKE256_RATE]; - keccak_state state; + KECCAK1600_CTX state; - shake256_init(&state); - shake256_absorb(&state, seed, params->c_tilde_bytes); - shake256_finalize(&state); - shake256_squeezeblocks(buf, 1, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, seed, params->c_tilde_bytes); + SHAKE_Final(buf, &state, SHAKE256_BLOCKSIZE); signs = 0; for(i = 0; i < 8; ++i) { @@ -473,7 +491,7 @@ void poly_challenge(ml_dsa_params *params, poly *c, const uint8_t *seed) { for(i = N-params->tau; i < N; ++i) { do { if(pos >= SHAKE256_RATE) { - shake256_squeezeblocks(buf, 1, &state); + SHAKE_Final(buf, &state, SHAKE256_BLOCKSIZE); pos = 0; } diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/sign.c b/crypto/dilithium/pqcrystals_dilithium_ref_common/sign.c index ea3ffb5cc7..ae0568d66c 100644 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/sign.c +++ b/crypto/dilithium/pqcrystals_dilithium_ref_common/sign.c @@ -2,12 +2,11 @@ #include #include "../../internal.h" #include "openssl/rand.h" -#include "fips202.h" #include "packing.h" #include "params.h" #include "poly.h" #include "polyvec.h" -#include "symmetric.h" + /************************************************* * Name: crypto_sign_keypair_internal @@ -38,7 +37,7 @@ int crypto_sign_keypair_internal(ml_dsa_params *params, OPENSSL_memcpy(seedbuf, seed, SEEDBYTES); seedbuf[SEEDBYTES+0] = params->k; seedbuf[SEEDBYTES+1] = params->l; - shake256(seedbuf, 2*SEEDBYTES + CRHBYTES, seedbuf, SEEDBYTES+2); + SHAKE256(seedbuf, SEEDBYTES + 2, seedbuf, 2 * SEEDBYTES + CRHBYTES); rho = seedbuf; rhoprime = rho + SEEDBYTES; key = rhoprime + CRHBYTES; @@ -67,7 +66,7 @@ int crypto_sign_keypair_internal(ml_dsa_params *params, pack_pk(params, pk, rho, &t1); /* FIPS 204: line 9 Compute H(rho, t1) and line 10 write secret key */ - shake256(tr, TRBYTES, pk, params->public_key_bytes); + SHAKE256(pk, params->public_key_bytes, tr, TRBYTES); pack_sk(params, sk, rho, tr, key, &t0, &s1, &s2); /* FIPS 204. Section 3.6.3 Destruction of intermediate values. */ @@ -141,7 +140,7 @@ int crypto_sign_signature_internal(ml_dsa_params *params, polyvecl mat[DILITHIUM_K_MAX], s1, y, z; polyveck t0, s2, w1, w0, h; poly cp; - keccak_state state; + KECCAK1600_CTX state; rho = seedbuf; tr = rho + SEEDBYTES; @@ -155,20 +154,18 @@ int crypto_sign_signature_internal(ml_dsa_params *params, // This differs from FIPS 204 line 6 that performs mu = CRH(tr, M') and the // processing of M' in the external function. However, as M' = (pre, msg), // mu = CRH(tr, M') = CRH(tr, pre, msg). - shake256_init(&state); - shake256_absorb(&state, tr, TRBYTES); - shake256_absorb(&state, pre, prelen); - shake256_absorb(&state, m, mlen); - shake256_finalize(&state); - shake256_squeeze(mu, CRHBYTES, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, tr, TRBYTES); + SHA3_Update(&state, pre, prelen); + SHA3_Update(&state, m, mlen); + SHAKE_Final(mu, &state, CRHBYTES); /* FIPS 204: line 7 Compute rhoprime = CRH(key, rnd, mu) */ - shake256_init(&state); - shake256_absorb(&state, key, SEEDBYTES); - shake256_absorb(&state, rnd, RNDBYTES); - shake256_absorb(&state, mu, CRHBYTES); - shake256_finalize(&state); - shake256_squeeze(rhoprime, CRHBYTES, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, key, SEEDBYTES); + SHA3_Update(&state, rnd, RNDBYTES); + SHA3_Update(&state, mu, CRHBYTES); + SHAKE_Final(rhoprime, &state, CRHBYTES); /* FIPS 204: line 5 Expand matrix and transform vectors */ polyvec_matrix_expand(params, mat, rho); @@ -192,11 +189,10 @@ int crypto_sign_signature_internal(ml_dsa_params *params, polyveck_decompose(params, &w1, &w0, &w1); polyveck_pack_w1(params, sig, &w1); - shake256_init(&state); - shake256_absorb(&state, mu, CRHBYTES); - shake256_absorb(&state, sig, params->k * params->poly_w1_packed_bytes); - shake256_finalize(&state); - shake256_squeeze(sig, params->c_tilde_bytes, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, mu, CRHBYTES); + SHA3_Update(&state, sig, params->k * params->poly_w1_packed_bytes); + SHAKE_Final(sig, &state, params->c_tilde_bytes); poly_challenge(params, &cp, sig); poly_ntt(&cp); @@ -226,6 +222,7 @@ int crypto_sign_signature_internal(ml_dsa_params *params, if(polyveck_chknorm(params, &h, params->gamma2)) { goto rej; } + /* FIPS 204: line 26 Compute signer's hint */ polyveck_add(params, &w0, &w0, &h); n = polyveck_make_hint(params, &h, &w0, &w1); @@ -376,7 +373,7 @@ int crypto_sign_verify_internal(ml_dsa_params *params, poly cp; polyvecl mat[DILITHIUM_K_MAX], z; polyveck t1, w1, h; - keccak_state state; + KECCAK1600_CTX state; if(siglen != params->bytes) { return -1; @@ -392,16 +389,15 @@ int crypto_sign_verify_internal(ml_dsa_params *params, } /* FIPS 204: line 6 Compute tr */ - shake256(tr, TRBYTES, pk, params->public_key_bytes); + SHAKE256(pk, params->public_key_bytes, tr, TRBYTES); /* FIPS 204: line 7 Compute mu = H(BytesToBits(tr) || M', 64) */ // Like crypto_sign_signature_internal, the processing of M' is performed // here, as opposed to within the external function. - shake256_init(&state); - shake256_absorb(&state, tr, TRBYTES); - shake256_absorb(&state, pre, prelen); - shake256_absorb(&state, m, mlen); - shake256_finalize(&state); - shake256_squeeze(mu, CRHBYTES, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, tr, TRBYTES); + SHA3_Update(&state, pre, prelen); + SHA3_Update(&state, m, mlen); + SHAKE_Final(mu, &state, CRHBYTES); /* FIPS 204: line 9 Matrix-vector multiplication; compute Az - c2^dt1 */ poly_challenge(params, &cp, c); @@ -425,11 +421,10 @@ int crypto_sign_verify_internal(ml_dsa_params *params, polyveck_pack_w1(params, buf, &w1); /* FIPS 204: line 12 Call random oracle and verify challenge */ - shake256_init(&state); - shake256_absorb(&state, mu, CRHBYTES); - shake256_absorb(&state, buf, params->k * params->poly_w1_packed_bytes); - shake256_finalize(&state); - shake256_squeeze(c2, params->c_tilde_bytes, &state); + SHAKE_Init(&state, SHAKE256_BLOCKSIZE); + SHA3_Update(&state, mu, CRHBYTES); + SHA3_Update(&state, buf, params->k * params->poly_w1_packed_bytes); + SHAKE_Final(c2, &state, params->c_tilde_bytes); for(i = 0; i < params->c_tilde_bytes; ++i) { if(c[i] != c2[i]) { return -1; diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric-shake.c b/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric-shake.c deleted file mode 100644 index 11ec09cce6..0000000000 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric-shake.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "params.h" -#include "symmetric.h" -#include "fips202.h" - -void dilithium_shake128_stream_init(keccak_state *state, const uint8_t seed[SEEDBYTES], uint16_t nonce) -{ - uint8_t t[2]; - t[0] = nonce; - t[1] = nonce >> 8; - - shake128_init(state); - shake128_absorb(state, seed, SEEDBYTES); - shake128_absorb(state, t, 2); - shake128_finalize(state); -} - -void dilithium_shake256_stream_init(keccak_state *state, const uint8_t seed[CRHBYTES], uint16_t nonce) -{ - uint8_t t[2]; - t[0] = nonce; - t[1] = nonce >> 8; - - shake256_init(state); - shake256_absorb(state, seed, CRHBYTES); - shake256_absorb(state, t, 2); - shake256_finalize(state); -} diff --git a/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric.h b/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric.h deleted file mode 100644 index f8df7fce82..0000000000 --- a/crypto/dilithium/pqcrystals_dilithium_ref_common/symmetric.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef SYMMETRIC_H -#define SYMMETRIC_H - -#include -#include "params.h" - -#include "fips202.h" - -typedef keccak_state stream128_state; -typedef keccak_state stream256_state; - -void dilithium_shake128_stream_init(keccak_state *state, - const uint8_t seed[SEEDBYTES], - uint16_t nonce); - - -void dilithium_shake256_stream_init(keccak_state *state, - const uint8_t seed[CRHBYTES], - uint16_t nonce); - -#define STREAM128_BLOCKBYTES SHAKE128_RATE -#define STREAM256_BLOCKBYTES SHAKE256_RATE - -#define stream128_init(STATE, SEED, NONCE) \ -dilithium_shake128_stream_init(STATE, SEED, NONCE) -#define stream128_squeezeblocks(OUT, OUTBLOCKS, STATE) \ -shake128_squeezeblocks(OUT, OUTBLOCKS, STATE) -#define stream256_init(STATE, SEED, NONCE) \ -dilithium_shake256_stream_init(STATE, SEED, NONCE) -#define stream256_squeezeblocks(OUT, OUTBLOCKS, STATE) \ -shake256_squeezeblocks(OUT, OUTBLOCKS, STATE) - -#endif diff --git a/crypto/fipsmodule/sha/internal.h b/crypto/fipsmodule/sha/internal.h index 596371ade9..c796a51c5f 100644 --- a/crypto/fipsmodule/sha/internal.h +++ b/crypto/fipsmodule/sha/internal.h @@ -67,6 +67,7 @@ extern "C" { #define SHAKE128_BLOCKSIZE (KECCAK1600_WIDTH - 128 * 2) / 8 #define SHAKE256_BLOCKSIZE (KECCAK1600_WIDTH - 256 * 2) / 8 #define SHAKE128_RATE 168 +#define SHAKE256_RATE 136 #define XOF_BLOCKBYTES SHAKE128_RATE // SHAKE128 has the maximum block size among the SHA3/SHAKE algorithms.