@@ -0,0 +1,5 @@ | |||
--- | |||
Language: Cpp | |||
BasedOnStyle: LLVM | |||
... | |||
@@ -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 |
@@ -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 <stdint.h> | |||
#include <assert.h> | |||
#include "fips202.h" | |||
#include <assert.h> | |||
#include <stdint.h> | |||
#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 <string.h> | |||
#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<outlen;i++) | |||
for (i = 0; i < outlen; i++) | |||
output[i] = t[i]; | |||
} | |||
} | |||
/************************************************* | |||
* Name: sha3_256 | |||
* | |||
* Description: SHA3-256 with non-incremental API | |||
* | |||
* Arguments: - unsigned char *output: pointer to output | |||
* - const unsigned char *input: pointer to input | |||
* - unsigned long long inlen: length of input in bytes | |||
**************************************************/ | |||
void sha3_256(unsigned char *output, const unsigned char *input, unsigned long long inlen) | |||
{ | |||
* Name: sha3_256 | |||
* | |||
* Description: SHA3-256 with non-incremental API | |||
* | |||
* Arguments: - unsigned char *output: pointer to output | |||
* - const unsigned char *input: pointer to input | |||
* - unsigned long long inlen: length of input in bytes | |||
**************************************************/ | |||
void sha3_256(unsigned char *output, const unsigned char *input, | |||
unsigned long long inlen) { | |||
uint64_t s[25]; | |||
unsigned char t[SHA3_256_RATE]; | |||
size_t i; | |||
@@ -518,21 +498,21 @@ void sha3_256(unsigned char *output, const unsigned char *input, unsigned long | |||
/* Squeeze output */ | |||
keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); | |||
for(i=0;i<32;i++) | |||
output[i] = t[i]; | |||
for (i = 0; i < 32; i++) | |||
output[i] = t[i]; | |||
} | |||
/************************************************* | |||
* Name: sha3_512 | |||
* | |||
* Description: SHA3-512 with non-incremental API | |||
* | |||
* Arguments: - unsigned char *output: pointer to output | |||
* - const unsigned char *input: pointer to input | |||
* - unsigned long long inlen: length of input in bytes | |||
**************************************************/ | |||
void sha3_512(unsigned char *output, const unsigned char *input, unsigned long long inlen) | |||
{ | |||
* Name: sha3_512 | |||
* | |||
* Description: SHA3-512 with non-incremental API | |||
* | |||
* Arguments: - unsigned char *output: pointer to output | |||
* - const unsigned char *input: pointer to input | |||
* - unsigned long long inlen: length of input in bytes | |||
**************************************************/ | |||
void sha3_512(unsigned char *output, const unsigned char *input, | |||
unsigned long long inlen) { | |||
uint64_t s[25]; | |||
unsigned char t[SHA3_512_RATE]; | |||
size_t i; | |||
@@ -543,7 +523,6 @@ void sha3_512(unsigned char *output, const unsigned char *input, unsigned long | |||
/* Squeeze output */ | |||
keccak_squeezeblocks(t, 1, s, SHA3_512_RATE); | |||
for(i=0;i<64;i++) | |||
output[i] = t[i]; | |||
for (i = 0; i < 64; i++) | |||
output[i] = t[i]; | |||
} | |||
@@ -6,13 +6,18 @@ | |||
#define SHAKE128_RATE 168 | |||
#define SHAKE256_RATE 136 | |||
#define SHA3_256_RATE 136 | |||
#define SHA3_512_RATE 72 | |||
#define SHA3_512_RATE 72 | |||
void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen); | |||
void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s); | |||
void shake128_absorb(uint64_t *s, const unsigned char *input, | |||
unsigned int inputByteLen); | |||
void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, | |||
uint64_t *s); | |||
void shake256(unsigned char *output, unsigned long long outlen, const unsigned char *input, unsigned long long inlen); | |||
void sha3_256(unsigned char *output, const unsigned char *input, unsigned long long inlen); | |||
void sha3_512(unsigned char *output, 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); | |||
void sha3_256(unsigned char *output, const unsigned char *input, | |||
unsigned long long inlen); | |||
void sha3_512(unsigned char *output, const unsigned char *input, | |||
unsigned long long inlen); | |||
#endif |
@@ -7,41 +7,50 @@ | |||
* scenario where you are expecting actual cryptography to happen. | |||
*/ | |||
#include <stdint.h> | |||
#include "randombytes.h" | |||
#include <stdint.h> | |||
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; | |||
} | |||
@@ -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 |
@@ -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; | |||
} |
@@ -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 | |||
@@ -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 |
@@ -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<bytes;i++) | |||
r |= (uint64_t)x[i] << (8*i); | |||
for (i = 1; i < bytes; i++) | |||
r |= (uint64_t)x[i] << (8 * i); | |||
return r; | |||
} | |||
/************************************************* | |||
* Name: cbd | |||
* | |||
* Description: Given an array of uniformly random bytes, compute | |||
* polynomial with coefficients distributed according to | |||
* a centered binomial distribution with parameter KYBER_ETA | |||
* | |||
* Arguments: - poly *r: pointer to output polynomial | |||
* - const unsigned char *buf: pointer to input byte array | |||
**************************************************/ | |||
void cbd(poly *r, const unsigned char *buf) | |||
{ | |||
* Name: cbd | |||
* | |||
* Description: Given an array of uniformly random bytes, compute | |||
* polynomial with coefficients distributed according to | |||
* a centered binomial distribution with parameter KYBER_ETA | |||
* | |||
* Arguments: - poly *r: pointer to output polynomial | |||
* - const unsigned char *buf: pointer to input byte array | |||
**************************************************/ | |||
void cbd(poly *r, const unsigned char *buf) { | |||
#if KYBER_ETA == 3 | |||
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<KYBER_N/4;i++) | |||
{ | |||
t = load_littleendian(buf+3*i,3); | |||
for (i = 0; i < KYBER_N / 4; i++) { | |||
t = load_littleendian(buf + 3 * i, 3); | |||
d = 0; | |||
for(j=0;j<3;j++) | |||
for (j = 0; j < 3; j++) | |||
d += (t >> 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<KYBER_N/4;i++) | |||
{ | |||
t = load_littleendian(buf+4*i,4); | |||
for (i = 0; i < KYBER_N / 4; i++) { | |||
t = load_littleendian(buf + 4 * i, 4); | |||
d = 0; | |||
for(j=0;j<4;j++) | |||
for (j = 0; j < 4; j++) | |||
d += (t >> 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<KYBER_N/4;i++) | |||
{ | |||
t = load_littleendian(buf+5*i,5); | |||
for (i = 0; i < KYBER_N / 4; i++) { | |||
t = load_littleendian(buf + 5 * i, 5); | |||
d = 0; | |||
for(j=0;j<5;j++) | |||
for (j = 0; j < 5; j++) | |||
d += (t >> 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}" | |||
@@ -1,8 +1,8 @@ | |||
#ifndef CBD_H | |||
#define CBD_H | |||
#include <stdint.h> | |||
#include "poly.h" | |||
#include <stdint.h> | |||
void cbd(poly *r, const unsigned char *buf); | |||
@@ -1,172 +1,169 @@ | |||
#include <string.h> | |||
#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 <string.h> | |||
/************************************************* | |||
* 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<KYBER_SYMBYTES;i++) | |||
r[i+KYBER_POLYVECCOMPRESSEDBYTES] = seed[i]; | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
r[i + KYBER_POLYVECCOMPRESSEDBYTES] = seed[i]; | |||
} | |||
/************************************************* | |||
* Name: unpack_pk | |||
* | |||
* Description: De-serialize and decompress public key from a byte array; | |||
* approximate inverse of pack_pk | |||
* | |||
* Arguments: - polyvec *pk: pointer to output public-key vector of polynomials | |||
* - unsigned char *seed: pointer to output seed to generate matrix A | |||
* - const unsigned char *packedpk: pointer to input serialized public key | |||
**************************************************/ | |||
static void unpack_pk(polyvec *pk, unsigned char *seed, const unsigned char *packedpk) | |||
{ | |||
* Name: unpack_pk | |||
* | |||
* Description: De-serialize and decompress public key from a byte array; | |||
* approximate inverse of pack_pk | |||
* | |||
* Arguments: - polyvec *pk: pointer to output public-key | |||
*vector of polynomials | |||
* - unsigned char *seed: pointer to output seed to | |||
*generate matrix A | |||
* - const unsigned char *packedpk: pointer to input serialized | |||
*public key | |||
**************************************************/ | |||
static void unpack_pk(polyvec *pk, unsigned char *seed, | |||
const unsigned char *packedpk) { | |||
int i; | |||
polyvec_decompress(pk, packedpk); | |||
for(i=0;i<KYBER_SYMBYTES;i++) | |||
seed[i] = packedpk[i+KYBER_POLYVECCOMPRESSEDBYTES]; | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
seed[i] = packedpk[i + KYBER_POLYVECCOMPRESSEDBYTES]; | |||
} | |||
/************************************************* | |||
* Name: pack_ciphertext | |||
* | |||
* Description: Serialize the ciphertext as concatenation of the | |||
* compressed and serialized vector of polynomials b | |||
* and the compressed and serialized polynomial v | |||
* | |||
* Arguments: unsigned char *r: pointer to the output serialized ciphertext | |||
* const poly *pk: pointer to the input vector of polynomials b | |||
* const unsigned char *seed: pointer to the input polynomial v | |||
**************************************************/ | |||
static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) | |||
{ | |||
* Name: pack_ciphertext | |||
* | |||
* Description: Serialize the ciphertext as concatenation of the | |||
* compressed and serialized vector of polynomials b | |||
* and the compressed and serialized polynomial v | |||
* | |||
* Arguments: unsigned char *r: pointer to the output serialized | |||
*ciphertext const poly *pk: pointer to the input vector of | |||
*polynomials b const unsigned char *seed: pointer to the input polynomial v | |||
**************************************************/ | |||
static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) { | |||
polyvec_compress(r, b); | |||
poly_compress(r+KYBER_POLYVECCOMPRESSEDBYTES, v); | |||
poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v); | |||
} | |||
/************************************************* | |||
* Name: unpack_ciphertext | |||
* | |||
* Description: De-serialize and decompress ciphertext from a byte array; | |||
* approximate inverse of pack_ciphertext | |||
* | |||
* Arguments: - polyvec *b: pointer to the output vector of polynomials b | |||
* - poly *v: pointer to the output polynomial v | |||
* - const unsigned char *c: pointer to the input serialized ciphertext | |||
**************************************************/ | |||
static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) | |||
{ | |||
* Name: unpack_ciphertext | |||
* | |||
* Description: De-serialize and decompress ciphertext from a byte array; | |||
* approximate inverse of pack_ciphertext | |||
* | |||
* Arguments: - polyvec *b: pointer to the output vector of | |||
*polynomials b | |||
* - poly *v: pointer to the output polynomial v | |||
* - const unsigned char *c: pointer to the input serialized | |||
*ciphertext | |||
**************************************************/ | |||
static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) { | |||
polyvec_decompress(b, c); | |||
poly_decompress(v, c+KYBER_POLYVECCOMPRESSEDBYTES); | |||
poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES); | |||
} | |||
/************************************************* | |||
* Name: pack_sk | |||
* | |||
* Description: Serialize the secret key | |||
* | |||
* Arguments: - unsigned char *r: pointer to output serialized secret key | |||
* - const polyvec *sk: pointer to input vector of polynomials (secret key) | |||
**************************************************/ | |||
static void pack_sk(unsigned char *r, const polyvec *sk) | |||
{ | |||
* Name: pack_sk | |||
* | |||
* Description: Serialize the secret key | |||
* | |||
* Arguments: - unsigned char *r: pointer to output serialized secret key | |||
* - const polyvec *sk: pointer to input vector of polynomials | |||
*(secret key) | |||
**************************************************/ | |||
static void pack_sk(unsigned char *r, const polyvec *sk) { | |||
polyvec_tobytes(r, sk); | |||
} | |||
/************************************************* | |||
* Name: unpack_sk | |||
* | |||
* Description: De-serialize the secret key; | |||
* inverse of pack_sk | |||
* | |||
* Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key) | |||
* - const unsigned char *packedsk: pointer to input serialized secret key | |||
**************************************************/ | |||
static void unpack_sk(polyvec *sk, const unsigned char *packedsk) | |||
{ | |||
* Name: unpack_sk | |||
* | |||
* Description: De-serialize the secret key; | |||
* inverse of pack_sk | |||
* | |||
* Arguments: - polyvec *sk: pointer to output vector of | |||
*polynomials (secret key) | |||
* - const unsigned char *packedsk: pointer to input serialized | |||
*secret key | |||
**************************************************/ | |||
static void unpack_sk(polyvec *sk, const unsigned char *packedsk) { | |||
polyvec_frombytes(sk, packedsk); | |||
} | |||
#define gen_a(A,B) gen_matrix(A,B,0) | |||
#define gen_at(A,B) gen_matrix(A,B,1) | |||
#define gen_a(A, B) gen_matrix(A, B, 0) | |||
#define gen_at(A, B) gen_matrix(A, B, 1) | |||
/************************************************* | |||
* Name: gen_matrix | |||
* | |||
* Description: Deterministically generate matrix A (or the transpose of A) | |||
* from a seed. Entries of the matrix are polynomials that look | |||
* uniformly random. Performs rejection sampling on output of | |||
* SHAKE-128 | |||
* | |||
* Arguments: - polyvec *a: pointer to ouptput matrix A | |||
* - const unsigned char *seed: pointer to input seed | |||
* - int transposed: boolean deciding whether A or A^T is generated | |||
**************************************************/ | |||
void gen_matrix(polyvec *a, const unsigned char *seed, int transposed) // Not static for benchmarking | |||
* Name: gen_matrix | |||
* | |||
* Description: Deterministically generate matrix A (or the transpose of A) | |||
* from a seed. Entries of the matrix are polynomials that look | |||
* uniformly random. Performs rejection sampling on output of | |||
* SHAKE-128 | |||
* | |||
* Arguments: - polyvec *a: pointer to ouptput matrix A | |||
* - const unsigned char *seed: pointer to input seed | |||
* - int transposed: boolean deciding whether A or A^T | |||
*is generated | |||
**************************************************/ | |||
void gen_matrix(polyvec *a, const unsigned char *seed, | |||
int transposed) // Not static for benchmarking | |||
{ | |||
unsigned int pos=0, ctr; | |||
unsigned int pos = 0, ctr; | |||
uint16_t val; | |||
unsigned int nblocks; | |||
const unsigned int maxnblocks=4; | |||
uint8_t buf[SHAKE128_RATE*maxnblocks]; | |||
int i,j; | |||
const unsigned int maxnblocks = 4; | |||
uint8_t buf[SHAKE128_RATE * maxnblocks]; | |||
int i, j; | |||
uint64_t state[25]; // SHAKE state | |||
unsigned char extseed[KYBER_SYMBYTES+2]; | |||
unsigned char extseed[KYBER_SYMBYTES + 2]; | |||
for(i=0;i<KYBER_SYMBYTES;i++) | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
extseed[i] = seed[i]; | |||
for(i=0;i<KYBER_K;i++) | |||
{ | |||
for(j=0;j<KYBER_K;j++) | |||
{ | |||
for (i = 0; i < KYBER_K; i++) { | |||
for (j = 0; j < KYBER_K; j++) { | |||
ctr = pos = 0; | |||
nblocks = maxnblocks; | |||
if(transposed) | |||
{ | |||
extseed[KYBER_SYMBYTES] = i; | |||
extseed[KYBER_SYMBYTES+1] = j; | |||
} | |||
else | |||
{ | |||
extseed[KYBER_SYMBYTES] = j; | |||
extseed[KYBER_SYMBYTES+1] = i; | |||
if (transposed) { | |||
extseed[KYBER_SYMBYTES] = i; | |||
extseed[KYBER_SYMBYTES + 1] = j; | |||
} else { | |||
extseed[KYBER_SYMBYTES] = j; | |||
extseed[KYBER_SYMBYTES + 1] = i; | |||
} | |||
shake128_absorb(state,extseed,KYBER_SYMBYTES+2); | |||
shake128_squeezeblocks(buf,nblocks,state); | |||
while(ctr < KYBER_N) | |||
{ | |||
val = (buf[pos] | ((uint16_t) buf[pos+1] << 8)) & 0x1fff; | |||
if(val < KYBER_Q) | |||
{ | |||
a[i].vec[j].coeffs[ctr++] = val; | |||
shake128_absorb(state, extseed, KYBER_SYMBYTES + 2); | |||
shake128_squeezeblocks(buf, nblocks, state); | |||
while (ctr < KYBER_N) { | |||
val = (buf[pos] | ((uint16_t)buf[pos + 1] << 8)) & 0x1fff; | |||
if (val < KYBER_Q) { | |||
a[i].vec[j].coeffs[ctr++] = val; | |||
} | |||
pos += 2; | |||
if(pos > 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<KYBER_K;i++) | |||
poly_getnoise(skpv.vec+i,noiseseed,nonce++); | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_getnoise(skpv.vec + i, noiseseed, nonce++); | |||
polyvec_ntt(&skpv); | |||
for(i=0;i<KYBER_K;i++) | |||
poly_getnoise(e.vec+i,noiseseed,nonce++); | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_getnoise(e.vec + i, noiseseed, nonce++); | |||
// matrix-vector multiplication | |||
for(i=0;i<KYBER_K;i++) | |||
polyvec_pointwise_acc(&pkpv.vec[i],&skpv,a+i); | |||
for (i = 0; i < KYBER_K; i++) | |||
polyvec_pointwise_acc(&pkpv.vec[i], &skpv, a + i); | |||
polyvec_invntt(&pkpv); | |||
polyvec_add(&pkpv,&pkpv,&e); | |||
polyvec_add(&pkpv, &pkpv, &e); | |||
pack_sk(sk, &skpv); | |||
pack_pk(pk, &pkpv, publicseed); | |||
} | |||
/************************************************* | |||
* Name: indcpa_enc | |||
* | |||
* Description: Encryption function of the CPA-secure | |||
* public-key encryption scheme underlying Kyber. | |||
* | |||
* Arguments: - unsigned char *c: pointer to output ciphertext (of length KYBER_INDCPA_BYTES bytes) | |||
* - const unsigned char *m: pointer to input message (of length KYBER_INDCPA_MSGBYTES bytes) | |||
* - const unsigned char *pk: pointer to input public key (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) | |||
* - const unsigned char *coin: pointer to input random coins used as seed (of length KYBER_SYMBYTES bytes) | |||
* to deterministically generate all randomness | |||
**************************************************/ | |||
void indcpa_enc(unsigned char *c, | |||
const unsigned char *m, | |||
const unsigned char *pk, | |||
const unsigned char *coins) | |||
{ | |||
* Name: indcpa_enc | |||
* | |||
* Description: Encryption function of the CPA-secure | |||
* public-key encryption scheme underlying Kyber. | |||
* | |||
* Arguments: - unsigned char *c: pointer to output ciphertext (of | |||
*length KYBER_INDCPA_BYTES bytes) | |||
* - const unsigned char *m: pointer to input message (of length | |||
*KYBER_INDCPA_MSGBYTES bytes) | |||
* - const unsigned char *pk: pointer to input public key (of | |||
*length KYBER_INDCPA_PUBLICKEYBYTES bytes) | |||
* - const unsigned char *coin: pointer to input random coins used | |||
*as seed (of length KYBER_SYMBYTES bytes) to deterministically generate all | |||
*randomness | |||
**************************************************/ | |||
void indcpa_enc(unsigned char *c, const unsigned char *m, | |||
const unsigned char *pk, const unsigned char *coins) { | |||
polyvec sp, pkpv, ep, at[KYBER_K], bp; | |||
poly v, k, epp; | |||
unsigned char seed[KYBER_SYMBYTES]; | |||
int i; | |||
unsigned char nonce=0; | |||
unsigned char nonce = 0; | |||
unpack_pk(&pkpv, seed, pk); | |||
@@ -251,25 +246,25 @@ void indcpa_enc(unsigned char *c, | |||
gen_at(at, seed); | |||
for(i=0;i<KYBER_K;i++) | |||
poly_getnoise(sp.vec+i,coins,nonce++); | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_getnoise(sp.vec + i, coins, nonce++); | |||
polyvec_ntt(&sp); | |||
for(i=0;i<KYBER_K;i++) | |||
poly_getnoise(ep.vec+i,coins,nonce++); | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_getnoise(ep.vec + i, coins, nonce++); | |||
// matrix-vector multiplication | |||
for(i=0;i<KYBER_K;i++) | |||
polyvec_pointwise_acc(&bp.vec[i],&sp,at+i); | |||
for (i = 0; i < KYBER_K; i++) | |||
polyvec_pointwise_acc(&bp.vec[i], &sp, at + i); | |||
polyvec_invntt(&bp); | |||
polyvec_add(&bp, &bp, &ep); | |||
polyvec_pointwise_acc(&v, &pkpv, &sp); | |||
poly_invntt(&v); | |||
poly_getnoise(&epp,coins,nonce++); | |||
poly_getnoise(&epp, coins, nonce++); | |||
poly_add(&v, &v, &epp); | |||
poly_add(&v, &v, &k); | |||
@@ -278,19 +273,20 @@ void indcpa_enc(unsigned char *c, | |||
} | |||
/************************************************* | |||
* Name: indcpa_dec | |||
* | |||
* Description: Decryption function of the CPA-secure | |||
* public-key encryption scheme underlying Kyber. | |||
* | |||
* Arguments: - unsigned char *m: pointer to output decrypted message (of length KYBER_INDCPA_MSGBYTES) | |||
* - const unsigned char *c: pointer to input ciphertext (of length KYBER_INDCPA_BYTES) | |||
* - const unsigned char *sk: pointer to input secret key (of length KYBER_INDCPA_SECRETKEYBYTES) | |||
**************************************************/ | |||
void indcpa_dec(unsigned char *m, | |||
const unsigned char *c, | |||
const unsigned char *sk) | |||
{ | |||
* Name: indcpa_dec | |||
* | |||
* Description: Decryption function of the CPA-secure | |||
* public-key encryption scheme underlying Kyber. | |||
* | |||
* Arguments: - unsigned char *m: pointer to output decrypted message | |||
*(of length KYBER_INDCPA_MSGBYTES) | |||
* - const unsigned char *c: pointer to input ciphertext (of | |||
*length KYBER_INDCPA_BYTES) | |||
* - const unsigned char *sk: pointer to input secret key (of | |||
*length KYBER_INDCPA_SECRETKEYBYTES) | |||
**************************************************/ | |||
void indcpa_dec(unsigned char *m, const unsigned char *c, | |||
const unsigned char *sk) { | |||
polyvec bp, skpv; | |||
poly v, mp; | |||
@@ -299,7 +295,7 @@ void indcpa_dec(unsigned char *m, | |||
polyvec_ntt(&bp); | |||
polyvec_pointwise_acc(&mp,&skpv,&bp); | |||
polyvec_pointwise_acc(&mp, &skpv, &bp); | |||
poly_invntt(&mp); | |||
poly_sub(&mp, &mp, &v); | |||
@@ -1,16 +1,12 @@ | |||
#ifndef INDCPA_H | |||
#define INDCPA_H | |||
void indcpa_keypair(unsigned char *pk, | |||
unsigned char *sk); | |||
void indcpa_keypair(unsigned char *pk, unsigned char *sk); | |||
void indcpa_enc(unsigned char *c, | |||
const unsigned char *m, | |||
const unsigned char *pk, | |||
const unsigned char *coins); | |||
void indcpa_enc(unsigned char *c, const unsigned char *m, | |||
const unsigned char *pk, const unsigned char *coins); | |||
void indcpa_dec(unsigned char *m, | |||
const unsigned char *c, | |||
const unsigned char *sk); | |||
void indcpa_dec(unsigned char *m, const unsigned char *c, | |||
const unsigned char *sk); | |||
#endif |
@@ -1,100 +1,120 @@ | |||
#include "api.h" | |||
#include "randombytes.h" | |||
#include "fips202.h" | |||
#include "indcpa.h" | |||
#include "params.h" | |||
#include "randombytes.h" | |||
#include "verify.h" | |||
#include "indcpa.h" | |||
/************************************************* | |||
* Name: crypto_kem_keypair | |||
* | |||
* Description: Generates public and private key | |||
* for CCA-secure Kyber key encapsulation mechanism | |||
* | |||
* Arguments: - unsigned char *pk: pointer to output public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) | |||
* - unsigned char *sk: pointer to output private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) | |||
* | |||
* Returns 0 (success) | |||
**************************************************/ | |||
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk) | |||
{ | |||
* Name: crypto_kem_keypair | |||
* | |||
* Description: Generates public and private key | |||
* for CCA-secure Kyber key encapsulation mechanism | |||
* | |||
* Arguments: - unsigned char *pk: pointer to output public key (an already | |||
*allocated array of CRYPTO_PUBLICKEYBYTES bytes) | |||
* - unsigned char *sk: pointer to output private key (an already | |||
*allocated array of CRYPTO_SECRETKEYBYTES bytes) | |||
* | |||
* Returns 0 (success) | |||
**************************************************/ | |||
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { | |||
size_t i; | |||
indcpa_keypair(pk, sk); | |||
for(i=0;i<KYBER_INDCPA_PUBLICKEYBYTES;i++) | |||
sk[i+KYBER_INDCPA_SECRETKEYBYTES] = pk[i]; | |||
sha3_256(sk+KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES,pk,KYBER_PUBLICKEYBYTES); | |||
randombytes(sk+KYBER_SECRETKEYBYTES-KYBER_SYMBYTES,KYBER_SYMBYTES); /* Value z for pseudo-random output on reject */ | |||
for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++) | |||
sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i]; | |||
sha3_256(sk + KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES, pk, | |||
KYBER_PUBLICKEYBYTES); | |||
randombytes(sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, | |||
KYBER_SYMBYTES); /* Value z for pseudo-random output on reject */ | |||
return 0; | |||
} | |||
/************************************************* | |||
* Name: crypto_kem_enc | |||
* | |||
* Description: Generates cipher text and shared | |||
* secret for given public key | |||
* | |||
* Arguments: - unsigned char *ct: pointer to output cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) | |||
* - unsigned char *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) | |||
* - const unsigned char *pk: pointer to input public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) | |||
* | |||
* Returns 0 (success) | |||
**************************************************/ | |||
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk) | |||
{ | |||
unsigned char kr[2*KYBER_SYMBYTES]; /* Will contain key, coins */ | |||
unsigned char buf[2*KYBER_SYMBYTES]; | |||
* Name: crypto_kem_enc | |||
* | |||
* Description: Generates cipher text and shared | |||
* secret for given public key | |||
* | |||
* Arguments: - unsigned char *ct: pointer to output cipher text (an | |||
*already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) | |||
* - unsigned char *ss: pointer to output shared secret (an | |||
*already allocated array of CRYPTO_BYTES bytes) | |||
* - const unsigned char *pk: pointer to input public key (an | |||
*already allocated array of CRYPTO_PUBLICKEYBYTES bytes) | |||
* | |||
* Returns 0 (success) | |||
**************************************************/ | |||
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, | |||
const unsigned char *pk) { | |||
unsigned char kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ | |||
unsigned char buf[2 * KYBER_SYMBYTES]; | |||
randombytes(buf, KYBER_SYMBYTES); | |||
sha3_256(buf,buf,KYBER_SYMBYTES); /* Don't release system RNG output */ | |||
sha3_256(buf, buf, KYBER_SYMBYTES); /* Don't release system RNG output */ | |||
sha3_256(buf+KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + contributory KEM */ | |||
sha3_512(kr, buf, 2*KYBER_SYMBYTES); | |||
sha3_256(buf + KYBER_SYMBYTES, pk, | |||
KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + | |||
contributory KEM */ | |||
sha3_512(kr, buf, 2 * KYBER_SYMBYTES); | |||
indcpa_enc(ct, buf, pk, kr+KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ | |||
indcpa_enc(ct, buf, pk, | |||
kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ | |||
sha3_256(kr+KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ | |||
sha3_256(ss, kr, 2*KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ | |||
sha3_256(kr + KYBER_SYMBYTES, ct, | |||
KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ | |||
sha3_256(ss, kr, | |||
2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ | |||
return 0; | |||
} | |||
/************************************************* | |||
* Name: crypto_kem_dec | |||
* | |||
* Description: Generates shared secret for given | |||
* cipher text and private key | |||
* | |||
* Arguments: - unsigned char *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) | |||
* - const unsigned char *ct: pointer to input cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) | |||
* - const unsigned char *sk: pointer to input private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) | |||
* | |||
* Returns 0. | |||
* | |||
* On failure, ss will contain a pseudo-random value. | |||
**************************************************/ | |||
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk) | |||
{ | |||
size_t i; | |||
* Name: crypto_kem_dec | |||
* | |||
* Description: Generates shared secret for given | |||
* cipher text and private key | |||
* | |||
* Arguments: - unsigned char *ss: pointer to output shared secret (an | |||
*already allocated array of CRYPTO_BYTES bytes) | |||
* - const unsigned char *ct: pointer to input cipher text (an | |||
*already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) | |||
* - const unsigned char *sk: pointer to input private key (an | |||
*already allocated array of CRYPTO_SECRETKEYBYTES bytes) | |||
* | |||
* Returns 0. | |||
* | |||
* On failure, ss will contain a pseudo-random value. | |||
**************************************************/ | |||
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, | |||
const unsigned char *sk) { | |||
size_t i; | |||
int fail; | |||
unsigned char cmp[KYBER_CIPHERTEXTBYTES]; | |||
unsigned char buf[2*KYBER_SYMBYTES]; | |||
unsigned char kr[2*KYBER_SYMBYTES]; /* Will contain key, coins, qrom-hash */ | |||
const unsigned char *pk = sk+KYBER_INDCPA_SECRETKEYBYTES; | |||
unsigned char buf[2 * KYBER_SYMBYTES]; | |||
unsigned char kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins, qrom-hash */ | |||
const unsigned char *pk = sk + KYBER_INDCPA_SECRETKEYBYTES; | |||
indcpa_dec(buf, ct, sk); | |||
for(i=0;i<KYBER_SYMBYTES;i++) /* Multitarget countermeasure for coins + contributory KEM */ | |||
buf[KYBER_SYMBYTES+i] = sk[KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES+i]; /* Save hash by storing H(pk) in sk */ | |||
sha3_512(kr, buf, 2*KYBER_SYMBYTES); | |||
indcpa_enc(cmp, buf, pk, kr+KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ | |||
for (i = 0; i < KYBER_SYMBYTES; | |||
i++) /* Multitarget countermeasure for coins + contributory KEM */ | |||
buf[KYBER_SYMBYTES + i] = sk[KYBER_SECRETKEYBYTES - 2 * KYBER_SYMBYTES + | |||
i]; /* Save hash by storing H(pk) in sk */ | |||
sha3_512(kr, buf, 2 * KYBER_SYMBYTES); | |||
indcpa_enc(cmp, buf, pk, | |||
kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ | |||
fail = verify(ct, cmp, KYBER_CIPHERTEXTBYTES); | |||
sha3_256(kr+KYBER_SYMBYTES, ct, KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ | |||
sha3_256(kr + KYBER_SYMBYTES, ct, | |||
KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ | |||
cmov(kr, sk+KYBER_SECRETKEYBYTES-KYBER_SYMBYTES, KYBER_SYMBYTES, fail); /* Overwrite pre-k with z on re-encryption failure */ | |||
cmov(kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES, | |||
fail); /* Overwrite pre-k with z on re-encryption failure */ | |||
sha3_256(ss, kr, 2*KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ | |||
sha3_256(ss, kr, | |||
2 * KYBER_SYMBYTES); /* hash concatenation of pre-k and H(c) to k */ | |||
return 0; | |||
} |
@@ -1,55 +1,49 @@ | |||
#include "kex.h" | |||
#include "verify.h" | |||
#include "fips202.h" | |||
#include "verify.h" | |||
void kyber_uake_initA(u8 *send, u8* tk, u8 *sk, const u8 *pkb) | |||
{ | |||
void kyber_uake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb) { | |||
crypto_kem_keypair(send, sk); | |||
crypto_kem_enc(send+KYBER_PUBLICKEYBYTES, tk, pkb); | |||
crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb); | |||
} | |||
void kyber_uake_sharedB(u8 *send, u8 *k, const u8* recv, const u8 *skb) | |||
{ | |||
unsigned char buf[2*KYBER_SYMBYTES]; | |||
void kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb) { | |||
unsigned char buf[2 * KYBER_SYMBYTES]; | |||
crypto_kem_enc(send, buf, recv); | |||
crypto_kem_dec(buf+KYBER_SYMBYTES, recv+KYBER_PUBLICKEYBYTES, skb); | |||
shake256(k,KYBER_SYMBYTES,buf,2*KYBER_SYMBYTES); | |||
crypto_kem_dec(buf + KYBER_SYMBYTES, recv + KYBER_PUBLICKEYBYTES, skb); | |||
shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES); | |||
} | |||
void kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk) | |||
{ | |||
unsigned char buf[2*KYBER_SYMBYTES]; | |||
void kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk) { | |||
unsigned char buf[2 * KYBER_SYMBYTES]; | |||
int i; | |||
crypto_kem_dec(buf, recv, sk); | |||
for(i=0;i<KYBER_SYMBYTES;i++) | |||
buf[i+KYBER_SYMBYTES] = tk[i]; | |||
shake256(k,KYBER_SYMBYTES,buf,2*KYBER_SYMBYTES); | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
buf[i + KYBER_SYMBYTES] = tk[i]; | |||
shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES); | |||
} | |||
void kyber_ake_initA(u8 *send, u8* tk, u8 *sk, const u8 *pkb) | |||
{ | |||
void kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb) { | |||
crypto_kem_keypair(send, sk); | |||
crypto_kem_enc(send+KYBER_PUBLICKEYBYTES, tk, pkb); | |||
crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb); | |||
} | |||
void kyber_ake_sharedB(u8 *send, u8 *k, const u8* recv, const u8 *skb, const u8 *pka) | |||
{ | |||
unsigned char buf[3*KYBER_SYMBYTES]; | |||
void kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb, | |||
const u8 *pka) { | |||
unsigned char buf[3 * KYBER_SYMBYTES]; | |||
crypto_kem_enc(send, buf, recv); | |||
crypto_kem_enc(send+KYBER_CIPHERTEXTBYTES, buf+KYBER_SYMBYTES, pka); | |||
crypto_kem_dec(buf+2*KYBER_SYMBYTES, recv+KYBER_PUBLICKEYBYTES, skb); | |||
shake256(k,KYBER_SYMBYTES,buf,3*KYBER_SYMBYTES); | |||
crypto_kem_enc(send + KYBER_CIPHERTEXTBYTES, buf + KYBER_SYMBYTES, pka); | |||
crypto_kem_dec(buf + 2 * KYBER_SYMBYTES, recv + KYBER_PUBLICKEYBYTES, skb); | |||
shake256(k, KYBER_SYMBYTES, buf, 3 * KYBER_SYMBYTES); | |||
} | |||
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, const u8 *ska) | |||
{ | |||
unsigned char buf[3*KYBER_SYMBYTES]; | |||
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, | |||
const u8 *ska) { | |||
unsigned char buf[3 * KYBER_SYMBYTES]; | |||
int i; | |||
crypto_kem_dec(buf, recv, sk); | |||
crypto_kem_dec(buf+KYBER_SYMBYTES, recv+KYBER_CIPHERTEXTBYTES, ska); | |||
for(i=0;i<KYBER_SYMBYTES;i++) | |||
buf[i+2*KYBER_SYMBYTES] = tk[i]; | |||
shake256(k,KYBER_SYMBYTES,buf,3*KYBER_SYMBYTES); | |||
crypto_kem_dec(buf + KYBER_SYMBYTES, recv + KYBER_CIPHERTEXTBYTES, ska); | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
buf[i + 2 * KYBER_SYMBYTES] = tk[i]; | |||
shake256(k, KYBER_SYMBYTES, buf, 3 * KYBER_SYMBYTES); | |||
} |
@@ -1,30 +1,29 @@ | |||
#ifndef KEX_H | |||
#define KEX_H | |||
#include "params.h" | |||
#include "api.h" | |||
#include "params.h" | |||
#define KYBER_UAKE_SENDABYTES (KYBER_PUBLICKEYBYTES + KYBER_CIPHERTEXTBYTES) | |||
#define KYBER_UAKE_SENDBBYTES (KYBER_CIPHERTEXTBYTES) | |||
#define KYBER_AKE_SENDABYTES (KYBER_PUBLICKEYBYTES + KYBER_CIPHERTEXTBYTES) | |||
#define KYBER_AKE_SENDBBYTES (2*KYBER_CIPHERTEXTBYTES) | |||
#define KYBER_AKE_SENDBBYTES (2 * KYBER_CIPHERTEXTBYTES) | |||
typedef unsigned char u8; | |||
void kyber_uake_initA(u8 *send, u8* tk, u8 *sk, const u8 *pkb); | |||
void kyber_uake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb); | |||
void kyber_uake_sharedB(u8 *send, u8 *k, const u8* recv, const u8 *skb); | |||
void kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb); | |||
void kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk); | |||
void kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb); | |||
void kyber_ake_initA(u8 *send, u8* tk, u8 *sk, const u8 *pkb); | |||
void kyber_ake_sharedB(u8 *send, u8 *k, const u8* recv, const u8 *skb, const u8 *pka); | |||
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, const u8 *ska); | |||
void kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb, | |||
const u8 *pka); | |||
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, | |||
const u8 *ska); | |||
#endif |
@@ -1,5 +1,5 @@ | |||
#include "inttypes.h" | |||
#include "ntt.h" | |||
#include "inttypes.h" | |||
#include "params.h" | |||
#include "reduce.h" | |||
@@ -8,34 +8,31 @@ extern const uint16_t psis_inv_montgomery[]; | |||
extern const uint16_t zetas[]; | |||
/************************************************* | |||
* Name: ntt | |||
* | |||
* Description: Computes negacyclic number-theoretic transform (NTT) of | |||
* a polynomial (vector of 256 coefficients) in place; | |||
* inputs assumed to be in normal order, output in bitreversed order | |||
* | |||
* Arguments: - uint16_t *p: pointer to in/output polynomial | |||
**************************************************/ | |||
void ntt(uint16_t *p) | |||
{ | |||
* Name: ntt | |||
* | |||
* Description: Computes negacyclic number-theoretic transform (NTT) of | |||
* a polynomial (vector of 256 coefficients) in place; | |||
* inputs assumed to be in normal order, output in bitreversed | |||
*order | |||
* | |||
* Arguments: - uint16_t *p: pointer to in/output polynomial | |||
**************************************************/ | |||
void ntt(uint16_t *p) { | |||
int level, start, j, k; | |||
uint16_t zeta, t; | |||
k = 1; | |||
for(level = 7; level >= 0; level--) | |||
{ | |||
for(start = 0; start < KYBER_N; start = j + (1<<level)) | |||
{ | |||
for (level = 7; level >= 0; level--) { | |||
for (start = 0; start < KYBER_N; start = j + (1 << level)) { | |||
zeta = zetas[k++]; | |||
for(j = start; j < start + (1<<level); ++j) | |||
{ | |||
t = montgomery_reduce((uint32_t)zeta * p[j + (1<<level)]); | |||
for (j = start; j < start + (1 << level); ++j) { | |||
t = montgomery_reduce((uint32_t)zeta * p[j + (1 << level)]); | |||
p[j + (1<<level)] = barrett_reduce(p[j] + 4*KYBER_Q - t); | |||
p[j + (1 << level)] = barrett_reduce(p[j] + 4 * KYBER_Q - t); | |||
if(level & 1) /* odd level */ | |||
if (level & 1) /* odd level */ | |||
p[j] = p[j] + t; /* Omit reduction (be lazy) */ | |||
else | |||
else | |||
p[j] = barrett_reduce(p[j] + t); | |||
} | |||
} | |||
@@ -43,42 +40,38 @@ void ntt(uint16_t *p) | |||
} | |||
/************************************************* | |||
* Name: invntt | |||
* | |||
* Description: Computes inverse of negacyclic number-theoretic transform (NTT) of | |||
* a polynomial (vector of 256 coefficients) in place; | |||
* inputs assumed to be in bitreversed order, output in normal order | |||
* | |||
* Arguments: - uint16_t *a: pointer to in/output polynomial | |||
**************************************************/ | |||
void invntt(uint16_t * a) | |||
{ | |||
* Name: invntt | |||
* | |||
* Description: Computes inverse of negacyclic number-theoretic transform (NTT) | |||
*of a polynomial (vector of 256 coefficients) in place; inputs assumed to be in | |||
*bitreversed order, output in normal order | |||
* | |||
* Arguments: - uint16_t *a: pointer to in/output polynomial | |||
**************************************************/ | |||
void invntt(uint16_t *a) { | |||
int start, j, jTwiddle, level; | |||
uint16_t temp, W; | |||
uint32_t t; | |||
for(level=0;level<8;level++) | |||
{ | |||
for(start = 0; start < (1<<level);start++) | |||
{ | |||
for (level = 0; level < 8; level++) { | |||
for (start = 0; start < (1 << level); start++) { | |||
jTwiddle = 0; | |||
for(j=start;j<KYBER_N-1;j+=2*(1<<level)) | |||
{ | |||
for (j = start; j < KYBER_N - 1; j += 2 * (1 << level)) { | |||
W = omegas_inv_bitrev_montgomery[jTwiddle++]; | |||
temp = a[j]; | |||
if(level & 1) /* odd level */ | |||
a[j] = barrett_reduce((temp + a[j + (1<<level)])); | |||
if (level & 1) /* odd level */ | |||
a[j] = barrett_reduce((temp + a[j + (1 << level)])); | |||
else | |||
a[j] = (temp + a[j + (1<<level)]); /* Omit reduction (be lazy) */ | |||
a[j] = (temp + a[j + (1 << level)]); /* Omit reduction (be lazy) */ | |||
t = (W * ((uint32_t)temp + 4*KYBER_Q - a[j + (1<<level)])); | |||
t = (W * ((uint32_t)temp + 4 * KYBER_Q - a[j + (1 << level)])); | |||
a[j + (1<<level)] = montgomery_reduce(t); | |||
a[j + (1 << level)] = montgomery_reduce(t); | |||
} | |||
} | |||
} | |||
for(j = 0; j < KYBER_N; j++) | |||
for (j = 0; j < KYBER_N; j++) | |||
a[j] = montgomery_reduce((a[j] * psis_inv_montgomery[j])); | |||
} |
@@ -3,7 +3,7 @@ | |||
#include <stdint.h> | |||
void ntt(uint16_t* poly); | |||
void invntt(uint16_t* poly); | |||
void ntt(uint16_t *poly); | |||
void invntt(uint16_t *poly); | |||
#endif |
@@ -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 |
@@ -1,248 +1,238 @@ | |||
#include <stdio.h> | |||
#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 <stdio.h> | |||
/************************************************* | |||
* 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;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; | |||
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;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; | |||
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;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); | |||
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;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); | |||
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;i<KYBER_SYMBYTES;i++) | |||
for (i = 0; i < KYBER_SYMBYTES; i++) | |||
extseed[i] = seed[i]; | |||
extseed[KYBER_SYMBYTES] = nonce; | |||
shake256(buf,KYBER_ETA*KYBER_N/4,extseed,KYBER_SYMBYTES+1); | |||
shake256(buf, KYBER_ETA * KYBER_N / 4, extseed, KYBER_SYMBYTES + 1); | |||
cbd(r, buf); | |||
} | |||
/************************************************* | |||
* Name: poly_ntt | |||
* | |||
* Description: Computes negacyclic number-theoretic transform (NTT) of | |||
* a polynomial in place; | |||
* inputs assumed to be in normal order, output in bitreversed order | |||
* | |||
* Arguments: - uint16_t *r: pointer to in/output polynomial | |||
**************************************************/ | |||
void poly_ntt(poly *r) | |||
{ | |||
ntt(r->coeffs); | |||
} | |||
* 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;i<KYBER_N;i++) | |||
for (i = 0; i < KYBER_N; i++) | |||
r->coeffs[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;i<KYBER_N;i++) | |||
r->coeffs[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<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_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;i<KYBER_SYMBYTES;i++) | |||
{ | |||
for (i = 0; i < KYBER_SYMBYTES; i++) { | |||
msg[i] = 0; | |||
for(j=0;j<8;j++) | |||
{ | |||
t = (((freeze(a->coeffs[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; | |||
} | |||
} | |||
@@ -1,14 +1,14 @@ | |||
#ifndef POLY_H | |||
#define POLY_H | |||
#include <stdint.h> | |||
#include "params.h" | |||
#include <stdint.h> | |||
/* | |||
/* | |||
* Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial | |||
* coeffs[0] + X*coeffs[1] + X^2*xoeffs[2] + ... + X^{n-1}*coeffs[n-1] | |||
* 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); | |||
@@ -1,152 +1,177 @@ | |||
#include <stdio.h> | |||
#include "polyvec.h" | |||
#include "fips202.h" | |||
#include "cbd.h" | |||
#include "fips202.h" | |||
#include "reduce.h" | |||
#include <stdio.h> | |||
/************************************************* | |||
* 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;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; | |||
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;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; | |||
* 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;i<KYBER_K;i++) | |||
poly_tobytes(r+i*KYBER_POLYBYTES, &a->vec[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;i<KYBER_K;i++) | |||
poly_frombytes(&r->vec[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;i<KYBER_K;i++) | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_ntt(&r->vec[i]); | |||
} | |||
/************************************************* | |||
* Name: polyvec_invntt | |||
* | |||
* Description: Apply inverse NTT to all elements of a vector of polynomials | |||
* | |||
* Arguments: - polyvec *r: pointer to in/output vector of polynomials | |||
**************************************************/ | |||
void 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;i<KYBER_K;i++) | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_invntt(&r->vec[i]); | |||
} | |||
/************************************************* | |||
* Name: polyvec_pointwise_acc | |||
* | |||
* Description: Pointwise multiply elements of a and b and accumulate into r | |||
* | |||
* Arguments: - poly *r: pointer to output polynomial | |||
* - const polyvec *a: pointer to first input vector of polynomials | |||
* - const polyvec *b: pointer to second input vector of polynomials | |||
**************************************************/ | |||
void 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;j<KYBER_N;j++) | |||
{ | |||
t = montgomery_reduce(4613* (uint32_t)b->vec[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;i<KYBER_K;i++) | |||
{ | |||
t = montgomery_reduce(4613* (uint32_t)b->vec[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;i<KYBER_K;i++) | |||
for (i = 0; i < KYBER_K; i++) | |||
poly_add(&r->vec[i], &a->vec[i], &b->vec[i]); | |||
} |
@@ -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); | |||
@@ -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}; |
@@ -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)-1); | |||
u &= ((1 << rlog) - 1); | |||
u *= KYBER_Q; | |||
a = a + u; | |||
return a >> 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; | |||
} |
@@ -1,24 +1,23 @@ | |||
#include <string.h> | |||
#include <stdint.h> | |||
#include <string.h> | |||
/************************************************* | |||
* 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<len;i++) | |||
for (i = 0; i < len; i++) | |||
r |= a[i] ^ b[i]; | |||
r = (-r) >> 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<len;i++) | |||
for (i = 0; i < len; i++) | |||
r[i] ^= b & (x[i] ^ r[i]); | |||
} |
@@ -5,6 +5,7 @@ | |||
int verify(const unsigned char *a, const unsigned char *b, size_t len); | |||
void cmov(unsigned char *r, const unsigned char *x, size_t len, unsigned char b); | |||
void cmov(unsigned char *r, const unsigned char *x, size_t len, | |||
unsigned char b); | |||
#endif |
@@ -5,66 +5,58 @@ | |||
#define NTESTS 10000 | |||
int test_keys() | |||
{ | |||
int test_keys() { | |||
unsigned char key_a[CRYPTO_BYTES], key_b[CRYPTO_BYTES]; | |||
unsigned char pk[CRYPTO_PUBLICKEYBYTES]; | |||
unsigned char sendb[CRYPTO_CIPHERTEXTBYTES]; | |||
unsigned char sk_a[CRYPTO_SECRETKEYBYTES]; | |||
int i; | |||
for(i=0; i<NTESTS; i++) | |||
{ | |||
//Alice generates a public key | |||
for (i = 0; i < NTESTS; i++) { | |||
// Alice generates a public key | |||
crypto_kem_keypair(pk, sk_a); | |||
//Bob derives a secret key and creates a response | |||
// Bob derives a secret key and creates a response | |||
crypto_kem_enc(sendb, key_b, pk); | |||
//Alice uses Bobs response to get her secret key | |||
// Alice uses Bobs response to get her secret key | |||
crypto_kem_dec(key_a, sendb, sk_a); | |||
if(memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
if (memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
printf("ERROR keys\n"); | |||
} | |||
return 0; | |||
} | |||
int test_invalid_sk_a() | |||
{ | |||
int test_invalid_sk_a() { | |||
unsigned char sk_a[CRYPTO_SECRETKEYBYTES]; | |||
unsigned char key_a[CRYPTO_BYTES], key_b[CRYPTO_BYTES]; | |||
unsigned char pk[CRYPTO_PUBLICKEYBYTES]; | |||
unsigned char sendb[CRYPTO_CIPHERTEXTBYTES]; | |||
int i; | |||
for(i=0; i<NTESTS; i++) | |||
{ | |||
//Alice generates a public key | |||
for (i = 0; i < NTESTS; i++) { | |||
// Alice generates a public key | |||
crypto_kem_keypair(pk, sk_a); | |||
//Bob derives a secret key and creates a response | |||
// Bob derives a secret key and creates a response | |||
crypto_kem_enc(sendb, key_b, pk); | |||
//Replace secret key with random values | |||
// Replace secret key with random values | |||
randombytes(sk_a, CRYPTO_SECRETKEYBYTES); | |||
//Alice uses Bobs response to get her secre key | |||
// Alice uses Bobs response to get her secre key | |||
crypto_kem_dec(key_a, sendb, sk_a); | |||
if(!memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
if (!memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
printf("ERROR invalid sk_a\n"); | |||
} | |||
return 0; | |||
} | |||
int test_invalid_ciphertext() | |||
{ | |||
int test_invalid_ciphertext() { | |||
unsigned char sk_a[CRYPTO_SECRETKEYBYTES]; | |||
unsigned char key_a[CRYPTO_BYTES], key_b[CRYPTO_BYTES]; | |||
unsigned char pk[CRYPTO_PUBLICKEYBYTES]; | |||
@@ -72,38 +64,36 @@ int test_invalid_ciphertext() | |||
int i; | |||
size_t pos; | |||
for(i=0; i<NTESTS; i++) | |||
{ | |||
for (i = 0; i < NTESTS; i++) { | |||
randombytes((unsigned char *)&pos, sizeof(size_t)); | |||
//Alice generates a public key | |||
// Alice generates a public key | |||
crypto_kem_keypair(pk, sk_a); | |||
//Bob derives a secret key and creates a response | |||
// Bob derives a secret key and creates a response | |||
crypto_kem_enc(sendb, key_b, pk); | |||
//Change some byte in the ciphertext (i.e., encapsulated key) | |||
// Change some byte in the ciphertext (i.e., encapsulated key) | |||
sendb[pos % CRYPTO_CIPHERTEXTBYTES] ^= 23; | |||
//Alice uses Bobs response to get her secre key | |||
// Alice uses Bobs response to get her secre key | |||
crypto_kem_dec(key_a, sendb, sk_a); | |||
if(!memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
if (!memcmp(key_a, key_b, CRYPTO_BYTES)) | |||
printf("ERROR invalid ciphertext\n"); | |||
} | |||
return 0; | |||
} | |||
int main(void) | |||
{ | |||
int main(void) { | |||
test_keys(); | |||
test_invalid_sk_a(); | |||
test_invalid_ciphertext(); | |||
printf("CRYPTO_SECRETKEYBYTES: %d\n",CRYPTO_SECRETKEYBYTES); | |||
printf("CRYPTO_PUBLICKEYBYTES: %d\n",CRYPTO_PUBLICKEYBYTES); | |||
printf("CRYPTO_CIPHERTEXTBYTES: %d\n",CRYPTO_CIPHERTEXTBYTES); | |||
printf("CRYPTO_SECRETKEYBYTES: %d\n", CRYPTO_SECRETKEYBYTES); | |||
printf("CRYPTO_PUBLICKEYBYTES: %d\n", CRYPTO_PUBLICKEYBYTES); | |||
printf("CRYPTO_CIPHERTEXTBYTES: %d\n", CRYPTO_CIPHERTEXTBYTES); | |||
return 0; | |||
} |