diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..3d584a65 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +... + diff --git a/Makefile b/Makefile index 3013e4ee..4aedc3e6 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ ifndef SCHEME $(error SCHEME variable is not set) endif +# This -Wall was supported by the European Commission through the ERC Starting Grant 805031 (EPOQUE) CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 functest: $(dir $(SCHEME))test.c $(wildcard $(SCHEME)/clean/*.c) $(wildcard $(SCHEME)/clean/*.h) @@ -21,3 +22,6 @@ functest: $(dir $(SCHEME))test.c $(wildcard $(SCHEME)/clean/*.c) $(wildcard $(SC clean: rm -rf bin + +format: + find . -iname *.h -o -iname *.c | xargs clang-format -i -style=file diff --git a/common/fips202.c b/common/fips202.c index 6dbfc6bb..9cca98ff 100644 --- a/common/fips202.c +++ b/common/fips202.c @@ -1,28 +1,27 @@ /* Based on the public domain implementation in * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html - * by Ronny Van Keer + * 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" +#include +#include #define NROUNDS 24 -#define ROL(a, offset) ((a << offset) ^ (a >> (64-offset))) +#define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset))) /************************************************* -* Name: load64 -* -* Description: Load 8 bytes into uint64_t in little-endian order -* -* Arguments: - const unsigned char *x: pointer to input byte array -* -* Returns the loaded 64-bit unsigned integer -**************************************************/ -static uint64_t load64(const unsigned char *x) -{ + * Name: load64 + * + * Description: Load 8 bytes into uint64_t in little-endian order + * + * Arguments: - const unsigned char *x: pointer to input byte array + * + * Returns the loaded 64-bit unsigned integer + **************************************************/ +static uint64_t load64(const unsigned char *x) { unsigned long long r = 0, i; for (i = 0; i < 8; ++i) { @@ -32,359 +31,341 @@ static uint64_t load64(const unsigned char *x) } /************************************************* -* 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) -{ + * 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) { unsigned int i; - for(i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { x[i] = u; u >>= 8; } } /* Keccak round constants */ -static 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 -}; +static 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 in/output Keccak state -**************************************************/ -void KeccakF1600_StatePermute(uint64_t * state) -{ + * Name: KeccakF1600_StatePermute + * + * Description: The Keccak F1600 Permutation + * + * Arguments: - uint64_t * state: pointer to in/output Keccak state + **************************************************/ +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; - 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; - - #undef 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; + +#undef round } #include #define MIN(a, b) ((a) < (b) ? (a) : (b)) - /************************************************* -* 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 -* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128) -* - const unsigned char *m: pointer to input to be absorbed into s -* - unsigned long long mlen: length of input in bytes -* - unsigned char p: domain-separation byte for different Keccak-derived functions -**************************************************/ -static void keccak_absorb(uint64_t *s, - unsigned int r, - const unsigned char *m, unsigned long long int mlen, - unsigned char p) -{ + * 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 + * - unsigned int r: rate in bytes (e.g., 168 for + *SHAKE128) + * - const unsigned char *m: pointer to input to be absorbed into + *s + * - unsigned long long mlen: length of input in bytes + * - unsigned char p: domain-separation byte for different + *Keccak-derived functions + **************************************************/ +static void keccak_absorb(uint64_t *s, unsigned int r, const unsigned char *m, + unsigned long long int mlen, unsigned char p) { unsigned long long i; unsigned char t[200]; // Zero state for (i = 0; i < 25; ++i) s[i] = 0; - - while (mlen >= r) - { + + while (mlen >= r) { for (i = 0; i < r / 8; ++i) s[i] ^= load64(m + 8 * i); - + KeccakF1600_StatePermute(s); mlen -= r; m += r; @@ -400,71 +381,72 @@ static void keccak_absorb(uint64_t *s, 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: - unsigned char *h: pointer to output blocks -* - unsigned long long int nblocks: number of blocks to be squeezed (written to h) -* - uint64_t *s: pointer to in/output Keccak state -* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128) -**************************************************/ -static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, - uint64_t *s, - unsigned int r) -{ + * 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: - unsigned char *h: pointer to output blocks + * - unsigned long long int nblocks: number of blocks to be + *squeezed (written to h) + * - uint64_t *s: pointer to in/output Keccak + *state + * - unsigned int r: rate in bytes (e.g., 168 for + *SHAKE128) + **************************************************/ +static void keccak_squeezeblocks(unsigned char *h, + unsigned long long int nblocks, uint64_t *s, + unsigned int r) { unsigned int i; - while(nblocks > 0) - { + while (nblocks > 0) { KeccakF1600_StatePermute(s); - for(i=0;i<(r>>3);i++) - { - store64(h+8*i, s[i]); + for (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 unsigned char *input: pointer to input to be absorbed into s -* - unsigned long long inputByteLen: length of input in bytes -**************************************************/ -void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) -{ + * 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 unsigned char *input: pointer to input to be + *absorbed into s + * - unsigned long long inputByteLen: length of input in bytes + **************************************************/ +void shake128_absorb(uint64_t *s, const unsigned char *input, + unsigned int inputByteLen) { keccak_absorb(s, SHAKE128_RATE, input, inputByteLen, 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: - unsigned char *output: pointer to output blocks -* - unsigned long long nblocks: number of blocks to be squeezed (written to output) -* - uint64_t *s: pointer to in/output Keccak state -**************************************************/ -void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) -{ + * 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: - unsigned char *output: pointer to output blocks + * - unsigned long long nblocks: number of blocks to be squeezed + *(written to output) + * - uint64_t *s: pointer to in/output Keccak state + **************************************************/ +void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, + uint64_t *s) { keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); } /************************************************* * Name: shake256 -* +* * Description: SHAKE256 XOF with non-incremental API * * Arguments: - unsigned char *output: pointer to output @@ -472,12 +454,11 @@ void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, u - const unsigned char *input: pointer to input - unsigned long long inlen: length of input in bytes **************************************************/ -void shake256(unsigned char *output, unsigned long long outlen, - const unsigned char *input, unsigned long long inlen) -{ +void shake256(unsigned char *output, unsigned long long outlen, + const unsigned char *input, unsigned long long inlen) { uint64_t s[25]; unsigned char t[SHAKE256_RATE]; - unsigned long long nblocks = outlen/SHAKE256_RATE; + unsigned long long nblocks = outlen / SHAKE256_RATE; size_t i; /* Absorb input */ @@ -486,28 +467,27 @@ void shake256(unsigned char *output, unsigned long long outlen, /* Squeeze output */ keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE); - output+=nblocks*SHAKE256_RATE; - outlen-=nblocks*SHAKE256_RATE; + output += nblocks * SHAKE256_RATE; + outlen -= nblocks * SHAKE256_RATE; - if(outlen) - { + if (outlen) { keccak_squeezeblocks(t, 1, s, SHAKE256_RATE); - for(i=0;i #include "randombytes.h" +#include -static uint32_t seed[32] = { 3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5 } ; +static uint32_t seed[32] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, + 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5}; static uint32_t in[12]; static uint32_t out[8]; static int32_t outleft = 0; -#define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b)))) -#define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b)); +#define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b)))) +#define MUSH(i, b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x, b)); -static void surf(void) -{ - uint32_t t[12]; uint32_t x; uint32_t sum = 0; - int32_t r; int32_t i; int32_t loop; +static void surf(void) { + uint32_t t[12]; + uint32_t x; + uint32_t sum = 0; + int32_t r; + int32_t i; + int32_t loop; - for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i]; - for (i = 0;i < 8;++i) out[i] = seed[24 + i]; + for (i = 0; i < 12; ++i) + t[i] = in[i] ^ seed[12 + i]; + for (i = 0; i < 8; ++i) + out[i] = seed[24 + i]; x = t[11]; - for (loop = 0;loop < 2;++loop) { - for (r = 0;r < 16;++r) { + for (loop = 0; loop < 2; ++loop) { + for (r = 0; r < 16; ++r) { sum += 0x9e3779b9; - MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13) - MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13) - MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13) + MUSH(0, 5) + MUSH(1, 7) MUSH(2, 9) MUSH(3, 13) MUSH(4, 5) MUSH(5, 7) MUSH(6, 9) + MUSH(7, 13) MUSH(8, 5) MUSH(9, 7) MUSH(10, 9) MUSH(11, 13) } - for (i = 0;i < 8;++i) out[i] ^= t[i + 4]; + for (i = 0; i < 8; ++i) + out[i] ^= t[i + 4]; } } -void randombytes(uint8_t *x,uint64_t xlen) -{ +void randombytes(uint8_t *x, uint64_t xlen) { while (xlen > 0) { if (!outleft) { - if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; + if (!++in[0]) + if (!++in[1]) + if (!++in[2]) + ++in[3]; surf(); outleft = 8; } diff --git a/common/randombytes.h b/common/randombytes.h index e79726c2..da3d394e 100644 --- a/common/randombytes.h +++ b/common/randombytes.h @@ -2,6 +2,6 @@ #ifndef RANDOMBYTES_H #define RANDOMBYTES_H -void randombytes(uint8_t *x,uint64_t xlen); +void randombytes(uint8_t *x, uint64_t xlen); #endif diff --git a/common/sha2.c b/common/sha2.c index c6bae790..9e2d5d36 100644 --- a/common/sha2.c +++ b/common/sha2.c @@ -6,76 +6,76 @@ typedef unsigned long long uint64; -static uint64 load_bigendian(const unsigned char *x) -{ - return - (uint64) (x[7]) \ - | (((uint64) (x[6])) << 8) \ - | (((uint64) (x[5])) << 16) \ - | (((uint64) (x[4])) << 24) \ - | (((uint64) (x[3])) << 32) \ - | (((uint64) (x[2])) << 40) \ - | (((uint64) (x[1])) << 48) \ - | (((uint64) (x[0])) << 56) - ; +static uint64 load_bigendian(const unsigned char *x) { + return (uint64)(x[7]) | (((uint64)(x[6])) << 8) | (((uint64)(x[5])) << 16) | + (((uint64)(x[4])) << 24) | (((uint64)(x[3])) << 32) | + (((uint64)(x[2])) << 40) | (((uint64)(x[1])) << 48) | + (((uint64)(x[0])) << 56); } -static void store_bigendian(unsigned char *x,uint64 u) -{ - x[7] = u; u >>= 8; - x[6] = u; u >>= 8; - x[5] = u; u >>= 8; - x[4] = u; u >>= 8; - x[3] = u; u >>= 8; - x[2] = u; u >>= 8; - x[1] = u; u >>= 8; +static void store_bigendian(unsigned char *x, uint64 u) { + x[7] = u; + u >>= 8; + x[6] = u; + u >>= 8; + x[5] = u; + u >>= 8; + x[4] = u; + u >>= 8; + x[3] = u; + u >>= 8; + x[2] = u; + u >>= 8; + x[1] = u; + u >>= 8; x[0] = u; } -#define SHR(x,c) ((x) >> (c)) -#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) - -#define Ch(x,y,z) ((x & y) ^ (~x & z)) -#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) -#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) -#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) -#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) - -#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; - -#define EXPAND \ - M(w0 ,w14,w9 ,w1 ) \ - M(w1 ,w15,w10,w2 ) \ - M(w2 ,w0 ,w11,w3 ) \ - M(w3 ,w1 ,w12,w4 ) \ - M(w4 ,w2 ,w13,w5 ) \ - M(w5 ,w3 ,w14,w6 ) \ - M(w6 ,w4 ,w15,w7 ) \ - M(w7 ,w5 ,w0 ,w8 ) \ - M(w8 ,w6 ,w1 ,w9 ) \ - M(w9 ,w7 ,w2 ,w10) \ - M(w10,w8 ,w3 ,w11) \ - M(w11,w9 ,w4 ,w12) \ - M(w12,w10,w5 ,w13) \ - M(w13,w11,w6 ,w14) \ - M(w14,w12,w7 ,w15) \ - M(w15,w13,w8 ,w0 ) - -#define F(w,k) \ - T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ - T2 = Sigma0(a) + Maj(a,b,c); \ - h = g; \ - g = f; \ - f = e; \ - e = d + T1; \ - d = c; \ - c = b; \ - b = a; \ +#define SHR(x, c) ((x) >> (c)) +#define ROTR(x, c) (((x) >> (c)) | ((x) << (64 - (c)))) + +#define Ch(x, y, z) ((x & y) ^ (~x & z)) +#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) +#define Sigma0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) +#define Sigma1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) +#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define sigma1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) + +#define M(w0, w14, w9, w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; + +#define EXPAND \ + M(w0, w14, w9, w1) \ + M(w1, w15, w10, w2) \ + M(w2, w0, w11, w3) \ + M(w3, w1, w12, w4) \ + M(w4, w2, w13, w5) \ + M(w5, w3, w14, w6) \ + M(w6, w4, w15, w7) \ + M(w7, w5, w0, w8) \ + M(w8, w6, w1, w9) \ + M(w9, w7, w2, w10) \ + M(w10, w8, w3, w11) \ + M(w11, w9, w4, w12) \ + M(w12, w10, w5, w13) \ + M(w13, w11, w6, w14) \ + M(w14, w12, w7, w15) \ + M(w15, w13, w8, w0) + +#define F(w, k) \ + T1 = h + Sigma1(e) + Ch(e, f, g) + k + w; \ + T2 = Sigma0(a) + Maj(a, b, c); \ + h = g; \ + g = f; \ + f = e; \ + e = d + T1; \ + d = c; \ + c = b; \ + b = a; \ a = T1 + T2; -static int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) -{ +static int crypto_hashblocks_sha512(unsigned char *statebytes, + const unsigned char *in, + unsigned long long inlen) { uint64 state[8]; uint64 a; uint64 b; @@ -88,125 +88,133 @@ static int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned cha uint64 T1; uint64 T2; - a = load_bigendian(statebytes + 0); state[0] = a; - b = load_bigendian(statebytes + 8); state[1] = b; - c = load_bigendian(statebytes + 16); state[2] = c; - d = load_bigendian(statebytes + 24); state[3] = d; - e = load_bigendian(statebytes + 32); state[4] = e; - f = load_bigendian(statebytes + 40); state[5] = f; - g = load_bigendian(statebytes + 48); state[6] = g; - h = load_bigendian(statebytes + 56); state[7] = h; + a = load_bigendian(statebytes + 0); + state[0] = a; + b = load_bigendian(statebytes + 8); + state[1] = b; + c = load_bigendian(statebytes + 16); + state[2] = c; + d = load_bigendian(statebytes + 24); + state[3] = d; + e = load_bigendian(statebytes + 32); + state[4] = e; + f = load_bigendian(statebytes + 40); + state[5] = f; + g = load_bigendian(statebytes + 48); + state[6] = g; + h = load_bigendian(statebytes + 56); + state[7] = h; while (inlen >= 128) { - uint64 w0 = load_bigendian(in + 0); - uint64 w1 = load_bigendian(in + 8); - uint64 w2 = load_bigendian(in + 16); - uint64 w3 = load_bigendian(in + 24); - uint64 w4 = load_bigendian(in + 32); - uint64 w5 = load_bigendian(in + 40); - uint64 w6 = load_bigendian(in + 48); - uint64 w7 = load_bigendian(in + 56); - uint64 w8 = load_bigendian(in + 64); - uint64 w9 = load_bigendian(in + 72); - uint64 w10 = load_bigendian(in + 80); - uint64 w11 = load_bigendian(in + 88); - uint64 w12 = load_bigendian(in + 96); + uint64 w0 = load_bigendian(in + 0); + uint64 w1 = load_bigendian(in + 8); + uint64 w2 = load_bigendian(in + 16); + uint64 w3 = load_bigendian(in + 24); + uint64 w4 = load_bigendian(in + 32); + uint64 w5 = load_bigendian(in + 40); + uint64 w6 = load_bigendian(in + 48); + uint64 w7 = load_bigendian(in + 56); + uint64 w8 = load_bigendian(in + 64); + uint64 w9 = load_bigendian(in + 72); + uint64 w10 = load_bigendian(in + 80); + uint64 w11 = load_bigendian(in + 88); + uint64 w12 = load_bigendian(in + 96); uint64 w13 = load_bigendian(in + 104); uint64 w14 = load_bigendian(in + 112); uint64 w15 = load_bigendian(in + 120); - F(w0 ,0x428a2f98d728ae22ULL) - F(w1 ,0x7137449123ef65cdULL) - F(w2 ,0xb5c0fbcfec4d3b2fULL) - F(w3 ,0xe9b5dba58189dbbcULL) - F(w4 ,0x3956c25bf348b538ULL) - F(w5 ,0x59f111f1b605d019ULL) - F(w6 ,0x923f82a4af194f9bULL) - F(w7 ,0xab1c5ed5da6d8118ULL) - F(w8 ,0xd807aa98a3030242ULL) - F(w9 ,0x12835b0145706fbeULL) - F(w10,0x243185be4ee4b28cULL) - F(w11,0x550c7dc3d5ffb4e2ULL) - F(w12,0x72be5d74f27b896fULL) - F(w13,0x80deb1fe3b1696b1ULL) - F(w14,0x9bdc06a725c71235ULL) - F(w15,0xc19bf174cf692694ULL) + F(w0, 0x428a2f98d728ae22ULL) + F(w1, 0x7137449123ef65cdULL) + F(w2, 0xb5c0fbcfec4d3b2fULL) + F(w3, 0xe9b5dba58189dbbcULL) + F(w4, 0x3956c25bf348b538ULL) + F(w5, 0x59f111f1b605d019ULL) + F(w6, 0x923f82a4af194f9bULL) + F(w7, 0xab1c5ed5da6d8118ULL) + F(w8, 0xd807aa98a3030242ULL) + F(w9, 0x12835b0145706fbeULL) + F(w10, 0x243185be4ee4b28cULL) + F(w11, 0x550c7dc3d5ffb4e2ULL) + F(w12, 0x72be5d74f27b896fULL) + F(w13, 0x80deb1fe3b1696b1ULL) + F(w14, 0x9bdc06a725c71235ULL) + F(w15, 0xc19bf174cf692694ULL) EXPAND - F(w0 ,0xe49b69c19ef14ad2ULL) - F(w1 ,0xefbe4786384f25e3ULL) - F(w2 ,0x0fc19dc68b8cd5b5ULL) - F(w3 ,0x240ca1cc77ac9c65ULL) - F(w4 ,0x2de92c6f592b0275ULL) - F(w5 ,0x4a7484aa6ea6e483ULL) - F(w6 ,0x5cb0a9dcbd41fbd4ULL) - F(w7 ,0x76f988da831153b5ULL) - F(w8 ,0x983e5152ee66dfabULL) - F(w9 ,0xa831c66d2db43210ULL) - F(w10,0xb00327c898fb213fULL) - F(w11,0xbf597fc7beef0ee4ULL) - F(w12,0xc6e00bf33da88fc2ULL) - F(w13,0xd5a79147930aa725ULL) - F(w14,0x06ca6351e003826fULL) - F(w15,0x142929670a0e6e70ULL) + F(w0, 0xe49b69c19ef14ad2ULL) + F(w1, 0xefbe4786384f25e3ULL) + F(w2, 0x0fc19dc68b8cd5b5ULL) + F(w3, 0x240ca1cc77ac9c65ULL) + F(w4, 0x2de92c6f592b0275ULL) + F(w5, 0x4a7484aa6ea6e483ULL) + F(w6, 0x5cb0a9dcbd41fbd4ULL) + F(w7, 0x76f988da831153b5ULL) + F(w8, 0x983e5152ee66dfabULL) + F(w9, 0xa831c66d2db43210ULL) + F(w10, 0xb00327c898fb213fULL) + F(w11, 0xbf597fc7beef0ee4ULL) + F(w12, 0xc6e00bf33da88fc2ULL) + F(w13, 0xd5a79147930aa725ULL) + F(w14, 0x06ca6351e003826fULL) + F(w15, 0x142929670a0e6e70ULL) EXPAND - F(w0 ,0x27b70a8546d22ffcULL) - F(w1 ,0x2e1b21385c26c926ULL) - F(w2 ,0x4d2c6dfc5ac42aedULL) - F(w3 ,0x53380d139d95b3dfULL) - F(w4 ,0x650a73548baf63deULL) - F(w5 ,0x766a0abb3c77b2a8ULL) - F(w6 ,0x81c2c92e47edaee6ULL) - F(w7 ,0x92722c851482353bULL) - F(w8 ,0xa2bfe8a14cf10364ULL) - F(w9 ,0xa81a664bbc423001ULL) - F(w10,0xc24b8b70d0f89791ULL) - F(w11,0xc76c51a30654be30ULL) - F(w12,0xd192e819d6ef5218ULL) - F(w13,0xd69906245565a910ULL) - F(w14,0xf40e35855771202aULL) - F(w15,0x106aa07032bbd1b8ULL) + F(w0, 0x27b70a8546d22ffcULL) + F(w1, 0x2e1b21385c26c926ULL) + F(w2, 0x4d2c6dfc5ac42aedULL) + F(w3, 0x53380d139d95b3dfULL) + F(w4, 0x650a73548baf63deULL) + F(w5, 0x766a0abb3c77b2a8ULL) + F(w6, 0x81c2c92e47edaee6ULL) + F(w7, 0x92722c851482353bULL) + F(w8, 0xa2bfe8a14cf10364ULL) + F(w9, 0xa81a664bbc423001ULL) + F(w10, 0xc24b8b70d0f89791ULL) + F(w11, 0xc76c51a30654be30ULL) + F(w12, 0xd192e819d6ef5218ULL) + F(w13, 0xd69906245565a910ULL) + F(w14, 0xf40e35855771202aULL) + F(w15, 0x106aa07032bbd1b8ULL) EXPAND - F(w0 ,0x19a4c116b8d2d0c8ULL) - F(w1 ,0x1e376c085141ab53ULL) - F(w2 ,0x2748774cdf8eeb99ULL) - F(w3 ,0x34b0bcb5e19b48a8ULL) - F(w4 ,0x391c0cb3c5c95a63ULL) - F(w5 ,0x4ed8aa4ae3418acbULL) - F(w6 ,0x5b9cca4f7763e373ULL) - F(w7 ,0x682e6ff3d6b2b8a3ULL) - F(w8 ,0x748f82ee5defb2fcULL) - F(w9 ,0x78a5636f43172f60ULL) - F(w10,0x84c87814a1f0ab72ULL) - F(w11,0x8cc702081a6439ecULL) - F(w12,0x90befffa23631e28ULL) - F(w13,0xa4506cebde82bde9ULL) - F(w14,0xbef9a3f7b2c67915ULL) - F(w15,0xc67178f2e372532bULL) + F(w0, 0x19a4c116b8d2d0c8ULL) + F(w1, 0x1e376c085141ab53ULL) + F(w2, 0x2748774cdf8eeb99ULL) + F(w3, 0x34b0bcb5e19b48a8ULL) + F(w4, 0x391c0cb3c5c95a63ULL) + F(w5, 0x4ed8aa4ae3418acbULL) + F(w6, 0x5b9cca4f7763e373ULL) + F(w7, 0x682e6ff3d6b2b8a3ULL) + F(w8, 0x748f82ee5defb2fcULL) + F(w9, 0x78a5636f43172f60ULL) + F(w10, 0x84c87814a1f0ab72ULL) + F(w11, 0x8cc702081a6439ecULL) + F(w12, 0x90befffa23631e28ULL) + F(w13, 0xa4506cebde82bde9ULL) + F(w14, 0xbef9a3f7b2c67915ULL) + F(w15, 0xc67178f2e372532bULL) EXPAND - F(w0 ,0xca273eceea26619cULL) - F(w1 ,0xd186b8c721c0c207ULL) - F(w2 ,0xeada7dd6cde0eb1eULL) - F(w3 ,0xf57d4f7fee6ed178ULL) - F(w4 ,0x06f067aa72176fbaULL) - F(w5 ,0x0a637dc5a2c898a6ULL) - F(w6 ,0x113f9804bef90daeULL) - F(w7 ,0x1b710b35131c471bULL) - F(w8 ,0x28db77f523047d84ULL) - F(w9 ,0x32caab7b40c72493ULL) - F(w10,0x3c9ebe0a15c9bebcULL) - F(w11,0x431d67c49c100d4cULL) - F(w12,0x4cc5d4becb3e42b6ULL) - F(w13,0x597f299cfc657e2aULL) - F(w14,0x5fcb6fab3ad6faecULL) - F(w15,0x6c44198c4a475817ULL) + F(w0, 0xca273eceea26619cULL) + F(w1, 0xd186b8c721c0c207ULL) + F(w2, 0xeada7dd6cde0eb1eULL) + F(w3, 0xf57d4f7fee6ed178ULL) + F(w4, 0x06f067aa72176fbaULL) + F(w5, 0x0a637dc5a2c898a6ULL) + F(w6, 0x113f9804bef90daeULL) + F(w7, 0x1b710b35131c471bULL) + F(w8, 0x28db77f523047d84ULL) + F(w9, 0x32caab7b40c72493ULL) + F(w10, 0x3c9ebe0a15c9bebcULL) + F(w11, 0x431d67c49c100d4cULL) + F(w12, 0x4cc5d4becb3e42b6ULL) + F(w13, 0x597f299cfc657e2aULL) + F(w14, 0x5fcb6fab3ad6faecULL) + F(w15, 0x6c44198c4a475817ULL) a += state[0]; b += state[1]; @@ -230,14 +238,14 @@ static int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned cha inlen -= 128; } - store_bigendian(statebytes + 0,state[0]); - store_bigendian(statebytes + 8,state[1]); - store_bigendian(statebytes + 16,state[2]); - store_bigendian(statebytes + 24,state[3]); - store_bigendian(statebytes + 32,state[4]); - store_bigendian(statebytes + 40,state[5]); - store_bigendian(statebytes + 48,state[6]); - store_bigendian(statebytes + 56,state[7]); + store_bigendian(statebytes + 0, state[0]); + store_bigendian(statebytes + 8, state[1]); + store_bigendian(statebytes + 16, state[2]); + store_bigendian(statebytes + 24, state[3]); + store_bigendian(statebytes + 32, state[4]); + store_bigendian(statebytes + 40, state[5]); + store_bigendian(statebytes + 48, state[6]); + store_bigendian(statebytes + 56, state[7]); return inlen; } @@ -245,46 +253,43 @@ static int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned cha #define blocks crypto_hashblocks_sha512 static const unsigned char iv_384[64] = { - 0xcb,0xbb,0x9d,0x5d,0xc1,0x05,0x9e,0xd8, - 0x62,0x9a,0x29,0x2a,0x36,0x7c,0xd5,0x07, - 0x91,0x59,0x01,0x5a,0x30,0x70,0xdd,0x17, - 0x15,0x2f,0xec,0xd8,0xf7,0x0e,0x59,0x39, - 0x67,0x33,0x26,0x67,0xff,0xc0,0x0b,0x31, - 0x8e,0xb4,0x4a,0x87,0x68,0x58,0x15,0x11, - 0xdb,0x0c,0x2e,0x0d,0x64,0xf9,0x8f,0xa7, - 0x47,0xb5,0x48,0x1d,0xbe,0xfa,0x4f,0xa4 -}; + 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29, + 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, + 0xdd, 0x17, 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, + 0x33, 0x26, 0x67, 0xff, 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, + 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c, 0x2e, 0x0d, 0x64, 0xf9, 0x8f, + 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4}; static const unsigned char iv_512[64] = { - 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, - 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, - 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, - 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, - 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, - 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, - 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, - 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 -}; - -int sha384(unsigned char *out, const unsigned char *in, unsigned long long inlen) -{ + 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae, + 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, + 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, + 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, + 0x2b, 0x3e, 0x6c, 0x1f, 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, + 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79}; + +int sha384(unsigned char *out, const unsigned char *in, + unsigned long long inlen) { unsigned char h[64]; unsigned char padded[256]; unsigned int i; unsigned long long bytes = inlen; - for (i = 0;i < 64;++i) h[i] = iv_384[i]; + for (i = 0; i < 64; ++i) + h[i] = iv_384[i]; - blocks(h,in,inlen); + blocks(h, in, inlen); in += inlen; inlen &= 127; in -= inlen; - for (i = 0;i < inlen;++i) padded[i] = in[i]; + for (i = 0; i < inlen; ++i) + padded[i] = in[i]; padded[inlen] = 0x80; if (inlen < 112) { - for (i = inlen + 1;i < 119;++i) padded[i] = 0; + for (i = inlen + 1; i < 119; ++i) + padded[i] = 0; padded[119] = bytes >> 61; padded[120] = bytes >> 53; padded[121] = bytes >> 45; @@ -294,9 +299,10 @@ int sha384(unsigned char *out, const unsigned char *in, unsigned long long inlen padded[125] = bytes >> 13; padded[126] = bytes >> 5; padded[127] = bytes << 3; - blocks(h,padded,128); + blocks(h, padded, 128); } else { - for (i = inlen + 1;i < 247;++i) padded[i] = 0; + for (i = inlen + 1; i < 247; ++i) + padded[i] = 0; padded[247] = bytes >> 61; padded[248] = bytes >> 53; padded[249] = bytes >> 45; @@ -306,33 +312,37 @@ int sha384(unsigned char *out, const unsigned char *in, unsigned long long inlen padded[253] = bytes >> 13; padded[254] = bytes >> 5; padded[255] = bytes << 3; - blocks(h,padded,256); + blocks(h, padded, 256); } - for (i = 0;i < 48;++i) out[i] = h[i]; + for (i = 0; i < 48; ++i) + out[i] = h[i]; return 0; } -int sha512(unsigned char *out, const unsigned char *in, unsigned long long inlen) -{ +int sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) { unsigned char h[64]; unsigned char padded[256]; unsigned int i; unsigned long long bytes = inlen; - for (i = 0;i < 64;++i) h[i] = iv_512[i]; + for (i = 0; i < 64; ++i) + h[i] = iv_512[i]; - blocks(h,in,inlen); + blocks(h, in, inlen); in += inlen; inlen &= 127; in -= inlen; - for (i = 0;i < inlen;++i) padded[i] = in[i]; + for (i = 0; i < inlen; ++i) + padded[i] = in[i]; padded[inlen] = 0x80; if (inlen < 112) { - for (i = inlen + 1;i < 119;++i) padded[i] = 0; + for (i = inlen + 1; i < 119; ++i) + padded[i] = 0; padded[119] = bytes >> 61; padded[120] = bytes >> 53; padded[121] = bytes >> 45; @@ -342,9 +352,10 @@ int sha512(unsigned char *out, const unsigned char *in, unsigned long long inlen padded[125] = bytes >> 13; padded[126] = bytes >> 5; padded[127] = bytes << 3; - blocks(h,padded,128); + blocks(h, padded, 128); } else { - for (i = inlen + 1;i < 247;++i) padded[i] = 0; + for (i = inlen + 1; i < 247; ++i) + padded[i] = 0; padded[247] = bytes >> 61; padded[248] = bytes >> 53; padded[249] = bytes >> 45; @@ -354,10 +365,11 @@ int sha512(unsigned char *out, const unsigned char *in, unsigned long long inlen padded[253] = bytes >> 13; padded[254] = bytes >> 5; padded[255] = bytes << 3; - blocks(h,padded,256); + blocks(h, padded, 256); } - for (i = 0;i < 64;++i) out[i] = h[i]; + for (i = 0; i < 64; ++i) + out[i] = h[i]; return 0; } diff --git a/common/sha2.h b/common/sha2.h index 7959e61a..b47927ef 100644 --- a/common/sha2.h +++ b/common/sha2.h @@ -1,9 +1,9 @@ #ifndef SHA2_H #define SHA2_H -int sha384(unsigned char *output, const unsigned char *input, unsigned long long inlen); -int sha512(unsigned char *output, const unsigned char *input, unsigned long long inlen); +int sha384(unsigned char *output, const unsigned char *input, + unsigned long long inlen); +int sha512(unsigned char *output, const unsigned char *input, + unsigned long long inlen); #endif - - diff --git a/crypto_kem/kyber768/clean/api.h b/crypto_kem/kyber768/clean/api.h index aaaa649b..cf6617f7 100644 --- a/crypto_kem/kyber768/clean/api.h +++ b/crypto_kem/kyber768/clean/api.h @@ -3,17 +3,19 @@ #include "params.h" -#define CRYPTO_SECRETKEYBYTES KYBER_SECRETKEYBYTES -#define CRYPTO_PUBLICKEYBYTES KYBER_PUBLICKEYBYTES +#define CRYPTO_SECRETKEYBYTES KYBER_SECRETKEYBYTES +#define CRYPTO_PUBLICKEYBYTES KYBER_PUBLICKEYBYTES #define CRYPTO_CIPHERTEXTBYTES KYBER_CIPHERTEXTBYTES -#define CRYPTO_BYTES KYBER_SYMBYTES +#define CRYPTO_BYTES KYBER_SYMBYTES #define CRYPTO_ALGNAME "Kyber768" int crypto_kem_keypair(unsigned char *pk, unsigned char *sk); -int crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk); +int crypto_kem_enc(unsigned char *ct, unsigned char *ss, + const unsigned char *pk); -int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk); +int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, + const unsigned char *sk); #endif diff --git a/crypto_kem/kyber768/clean/cbd.c b/crypto_kem/kyber768/clean/cbd.c index d445e340..1a99bfd1 100644 --- a/crypto_kem/kyber768/clean/cbd.c +++ b/crypto_kem/kyber768/clean/cbd.c @@ -1,100 +1,96 @@ #include "cbd.h" /************************************************* -* Name: load_littleendian -* -* Description: load bytes into a 64-bit integer -* in little-endian order -* -* Arguments: - const unsigned char *x: pointer to input byte array -* - bytes: number of bytes to load, has to be <= 8 -* -* Returns 64-bit unsigned integer loaded from x -**************************************************/ -static uint64_t load_littleendian(const unsigned char *x, int bytes) -{ + * Name: load_littleendian + * + * Description: load bytes into a 64-bit integer + * in little-endian order + * + * Arguments: - const unsigned char *x: pointer to input byte array + * - bytes: number of bytes to load, has to be <= + *8 + * + * Returns 64-bit unsigned integer loaded from x + **************************************************/ +static uint64_t load_littleendian(const unsigned char *x, int bytes) { int i; uint64_t r = x[0]; - for(i=1;i> j) & 0x249249; - a[0] = d & 0x7; - b[0] = (d >> 3) & 0x7; - a[1] = (d >> 6) & 0x7; - b[1] = (d >> 9) & 0x7; + a[0] = d & 0x7; + b[0] = (d >> 3) & 0x7; + a[1] = (d >> 6) & 0x7; + b[1] = (d >> 9) & 0x7; a[2] = (d >> 12) & 0x7; b[2] = (d >> 15) & 0x7; a[3] = (d >> 18) & 0x7; b[3] = (d >> 21); - r->coeffs[4*i+0] = a[0] + KYBER_Q - b[0]; - r->coeffs[4*i+1] = a[1] + KYBER_Q - b[1]; - r->coeffs[4*i+2] = a[2] + KYBER_Q - b[2]; - r->coeffs[4*i+3] = a[3] + KYBER_Q - b[3]; + r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0]; + r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1]; + r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2]; + r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3]; } #elif KYBER_ETA == 4 - uint32_t t,d, a[4], b[4]; - int i,j; + uint32_t t, d, a[4], b[4]; + int i, j; - for(i=0;i> j) & 0x11111111; - a[0] = d & 0xf; - b[0] = (d >> 4) & 0xf; - a[1] = (d >> 8) & 0xf; + a[0] = d & 0xf; + b[0] = (d >> 4) & 0xf; + a[1] = (d >> 8) & 0xf; b[1] = (d >> 12) & 0xf; a[2] = (d >> 16) & 0xf; b[2] = (d >> 20) & 0xf; a[3] = (d >> 24) & 0xf; b[3] = (d >> 28); - r->coeffs[4*i+0] = a[0] + KYBER_Q - b[0]; - r->coeffs[4*i+1] = a[1] + KYBER_Q - b[1]; - r->coeffs[4*i+2] = a[2] + KYBER_Q - b[2]; - r->coeffs[4*i+3] = a[3] + KYBER_Q - b[3]; + r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0]; + r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1]; + r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2]; + r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3]; } #elif KYBER_ETA == 5 - uint64_t t,d, a[4], b[4]; - int i,j; + uint64_t t, d, a[4], b[4]; + int i, j; - for(i=0;i> j) & 0x0842108421UL; - a[0] = d & 0x1f; - b[0] = (d >> 5) & 0x1f; + a[0] = d & 0x1f; + b[0] = (d >> 5) & 0x1f; a[1] = (d >> 10) & 0x1f; b[1] = (d >> 15) & 0x1f; a[2] = (d >> 20) & 0x1f; @@ -102,10 +98,10 @@ void cbd(poly *r, const unsigned char *buf) a[3] = (d >> 30) & 0x1f; b[3] = (d >> 35); - r->coeffs[4*i+0] = a[0] + KYBER_Q - b[0]; - r->coeffs[4*i+1] = a[1] + KYBER_Q - b[1]; - r->coeffs[4*i+2] = a[2] + KYBER_Q - b[2]; - r->coeffs[4*i+3] = a[3] + KYBER_Q - b[3]; + r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0]; + r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1]; + r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2]; + r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3]; } #else #error "poly_getnoise in poly.c only supports eta in {3,4,5}" diff --git a/crypto_kem/kyber768/clean/cbd.h b/crypto_kem/kyber768/clean/cbd.h index e88caae1..45e8b29e 100644 --- a/crypto_kem/kyber768/clean/cbd.h +++ b/crypto_kem/kyber768/clean/cbd.h @@ -1,8 +1,8 @@ #ifndef CBD_H #define CBD_H -#include #include "poly.h" +#include void cbd(poly *r, const unsigned char *buf); diff --git a/crypto_kem/kyber768/clean/indcpa.c b/crypto_kem/kyber768/clean/indcpa.c index 19ba7329..874ac1bc 100644 --- a/crypto_kem/kyber768/clean/indcpa.c +++ b/crypto_kem/kyber768/clean/indcpa.c @@ -1,172 +1,169 @@ -#include #include "indcpa.h" +#include "fips202.h" +#include "ntt.h" #include "poly.h" #include "polyvec.h" #include "randombytes.h" -#include "fips202.h" -#include "ntt.h" +#include /************************************************* -* Name: pack_pk -* -* Description: Serialize the public key as concatenation of the -* compressed and serialized vector of polynomials pk -* and the public seed used to generate the matrix A. -* -* Arguments: unsigned char *r: pointer to the output serialized public key -* const poly *pk: pointer to the input public-key polynomial -* const unsigned char *seed: pointer to the input public seed -**************************************************/ -static void pack_pk(unsigned char *r, const polyvec *pk, const unsigned char *seed) -{ + * Name: pack_pk + * + * Description: Serialize the public key as concatenation of the + * compressed and serialized vector of polynomials pk + * and the public seed used to generate the matrix A. + * + * Arguments: unsigned char *r: pointer to the output serialized + *public key const poly *pk: pointer to the input public-key + *polynomial const unsigned char *seed: pointer to the input public seed + **************************************************/ +static void pack_pk(unsigned char *r, const polyvec *pk, + const unsigned char *seed) { int i; polyvec_compress(r, pk); - for(i=0;i SHAKE128_RATE*nblocks-2) - { + if (pos > SHAKE128_RATE * nblocks - 2) { nblocks = 1; - shake128_squeezeblocks(buf,nblocks,state); + shake128_squeezeblocks(buf, nblocks, state); pos = 0; } } @@ -174,74 +171,72 @@ void gen_matrix(polyvec *a, const unsigned char *seed, int transposed) // Not st } } - /************************************************* -* Name: indcpa_keypair -* -* Description: Generates public and private key for the CPA-secure -* public-key encryption scheme underlying Kyber -* -* Arguments: - unsigned char *pk: pointer to output public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) -* - unsigned char *sk: pointer to output private key (of length KYBER_INDCPA_SECRETKEYBYTES bytes) -**************************************************/ -void indcpa_keypair(unsigned char *pk, - unsigned char *sk) -{ + * Name: indcpa_keypair + * + * Description: Generates public and private key for the CPA-secure + * public-key encryption scheme underlying Kyber + * + * Arguments: - unsigned char *pk: pointer to output public key (of length + *KYBER_INDCPA_PUBLICKEYBYTES bytes) + * - unsigned char *sk: pointer to output private key (of length + *KYBER_INDCPA_SECRETKEYBYTES bytes) + **************************************************/ +void indcpa_keypair(unsigned char *pk, unsigned char *sk) { polyvec a[KYBER_K], e, pkpv, skpv; - unsigned char buf[KYBER_SYMBYTES+KYBER_SYMBYTES]; + unsigned char buf[KYBER_SYMBYTES + KYBER_SYMBYTES]; unsigned char *publicseed = buf; - unsigned char *noiseseed = buf+KYBER_SYMBYTES; + unsigned char *noiseseed = buf + KYBER_SYMBYTES; int i; - unsigned char nonce=0; + unsigned char nonce = 0; randombytes(buf, KYBER_SYMBYTES); sha3_512(buf, buf, KYBER_SYMBYTES); gen_a(a, publicseed); - for(i=0;i= 0; level--) - { - for(start = 0; start < KYBER_N; start = j + (1<= 0; level--) { + for (start = 0; start < KYBER_N; start = j + (1 << level)) { zeta = zetas[k++]; - for(j = start; j < start + (1< -void ntt(uint16_t* poly); -void invntt(uint16_t* poly); +void ntt(uint16_t *poly); +void invntt(uint16_t *poly); #endif diff --git a/crypto_kem/kyber768/clean/params.h b/crypto_kem/kyber768/clean/params.h index 8758ce29..dfdc7b89 100644 --- a/crypto_kem/kyber768/clean/params.h +++ b/crypto_kem/kyber768/clean/params.h @@ -8,20 +8,24 @@ #define KYBER_ETA 4 -#define KYBER_SYMBYTES 32 /* size in bytes of shared key, hashes, and seeds */ +#define KYBER_SYMBYTES 32 /* size in bytes of shared key, hashes, and seeds */ -#define KYBER_POLYBYTES 416 -#define KYBER_POLYCOMPRESSEDBYTES 96 -#define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES) -#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 352) +#define KYBER_POLYBYTES 416 +#define KYBER_POLYCOMPRESSEDBYTES 96 +#define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES) +#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 352) -#define KYBER_INDCPA_MSGBYTES KYBER_SYMBYTES -#define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_SYMBYTES) +#define KYBER_INDCPA_MSGBYTES KYBER_SYMBYTES +#define KYBER_INDCPA_PUBLICKEYBYTES \ + (KYBER_POLYVECCOMPRESSEDBYTES + 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 +#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/crypto_kem/kyber768/clean/poly.c b/crypto_kem/kyber768/clean/poly.c index 080296cb..d1307796 100644 --- a/crypto_kem/kyber768/clean/poly.c +++ b/crypto_kem/kyber768/clean/poly.c @@ -1,248 +1,238 @@ -#include #include "poly.h" +#include "cbd.h" +#include "fips202.h" #include "ntt.h" #include "polyvec.h" #include "reduce.h" -#include "cbd.h" -#include "fips202.h" +#include /************************************************* -* Name: poly_compress -* -* Description: Compression and subsequent serialization of a polynomial -* -* Arguments: - unsigned char *r: pointer to output byte array -* - const poly *a: pointer to input polynomial -**************************************************/ -void poly_compress(unsigned char *r, const poly *a) -{ + * Name: poly_compress + * + * Description: Compression and subsequent serialization of a polynomial + * + * Arguments: - unsigned char *r: pointer to output byte array + * - const poly *a: pointer to input polynomial + **************************************************/ +void poly_compress(unsigned char *r, const poly *a) { uint32_t t[8]; - unsigned int i,j,k=0; + unsigned int i, j, k = 0; - for(i=0;icoeffs[i+j]) << 3) + KYBER_Q/2)/KYBER_Q) & 7; + for (i = 0; i < KYBER_N; i += 8) { + for (j = 0; j < 8; j++) + t[j] = (((freeze(a->coeffs[i + j]) << 3) + KYBER_Q / 2) / KYBER_Q) & 7; - r[k] = t[0] | (t[1] << 3) | (t[2] << 6); - r[k+1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7); - r[k+2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5); + r[k] = t[0] | (t[1] << 3) | (t[2] << 6); + r[k + 1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7); + r[k + 2] = (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 unsigned char *a: pointer to input byte array -**************************************************/ -void poly_decompress(poly *r, const unsigned char *a) -{ + * 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 unsigned char *a: pointer to input byte array + **************************************************/ +void poly_decompress(poly *r, const unsigned char *a) { unsigned int i; - for(i=0;icoeffs[i+0] = (((a[0] & 7) * KYBER_Q) + 4)>> 3; - r->coeffs[i+1] = ((((a[0] >> 3) & 7) * KYBER_Q)+ 4) >> 3; - r->coeffs[i+2] = ((((a[0] >> 6) | ((a[1] << 2) & 4)) * KYBER_Q) + 4)>> 3; - r->coeffs[i+3] = ((((a[1] >> 1) & 7) * KYBER_Q) + 4)>> 3; - r->coeffs[i+4] = ((((a[1] >> 4) & 7) * KYBER_Q) + 4)>> 3; - r->coeffs[i+5] = ((((a[1] >> 7) | ((a[2] << 1) & 6)) * KYBER_Q) + 4)>> 3; - r->coeffs[i+6] = ((((a[2] >> 2) & 7) * KYBER_Q) + 4)>> 3; - r->coeffs[i+7] = ((((a[2] >> 5)) * KYBER_Q) + 4)>> 3; + for (i = 0; i < KYBER_N; i += 8) { + r->coeffs[i + 0] = (((a[0] & 7) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 1] = ((((a[0] >> 3) & 7) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 2] = ((((a[0] >> 6) | ((a[1] << 2) & 4)) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 3] = ((((a[1] >> 1) & 7) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 4] = ((((a[1] >> 4) & 7) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 5] = ((((a[1] >> 7) | ((a[2] << 1) & 6)) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 6] = ((((a[2] >> 2) & 7) * KYBER_Q) + 4) >> 3; + r->coeffs[i + 7] = ((((a[2] >> 5)) * KYBER_Q) + 4) >> 3; a += 3; } } /************************************************* -* Name: poly_tobytes -* -* Description: Serialization of a polynomial -* -* Arguments: - unsigned char *r: pointer to output byte array -* - const poly *a: pointer to input polynomial -**************************************************/ -void poly_tobytes(unsigned char *r, const poly *a) -{ - int i,j; + * Name: poly_tobytes + * + * Description: Serialization of a polynomial + * + * Arguments: - unsigned char *r: pointer to output byte array + * - const poly *a: pointer to input polynomial + **************************************************/ +void poly_tobytes(unsigned char *r, const poly *a) { + int i, j; uint16_t t[8]; - for(i=0;icoeffs[8*i+j]); - - r[13*i+ 0] = t[0] & 0xff; - r[13*i+ 1] = (t[0] >> 8) | ((t[1] & 0x07) << 5); - r[13*i+ 2] = (t[1] >> 3) & 0xff; - r[13*i+ 3] = (t[1] >> 11) | ((t[2] & 0x3f) << 2); - r[13*i+ 4] = (t[2] >> 6) | ((t[3] & 0x01) << 7); - r[13*i+ 5] = (t[3] >> 1) & 0xff; - r[13*i+ 6] = (t[3] >> 9) | ((t[4] & 0x0f) << 4); - r[13*i+ 7] = (t[4] >> 4) & 0xff; - r[13*i+ 8] = (t[4] >> 12) | ((t[5] & 0x7f) << 1); - r[13*i+ 9] = (t[5] >> 7) | ((t[6] & 0x03) << 6); - r[13*i+10] = (t[6] >> 2) & 0xff; - r[13*i+11] = (t[6] >> 10) | ((t[7] & 0x1f) << 3); - r[13*i+12] = (t[7] >> 5); + for (i = 0; i < KYBER_N / 8; i++) { + for (j = 0; j < 8; j++) + t[j] = freeze(a->coeffs[8 * i + j]); + + r[13 * i + 0] = t[0] & 0xff; + r[13 * i + 1] = (t[0] >> 8) | ((t[1] & 0x07) << 5); + r[13 * i + 2] = (t[1] >> 3) & 0xff; + r[13 * i + 3] = (t[1] >> 11) | ((t[2] & 0x3f) << 2); + r[13 * i + 4] = (t[2] >> 6) | ((t[3] & 0x01) << 7); + r[13 * i + 5] = (t[3] >> 1) & 0xff; + r[13 * i + 6] = (t[3] >> 9) | ((t[4] & 0x0f) << 4); + r[13 * i + 7] = (t[4] >> 4) & 0xff; + r[13 * i + 8] = (t[4] >> 12) | ((t[5] & 0x7f) << 1); + r[13 * i + 9] = (t[5] >> 7) | ((t[6] & 0x03) << 6); + r[13 * i + 10] = (t[6] >> 2) & 0xff; + r[13 * i + 11] = (t[6] >> 10) | ((t[7] & 0x1f) << 3); + r[13 * i + 12] = (t[7] >> 5); } } /************************************************* -* Name: poly_frombytes -* -* Description: De-serialization of a polynomial; -* inverse of poly_tobytes -* -* Arguments: - poly *r: pointer to output polynomial -* - const unsigned char *a: pointer to input byte array -**************************************************/ -void poly_frombytes(poly *r, const unsigned char *a) -{ + * Name: poly_frombytes + * + * Description: De-serialization of a polynomial; + * inverse of poly_tobytes + * + * Arguments: - poly *r: pointer to output polynomial + * - const unsigned char *a: pointer to input byte array + **************************************************/ +void poly_frombytes(poly *r, const unsigned char *a) { int i; - for(i=0;icoeffs[8*i+0] = a[13*i+ 0] | (((uint16_t)a[13*i+ 1] & 0x1f) << 8); - r->coeffs[8*i+1] = (a[13*i+ 1] >> 5) | (((uint16_t)a[13*i+ 2] ) << 3) | (((uint16_t)a[13*i+ 3] & 0x03) << 11); - r->coeffs[8*i+2] = (a[13*i+ 3] >> 2) | (((uint16_t)a[13*i+ 4] & 0x7f) << 6); - r->coeffs[8*i+3] = (a[13*i+ 4] >> 7) | (((uint16_t)a[13*i+ 5] ) << 1) | (((uint16_t)a[13*i+ 6] & 0x0f) << 9); - r->coeffs[8*i+4] = (a[13*i+ 6] >> 4) | (((uint16_t)a[13*i+ 7] ) << 4) | (((uint16_t)a[13*i+ 8] & 0x01) << 12); - r->coeffs[8*i+5] = (a[13*i+ 8] >> 1) | (((uint16_t)a[13*i+ 9] & 0x3f) << 7); - r->coeffs[8*i+6] = (a[13*i+ 9] >> 6) | (((uint16_t)a[13*i+10] ) << 2) | (((uint16_t)a[13*i+11] & 0x07) << 10); - r->coeffs[8*i+7] = (a[13*i+11] >> 3) | (((uint16_t)a[13*i+12] ) << 5); + for (i = 0; i < KYBER_N / 8; i++) { + r->coeffs[8 * i + 0] = + a[13 * i + 0] | (((uint16_t)a[13 * i + 1] & 0x1f) << 8); + r->coeffs[8 * i + 1] = (a[13 * i + 1] >> 5) | + (((uint16_t)a[13 * i + 2]) << 3) | + (((uint16_t)a[13 * i + 3] & 0x03) << 11); + r->coeffs[8 * i + 2] = + (a[13 * i + 3] >> 2) | (((uint16_t)a[13 * i + 4] & 0x7f) << 6); + r->coeffs[8 * i + 3] = (a[13 * i + 4] >> 7) | + (((uint16_t)a[13 * i + 5]) << 1) | + (((uint16_t)a[13 * i + 6] & 0x0f) << 9); + r->coeffs[8 * i + 4] = (a[13 * i + 6] >> 4) | + (((uint16_t)a[13 * i + 7]) << 4) | + (((uint16_t)a[13 * i + 8] & 0x01) << 12); + r->coeffs[8 * i + 5] = + (a[13 * i + 8] >> 1) | (((uint16_t)a[13 * i + 9] & 0x3f) << 7); + r->coeffs[8 * i + 6] = (a[13 * i + 9] >> 6) | + (((uint16_t)a[13 * i + 10]) << 2) | + (((uint16_t)a[13 * i + 11] & 0x07) << 10); + r->coeffs[8 * i + 7] = + (a[13 * i + 11] >> 3) | (((uint16_t)a[13 * i + 12]) << 5); } } /************************************************* -* 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 unsigned char *seed: pointer to input seed -* - unsigned char nonce: one-byte input nonce -**************************************************/ -void poly_getnoise(poly *r,const unsigned char *seed, unsigned char nonce) -{ - unsigned char buf[KYBER_ETA*KYBER_N/4]; - unsigned char extseed[KYBER_SYMBYTES+1]; + * 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 unsigned char *seed: pointer to input seed + * - unsigned char nonce: one-byte input nonce + **************************************************/ +void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce) { + unsigned char buf[KYBER_ETA * KYBER_N / 4]; + unsigned char extseed[KYBER_SYMBYTES + 1]; int i; - for(i=0;icoeffs); -} + * 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 poly_ntt(poly *r) { ntt(r->coeffs); } /************************************************* -* 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 poly_invntt(poly *r) -{ - invntt(r->coeffs); -} - + * 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 poly_invntt(poly *r) { invntt(r->coeffs); } + /************************************************* -* 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 poly_add(poly *r, const poly *a, const poly *b) -{ + * 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 poly_add(poly *r, const poly *a, const poly *b) { int i; - for(i=0;icoeffs[i] = barrett_reduce(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 poly_sub(poly *r, const poly *a, const poly *b) -{ + * 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 poly_sub(poly *r, const poly *a, const poly *b) { int i; - for(i=0;icoeffs[i] = barrett_reduce(a->coeffs[i] + 3*KYBER_Q - b->coeffs[i]); + for (i = 0; i < KYBER_N; i++) + r->coeffs[i] = barrett_reduce(a->coeffs[i] + 3 * KYBER_Q - b->coeffs[i]); } /************************************************* -* Name: poly_frommsg -* -* Description: Convert 32-byte message to polynomial -* -* Arguments: - poly *r: pointer to output polynomial -* - const unsigned char *msg: pointer to input message -**************************************************/ -void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]) -{ - uint16_t i,j,mask; - - for(i=0;i> j)&1); - r->coeffs[8*i+j] = mask & ((KYBER_Q+1)/2); - } + * Name: poly_frommsg + * + * Description: Convert 32-byte message to polynomial + * + * Arguments: - poly *r: pointer to output polynomial + * - const unsigned char *msg: pointer to input message + **************************************************/ +void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]) { + uint16_t i, j, mask; + + for (i = 0; i < KYBER_SYMBYTES; i++) { + for (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: - unsigned char *msg: pointer to output message -* - const poly *a: pointer to input polynomial -**************************************************/ -void poly_tomsg(unsigned char msg[KYBER_SYMBYTES], const poly *a) -{ + * Name: poly_tomsg + * + * Description: Convert polynomial to 32-byte message + * + * Arguments: - unsigned char *msg: pointer to output message + * - const poly *a: pointer to input polynomial + **************************************************/ +void poly_tomsg(unsigned char msg[KYBER_SYMBYTES], const poly *a) { uint16_t t; - int i,j; + int i, j; - for(i=0;icoeffs[8*i+j]) << 1) + KYBER_Q/2)/KYBER_Q) & 1; + for (j = 0; j < 8; j++) { + t = (((freeze(a->coeffs[8 * i + j]) << 1) + KYBER_Q / 2) / KYBER_Q) & 1; msg[i] |= t << j; } } diff --git a/crypto_kem/kyber768/clean/poly.h b/crypto_kem/kyber768/clean/poly.h index a791c680..d5ace7c9 100644 --- a/crypto_kem/kyber768/clean/poly.h +++ b/crypto_kem/kyber768/clean/poly.h @@ -1,14 +1,14 @@ #ifndef POLY_H #define POLY_H -#include #include "params.h" +#include -/* +/* * 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] + * coeffs[0] + X*coeffs[1] + X^2*xoeffs[2] + ... + X^{n-1}*coeffs[n-1] */ -typedef struct{ +typedef struct { uint16_t coeffs[KYBER_N]; } poly; @@ -21,11 +21,11 @@ void poly_frombytes(poly *r, const unsigned char *a); void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]); void poly_tomsg(unsigned char msg[KYBER_SYMBYTES], const poly *r); -void poly_getnoise(poly *r,const unsigned char *seed, unsigned char nonce); +void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce); void poly_ntt(poly *r); void poly_invntt(poly *r); - + void poly_add(poly *r, const poly *a, const poly *b); void poly_sub(poly *r, const poly *a, const poly *b); diff --git a/crypto_kem/kyber768/clean/polyvec.c b/crypto_kem/kyber768/clean/polyvec.c index f61c26fe..c4cca381 100644 --- a/crypto_kem/kyber768/clean/polyvec.c +++ b/crypto_kem/kyber768/clean/polyvec.c @@ -1,152 +1,177 @@ -#include #include "polyvec.h" -#include "fips202.h" #include "cbd.h" +#include "fips202.h" #include "reduce.h" +#include /************************************************* -* Name: polyvec_compress -* -* Description: Compress and serialize vector of polynomials -* -* Arguments: - unsigned char *r: pointer to output byte array -* - const polyvec *a: pointer to input vector of polynomials -**************************************************/ -void polyvec_compress(unsigned char *r, const polyvec *a) -{ - int i,j,k; + * Name: polyvec_compress + * + * Description: Compress and serialize vector of polynomials + * + * Arguments: - unsigned char *r: pointer to output byte array + * - const polyvec *a: pointer to input vector of polynomials + **************************************************/ +void polyvec_compress(unsigned char *r, const polyvec *a) { + int i, j, k; uint16_t t[8]; - for(i=0;ivec[i].coeffs[8*j+k]) << 11) + KYBER_Q/2)/ KYBER_Q) & 0x7ff; + for (i = 0; i < KYBER_K; i++) { + for (j = 0; j < KYBER_N / 8; j++) { + for (k = 0; k < 8; k++) + t[k] = ((((uint32_t)freeze(a->vec[i].coeffs[8 * j + k]) << 11) + + KYBER_Q / 2) / + KYBER_Q) & + 0x7ff; - r[11*j+ 0] = t[0] & 0xff; - r[11*j+ 1] = (t[0] >> 8) | ((t[1] & 0x1f) << 3); - r[11*j+ 2] = (t[1] >> 5) | ((t[2] & 0x03) << 6); - r[11*j+ 3] = (t[2] >> 2) & 0xff; - r[11*j+ 4] = (t[2] >> 10) | ((t[3] & 0x7f) << 1); - r[11*j+ 5] = (t[3] >> 7) | ((t[4] & 0x0f) << 4); - r[11*j+ 6] = (t[4] >> 4) | ((t[5] & 0x01) << 7); - r[11*j+ 7] = (t[5] >> 1) & 0xff; - r[11*j+ 8] = (t[5] >> 9) | ((t[6] & 0x3f) << 2); - r[11*j+ 9] = (t[6] >> 6) | ((t[7] & 0x07) << 5); - r[11*j+10] = (t[7] >> 3); + r[11 * j + 0] = t[0] & 0xff; + r[11 * j + 1] = (t[0] >> 8) | ((t[1] & 0x1f) << 3); + r[11 * j + 2] = (t[1] >> 5) | ((t[2] & 0x03) << 6); + r[11 * j + 3] = (t[2] >> 2) & 0xff; + r[11 * j + 4] = (t[2] >> 10) | ((t[3] & 0x7f) << 1); + r[11 * j + 5] = (t[3] >> 7) | ((t[4] & 0x0f) << 4); + r[11 * j + 6] = (t[4] >> 4) | ((t[5] & 0x01) << 7); + r[11 * j + 7] = (t[5] >> 1) & 0xff; + r[11 * j + 8] = (t[5] >> 9) | ((t[6] & 0x3f) << 2); + r[11 * j + 9] = (t[6] >> 6) | ((t[7] & 0x07) << 5); + r[11 * j + 10] = (t[7] >> 3); } r += 352; } } /************************************************* -* 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 -* - unsigned char *a: pointer to input byte array -**************************************************/ -void polyvec_decompress(polyvec *r, const unsigned char *a) -{ - int i,j; - for(i=0;ivec[i].coeffs[8*j+0] = (((a[11*j+ 0] | (((uint32_t)a[11*j+ 1] & 0x07) << 8)) * KYBER_Q) +1024) >> 11; - r->vec[i].coeffs[8*j+1] = ((((a[11*j+ 1] >> 3) | (((uint32_t)a[11*j+ 2] & 0x3f) << 5)) * KYBER_Q) +1024) >> 11; - r->vec[i].coeffs[8*j+2] = ((((a[11*j+ 2] >> 6) | (((uint32_t)a[11*j+ 3] & 0xff) << 2) | (((uint32_t)a[11*j+ 4] & 0x01) << 10)) * KYBER_Q) + 1024) >> 11; - r->vec[i].coeffs[8*j+3] = ((((a[11*j+ 4] >> 1) | (((uint32_t)a[11*j+ 5] & 0x0f) << 7)) * KYBER_Q) + 1024) >> 11; - r->vec[i].coeffs[8*j+4] = ((((a[11*j+ 5] >> 4) | (((uint32_t)a[11*j+ 6] & 0x7f) << 4)) * KYBER_Q) + 1024) >> 11; - r->vec[i].coeffs[8*j+5] = ((((a[11*j+ 6] >> 7) | (((uint32_t)a[11*j+ 7] & 0xff) << 1) | (((uint32_t)a[11*j+ 8] & 0x03) << 9)) * KYBER_Q) + 1024) >> 11; - r->vec[i].coeffs[8*j+6] = ((((a[11*j+ 8] >> 2) | (((uint32_t)a[11*j+ 9] & 0x1f) << 6)) * KYBER_Q) + 1024) >> 11; - r->vec[i].coeffs[8*j+7] = ((((a[11*j+ 9] >> 5) | (((uint32_t)a[11*j+10] & 0xff) << 3)) * KYBER_Q) + 1024) >> 11; + * 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 + * - unsigned char *a: pointer to input byte array + **************************************************/ +void polyvec_decompress(polyvec *r, const unsigned char *a) { + int i, j; + for (i = 0; i < KYBER_K; i++) { + for (j = 0; j < KYBER_N / 8; j++) { + r->vec[i].coeffs[8 * j + 0] = + (((a[11 * j + 0] | (((uint32_t)a[11 * j + 1] & 0x07) << 8)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 1] = + ((((a[11 * j + 1] >> 3) | (((uint32_t)a[11 * j + 2] & 0x3f) << 5)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 2] = + ((((a[11 * j + 2] >> 6) | (((uint32_t)a[11 * j + 3] & 0xff) << 2) | + (((uint32_t)a[11 * j + 4] & 0x01) << 10)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 3] = + ((((a[11 * j + 4] >> 1) | (((uint32_t)a[11 * j + 5] & 0x0f) << 7)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 4] = + ((((a[11 * j + 5] >> 4) | (((uint32_t)a[11 * j + 6] & 0x7f) << 4)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 5] = + ((((a[11 * j + 6] >> 7) | (((uint32_t)a[11 * j + 7] & 0xff) << 1) | + (((uint32_t)a[11 * j + 8] & 0x03) << 9)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 6] = + ((((a[11 * j + 8] >> 2) | (((uint32_t)a[11 * j + 9] & 0x1f) << 6)) * + KYBER_Q) + + 1024) >> + 11; + r->vec[i].coeffs[8 * j + 7] = + ((((a[11 * j + 9] >> 5) | (((uint32_t)a[11 * j + 10] & 0xff) << 3)) * + KYBER_Q) + + 1024) >> + 11; } a += 352; } } /************************************************* -* Name: polyvec_tobytes -* -* Description: Serialize vector of polynomials -* -* Arguments: - unsigned char *r: pointer to output byte array -* - const polyvec *a: pointer to input vector of polynomials -**************************************************/ -void polyvec_tobytes(unsigned char *r, const polyvec *a) -{ + * Name: polyvec_tobytes + * + * Description: Serialize vector of polynomials + * + * Arguments: - unsigned char *r: pointer to output byte array + * - const polyvec *a: pointer to input vector of polynomials + **************************************************/ +void polyvec_tobytes(unsigned char *r, const polyvec *a) { int i; - for(i=0;ivec[i]); + for (i = 0; i < KYBER_K; i++) + poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]); } /************************************************* -* Name: polyvec_frombytes -* -* Description: De-serialize vector of polynomials; -* inverse of polyvec_tobytes -* -* Arguments: - unsigned char *r: pointer to output byte array -* - const polyvec *a: pointer to input vector of polynomials -**************************************************/ -void polyvec_frombytes(polyvec *r, const unsigned char *a) -{ + * Name: polyvec_frombytes + * + * Description: De-serialize vector of polynomials; + * inverse of polyvec_tobytes + * + * Arguments: - unsigned char *r: pointer to output byte array + * - const polyvec *a: pointer to input vector of polynomials + **************************************************/ +void polyvec_frombytes(polyvec *r, const unsigned char *a) { int i; - for(i=0;ivec[i], a+i*KYBER_POLYBYTES); + for (i = 0; i < KYBER_K; i++) + 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 polyvec_ntt(polyvec *r) -{ + * 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 polyvec_ntt(polyvec *r) { int i; - for(i=0;ivec[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 polyvec_invntt(polyvec *r) -{ + * 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 polyvec_invntt(polyvec *r) { int i; - for(i=0;ivec[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 polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) -{ - int i,j; + * 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 polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) { + int i, j; uint16_t t; - for(j=0;jvec[0].coeffs[j]); // 4613 = 2^{2*18} % q + for (j = 0; j < KYBER_N; j++) { + t = montgomery_reduce(4613 * + (uint32_t)b->vec[0].coeffs[j]); // 4613 = 2^{2*18} % q r->coeffs[j] = montgomery_reduce(a->vec[0].coeffs[j] * t); - for(i=1;ivec[i].coeffs[j]); + for (i = 1; i < KYBER_K; i++) { + t = montgomery_reduce(4613 * (uint32_t)b->vec[i].coeffs[j]); r->coeffs[j] += montgomery_reduce(a->vec[i].coeffs[j] * t); } r->coeffs[j] = barrett_reduce(r->coeffs[j]); @@ -154,18 +179,16 @@ void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) } /************************************************* -* 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 polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) -{ + * 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 polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) { int i; - for(i=0;ivec[i], &a->vec[i], &b->vec[i]); - } diff --git a/crypto_kem/kyber768/clean/polyvec.h b/crypto_kem/kyber768/clean/polyvec.h index ad9fe941..c2adb897 100644 --- a/crypto_kem/kyber768/clean/polyvec.h +++ b/crypto_kem/kyber768/clean/polyvec.h @@ -4,7 +4,7 @@ #include "params.h" #include "poly.h" -typedef struct{ +typedef struct { poly vec[KYBER_K]; } polyvec; @@ -16,7 +16,7 @@ void polyvec_frombytes(polyvec *r, const unsigned char *a); void polyvec_ntt(polyvec *r); void polyvec_invntt(polyvec *r); - + void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b); void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b); diff --git a/crypto_kem/kyber768/clean/precomp.c b/crypto_kem/kyber768/clean/precomp.c index 96edf275..243d5159 100644 --- a/crypto_kem/kyber768/clean/precomp.c +++ b/crypto_kem/kyber768/clean/precomp.c @@ -29,54 +29,69 @@ mont = Mod(2^18,q); g=0; for(i=2,q-1,if(znorder(Mod(i,q)) == 2*n, g=Mod(i,q); break)) zetas = lift(vector(n, i, g^(brv[i])*mont)) -omegas_inv_bitrev_montgomery = lift(vector(n/2, i, (g^2)^(-brv[2*(i-1)+1])*mont)) -psis_inv_montgomery = lift(vector(n, i, g^(-(i-1))/n*mont)) +omegas_inv_bitrev_montgomery = lift(vector(n/2, i, +(g^2)^(-brv[2*(i-1)+1])*mont)) psis_inv_montgomery = lift(vector(n, i, +g^(-(i-1))/n*mont)) */ const uint16_t zetas[KYBER_N] = { - 990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382, 6086, 3823, 877, 5656, - 3583, 7010, 6414, 263, 1285, 291, 7143, 7338, 1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, - 606, 729, 5383, 962, 3240, 7548, 5129, 7653, 5929, 4965, 2461, 641, 1584, 2666, 1142, 157, - 7407, 5222, 5602, 5142, 6140, 5485, 4931, 1559, 2085, 5284, 2056, 3538, 7269, 3535, 7190, 1957, - 3465, 6792, 1538, 4664, 2023, 7643, 3660, 7673, 1694, 6905, 3995, 3475, 5939, 1859, 6910, 4434, - 1019, 1492, 7087, 4761, 657, 4859, 5798, 2640, 1693, 2607, 2782, 5400, 6466, 1010, 957, 3851, - 2121, 6392, 7319, 3367, 3659, 3375, 6430, 7583, 1549, 5856, 4773, 6084, 5544, 1650, 3997, 4390, - 6722, 2915, 4245, 2635, 6128, 7676, 5737, 1616, 3457, 3132, 7196, 4702, 6239, 851, 2122, 3009, - 7613, 7295, 2007, 323, 5112, 3716, 2289, 6442, 6965, 2713, 7126, 3401, 963, 6596, 607, 5027, - 7078, 4484, 5937, 944, 2860, 2680, 5049, 1777, 5850, 3387, 6487, 6777, 4812, 4724, 7077, 186, - 6848, 6793, 3463, 5877, 1174, 7116, 3077, 5945, 6591, 590, 6643, 1337, 6036, 3991, 1675, 2053, - 6055, 1162, 1679, 3883, 4311, 2106, 6163, 4486, 6374, 5006, 4576, 4288, 5180, 4102, 282, 6119, - 7443, 6330, 3184, 4971, 2530, 5325, 4171, 7185, 5175, 5655, 1898, 382, 7211, 43, 5965, 6073, - 1730, 332, 1577, 3304, 2329, 1699, 6150, 2379, 5113, 333, 3502, 4517, 1480, 1172, 5567, 651, - 925, 4573, 599, 1367, 4109, 1863, 6929, 1605, 3866, 2065, 4048, 839, 5764, 2447, 2022, 3345, - 1990, 4067, 2036, 2069, 3567, 7371, 2368, 339, 6947, 2159, 654, 7327, 2768, 6676, 987, 2214}; + 990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382, + 6086, 3823, 877, 5656, 3583, 7010, 6414, 263, 1285, 291, 7143, 7338, + 1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, 606, 729, 5383, 962, + 3240, 7548, 5129, 7653, 5929, 4965, 2461, 641, 1584, 2666, 1142, 157, + 7407, 5222, 5602, 5142, 6140, 5485, 4931, 1559, 2085, 5284, 2056, 3538, + 7269, 3535, 7190, 1957, 3465, 6792, 1538, 4664, 2023, 7643, 3660, 7673, + 1694, 6905, 3995, 3475, 5939, 1859, 6910, 4434, 1019, 1492, 7087, 4761, + 657, 4859, 5798, 2640, 1693, 2607, 2782, 5400, 6466, 1010, 957, 3851, + 2121, 6392, 7319, 3367, 3659, 3375, 6430, 7583, 1549, 5856, 4773, 6084, + 5544, 1650, 3997, 4390, 6722, 2915, 4245, 2635, 6128, 7676, 5737, 1616, + 3457, 3132, 7196, 4702, 6239, 851, 2122, 3009, 7613, 7295, 2007, 323, + 5112, 3716, 2289, 6442, 6965, 2713, 7126, 3401, 963, 6596, 607, 5027, + 7078, 4484, 5937, 944, 2860, 2680, 5049, 1777, 5850, 3387, 6487, 6777, + 4812, 4724, 7077, 186, 6848, 6793, 3463, 5877, 1174, 7116, 3077, 5945, + 6591, 590, 6643, 1337, 6036, 3991, 1675, 2053, 6055, 1162, 1679, 3883, + 4311, 2106, 6163, 4486, 6374, 5006, 4576, 4288, 5180, 4102, 282, 6119, + 7443, 6330, 3184, 4971, 2530, 5325, 4171, 7185, 5175, 5655, 1898, 382, + 7211, 43, 5965, 6073, 1730, 332, 1577, 3304, 2329, 1699, 6150, 2379, + 5113, 333, 3502, 4517, 1480, 1172, 5567, 651, 925, 4573, 599, 1367, + 4109, 1863, 6929, 1605, 3866, 2065, 4048, 839, 5764, 2447, 2022, 3345, + 1990, 4067, 2036, 2069, 3567, 7371, 2368, 339, 6947, 2159, 654, 7327, + 2768, 6676, 987, 2214}; -const uint16_t omegas_inv_bitrev_montgomery[KYBER_N/2] = { - 990, 254, 862, 5047, 6586, 5538, 4400, 7103, 2025, 6804, 3858, 1595, 2299, 4345, 1319, 7197, - 7678, 5213, 1906, 3639, 1749, 2497, 2547, 6100, 343, 538, 7390, 6396, 7418, 1267, 671, 4098, - 5724, 491, 4146, 412, 4143, 5625, 2397, 5596, 6122, 2750, 2196, 1541, 2539, 2079, 2459, 274, - 7524, 6539, 5015, 6097, 7040, 5220, 2716, 1752, 28, 2552, 133, 4441, 6719, 2298, 6952, 7075, - 4672, 5559, 6830, 1442, 2979, 485, 4549, 4224, 6065, 1944, 5, 1553, 5046, 3436, 4766, 959, - 3291, 3684, 6031, 2137, 1597, 2908, 1825, 6132, 98, 1251, 4306, 4022, 4314, 362, 1289, 5560, - 3830, 6724, 6671, 1215, 2281, 4899, 5074, 5988, 5041, 1883, 2822, 7024, 2920, 594, 6189, 6662, - 3247, 771, 5822, 1742, 4206, 3686, 776, 5987, 8, 4021, 38, 5658, 3017, 6143, 889, 4216}; +const uint16_t omegas_inv_bitrev_montgomery[KYBER_N / 2] = { + 990, 254, 862, 5047, 6586, 5538, 4400, 7103, 2025, 6804, 3858, 1595, + 2299, 4345, 1319, 7197, 7678, 5213, 1906, 3639, 1749, 2497, 2547, 6100, + 343, 538, 7390, 6396, 7418, 1267, 671, 4098, 5724, 491, 4146, 412, + 4143, 5625, 2397, 5596, 6122, 2750, 2196, 1541, 2539, 2079, 2459, 274, + 7524, 6539, 5015, 6097, 7040, 5220, 2716, 1752, 28, 2552, 133, 4441, + 6719, 2298, 6952, 7075, 4672, 5559, 6830, 1442, 2979, 485, 4549, 4224, + 6065, 1944, 5, 1553, 5046, 3436, 4766, 959, 3291, 3684, 6031, 2137, + 1597, 2908, 1825, 6132, 98, 1251, 4306, 4022, 4314, 362, 1289, 5560, + 3830, 6724, 6671, 1215, 2281, 4899, 5074, 5988, 5041, 1883, 2822, 7024, + 2920, 594, 6189, 6662, 3247, 771, 5822, 1742, 4206, 3686, 776, 5987, + 8, 4021, 38, 5658, 3017, 6143, 889, 4216}; const uint16_t psis_inv_montgomery[KYBER_N] = { - 1024, 4972, 5779, 6907, 4943, 4168, 315, 5580, 90, 497, 1123, 142, 4710, 5527, 2443, 4871, - 698, 2489, 2394, 4003, 684, 2241, 2390, 7224, 5072, 2064, 4741, 1687, 6841, 482, 7441, 1235, - 2126, 4742, 2802, 5744, 6287, 4933, 699, 3604, 1297, 2127, 5857, 1705, 3868, 3779, 4397, 2177, - 159, 622, 2240, 1275, 640, 6948, 4572, 5277, 209, 2605, 1157, 7328, 5817, 3191, 1662, 2009, - 4864, 574, 2487, 164, 6197, 4436, 7257, 3462, 4268, 4281, 3414, 4515, 3170, 1290, 2003, 5855, - 7156, 6062, 7531, 1732, 3249, 4884, 7512, 3590, 1049, 2123, 1397, 6093, 3691, 6130, 6541, 3946, - 6258, 3322, 1788, 4241, 4900, 2309, 1400, 1757, 400, 502, 6698, 2338, 3011, 668, 7444, 4580, - 6516, 6795, 2959, 4136, 3040, 2279, 6355, 3943, 2913, 6613, 7416, 4084, 6508, 5556, 4054, 3782, - 61, 6567, 2212, 779, 632, 5709, 5667, 4923, 4911, 6893, 4695, 4164, 3536, 2287, 7594, 2848, - 3267, 1911, 3128, 546, 1991, 156, 4958, 5531, 6903, 483, 875, 138, 250, 2234, 2266, 7222, - 2842, 4258, 812, 6703, 232, 5207, 6650, 2585, 1900, 6225, 4932, 7265, 4701, 3173, 4635, 6393, - 227, 7313, 4454, 4284, 6759, 1224, 5223, 1447, 395, 2608, 4502, 4037, 189, 3348, 54, 6443, - 2210, 6230, 2826, 1780, 3002, 5995, 1955, 6102, 6045, 3938, 5019, 4417, 1434, 1262, 1507, 5847, - 5917, 7157, 7177, 6434, 7537, 741, 4348, 1309, 145, 374, 2236, 4496, 5028, 6771, 6923, 7421, - 1978, 1023, 3857, 6876, 1102, 7451, 4704, 6518, 1344, 765, 384, 5705, 1207, 1630, 4734, 1563, - 6839, 5933, 1954, 4987, 7142, 5814, 7527, 4953, 7637, 4707, 2182, 5734, 2818, 541, 4097, 5641}; - + 1024, 4972, 5779, 6907, 4943, 4168, 315, 5580, 90, 497, 1123, 142, + 4710, 5527, 2443, 4871, 698, 2489, 2394, 4003, 684, 2241, 2390, 7224, + 5072, 2064, 4741, 1687, 6841, 482, 7441, 1235, 2126, 4742, 2802, 5744, + 6287, 4933, 699, 3604, 1297, 2127, 5857, 1705, 3868, 3779, 4397, 2177, + 159, 622, 2240, 1275, 640, 6948, 4572, 5277, 209, 2605, 1157, 7328, + 5817, 3191, 1662, 2009, 4864, 574, 2487, 164, 6197, 4436, 7257, 3462, + 4268, 4281, 3414, 4515, 3170, 1290, 2003, 5855, 7156, 6062, 7531, 1732, + 3249, 4884, 7512, 3590, 1049, 2123, 1397, 6093, 3691, 6130, 6541, 3946, + 6258, 3322, 1788, 4241, 4900, 2309, 1400, 1757, 400, 502, 6698, 2338, + 3011, 668, 7444, 4580, 6516, 6795, 2959, 4136, 3040, 2279, 6355, 3943, + 2913, 6613, 7416, 4084, 6508, 5556, 4054, 3782, 61, 6567, 2212, 779, + 632, 5709, 5667, 4923, 4911, 6893, 4695, 4164, 3536, 2287, 7594, 2848, + 3267, 1911, 3128, 546, 1991, 156, 4958, 5531, 6903, 483, 875, 138, + 250, 2234, 2266, 7222, 2842, 4258, 812, 6703, 232, 5207, 6650, 2585, + 1900, 6225, 4932, 7265, 4701, 3173, 4635, 6393, 227, 7313, 4454, 4284, + 6759, 1224, 5223, 1447, 395, 2608, 4502, 4037, 189, 3348, 54, 6443, + 2210, 6230, 2826, 1780, 3002, 5995, 1955, 6102, 6045, 3938, 5019, 4417, + 1434, 1262, 1507, 5847, 5917, 7157, 7177, 6434, 7537, 741, 4348, 1309, + 145, 374, 2236, 4496, 5028, 6771, 6923, 7421, 1978, 1023, 3857, 6876, + 1102, 7451, 4704, 6518, 1344, 765, 384, 5705, 1207, 1630, 4734, 1563, + 6839, 5933, 1954, 4987, 7142, 5814, 7527, 4953, 7637, 4707, 2182, 5734, + 2818, 541, 4097, 5641}; diff --git a/crypto_kem/kyber768/clean/reduce.c b/crypto_kem/kyber768/clean/reduce.c index c626a0d2..ae3b3cdc 100644 --- a/crypto_kem/kyber768/clean/reduce.c +++ b/crypto_kem/kyber768/clean/reduce.c @@ -1,73 +1,70 @@ #include "reduce.h" #include "params.h" - static const uint32_t qinv = 7679; // -inverse_mod(q,2^18) static const uint32_t rlog = 18; /************************************************* -* 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^18 (see value of rlog) -* -* Arguments: - uint32_t a: input unsigned integer to be reduced; has to be in {0,...,2281446912} -* -* Returns: unsigned integer in {0,...,2^13-1} congruent to a * R^-1 modulo q. -**************************************************/ -uint16_t montgomery_reduce(uint32_t a) -{ + * 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^18 (see value of rlog) + * + * Arguments: - uint32_t a: input unsigned integer to be reduced; has to be in + *{0,...,2281446912} + * + * Returns: unsigned integer in {0,...,2^13-1} congruent to a * R^-1 modulo + *q. + **************************************************/ +uint16_t montgomery_reduce(uint32_t a) { uint32_t u; u = (a * qinv); - u &= ((1<> rlog; } - /************************************************* -* Name: barrett_reduce -* -* Description: Barrett reduction; given a 16-bit integer a, computes -* 16-bit integer congruent to a mod q in {0,...,11768} -* -* Arguments: - uint16_t a: input unsigned integer to be reduced -* -* Returns: unsigned integer in {0,...,11768} congruent to a modulo q. -**************************************************/ -uint16_t barrett_reduce(uint16_t a) -{ + * Name: barrett_reduce + * + * Description: Barrett reduction; given a 16-bit integer a, computes + * 16-bit integer congruent to a mod q in {0,...,11768} + * + * Arguments: - uint16_t a: input unsigned integer to be reduced + * + * Returns: unsigned integer in {0,...,11768} congruent to a modulo q. + **************************************************/ +uint16_t barrett_reduce(uint16_t a) { uint32_t u; - u = a >> 13;//((uint32_t) a * sinv) >> 16; + u = a >> 13; //((uint32_t) a * sinv) >> 16; u *= KYBER_Q; a -= u; return a; } /************************************************* -* Name: freeze -* -* Description: Full reduction; given a 16-bit integer a, computes -* unsigned integer a mod q. -* -* Arguments: - uint16_t x: input unsigned integer to be reduced -* -* Returns: unsigned integer in {0,...,q-1} congruent to a modulo q. -**************************************************/ -uint16_t freeze(uint16_t x) -{ - uint16_t m,r; + * Name: freeze + * + * Description: Full reduction; given a 16-bit integer a, computes + * unsigned integer a mod q. + * + * Arguments: - uint16_t x: input unsigned integer to be reduced + * + * Returns: unsigned integer in {0,...,q-1} congruent to a modulo q. + **************************************************/ +uint16_t freeze(uint16_t x) { + uint16_t m, r; int16_t c; r = barrett_reduce(x); m = r - KYBER_Q; c = m; - c >>= 15; - r = m ^ ((r^m)&c); + c >>= 15; + r = m ^ ((r ^ m) & c); return r; } diff --git a/crypto_kem/kyber768/clean/verify.c b/crypto_kem/kyber768/clean/verify.c index 9ab6ecab..9f9a79fb 100644 --- a/crypto_kem/kyber768/clean/verify.c +++ b/crypto_kem/kyber768/clean/verify.c @@ -1,24 +1,23 @@ -#include #include +#include /************************************************* -* Name: verify -* -* Description: Compare two arrays for equality in constant time. -* -* Arguments: const unsigned char *a: pointer to first byte array -* const unsigned char *b: pointer to second byte array -* size_t len: length of the byte arrays -* -* Returns 0 if the byte arrays are equal, 1 otherwise -**************************************************/ -int verify(const unsigned char *a, const unsigned char *b, size_t len) -{ + * Name: verify + * + * Description: Compare two arrays for equality in constant time. + * + * Arguments: const unsigned char *a: pointer to first byte array + * const unsigned char *b: pointer to second byte array + * size_t len: length of the byte arrays + * + * Returns 0 if the byte arrays are equal, 1 otherwise + **************************************************/ +int verify(const unsigned char *a, const unsigned char *b, size_t len) { uint64_t r; size_t i; r = 0; - - for(i=0;i> 63; @@ -26,23 +25,23 @@ int verify(const unsigned char *a, const unsigned char *b, size_t len) } /************************************************* -* 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: unsigned char *r: pointer to output byte array -* const unsigned char *x: pointer to input byte array -* size_t len: Amount of bytes to be copied -* unsigned char b: Condition bit; has to be in {0,1} -**************************************************/ -void cmov(unsigned char *r, const unsigned char *x, size_t len, unsigned char b) -{ + * 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: unsigned char *r: pointer to output byte array + * const unsigned char *x: pointer to input byte array + * size_t len: Amount of bytes to be copied + * unsigned char b: Condition bit; has to be in {0,1} + **************************************************/ +void cmov(unsigned char *r, const unsigned char *x, size_t len, + unsigned char b) { size_t i; b = -b; - for(i=0;i