Browse Source

add .clang-format and formatted all the files

master
Matthias J. Kannwischer 5 years ago
parent
commit
39aba8ac24
28 changed files with 1588 additions and 1559 deletions
  1. +5
    -0
      .clang-format
  2. +4
    -0
      Makefile
  3. +400
    -421
      common/fips202.c
  4. +11
    -6
      common/fips202.h
  5. +28
    -19
      common/notrandombytes.c
  6. +1
    -1
      common/randombytes.h
  7. +223
    -211
      common/sha2.c
  8. +4
    -4
      common/sha2.h
  9. +7
    -5
      crypto_kem/kyber768/clean/api.h
  10. +60
    -64
      crypto_kem/kyber768/clean/cbd.c
  11. +1
    -1
      crypto_kem/kyber768/clean/cbd.h
  12. +181
    -185
      crypto_kem/kyber768/clean/indcpa.c
  13. +5
    -9
      crypto_kem/kyber768/clean/indcpa.h
  14. +86
    -66
      crypto_kem/kyber768/clean/kem.c
  15. +27
    -33
      crypto_kem/kyber768/clean/kex.c
  16. +9
    -10
      crypto_kem/kyber768/clean/kex.h
  17. +36
    -43
      crypto_kem/kyber768/clean/ntt.c
  18. +2
    -2
      crypto_kem/kyber768/clean/ntt.h
  19. +16
    -12
      crypto_kem/kyber768/clean/params.h
  20. +176
    -186
      crypto_kem/kyber768/clean/poly.c
  21. +6
    -6
      crypto_kem/kyber768/clean/poly.h
  22. +146
    -123
      crypto_kem/kyber768/clean/polyvec.c
  23. +2
    -2
      crypto_kem/kyber768/clean/polyvec.h
  24. +59
    -44
      crypto_kem/kyber768/clean/precomp.c
  25. +38
    -41
      crypto_kem/kyber768/clean/reduce.c
  26. +29
    -30
      crypto_kem/kyber768/clean/verify.c
  27. +2
    -1
      crypto_kem/kyber768/clean/verify.h
  28. +24
    -34
      crypto_kem/test.c

+ 5
- 0
.clang-format View File

@@ -0,0 +1,5 @@
---
Language: Cpp
BasedOnStyle: LLVM
...


+ 4
- 0
Makefile View File

@@ -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

+ 400
- 421
common/fips202.c View 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];
}


+ 11
- 6
common/fips202.h View File

@@ -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

+ 28
- 19
common/notrandombytes.c View File

@@ -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;
}


+ 1
- 1
common/randombytes.h View File

@@ -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

+ 223
- 211
common/sha2.c View File

@@ -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;
}

+ 4
- 4
common/sha2.h View File

@@ -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



+ 7
- 5
crypto_kem/kyber768/clean/api.h View File

@@ -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

+ 60
- 64
crypto_kem/kyber768/clean/cbd.c View File

@@ -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
- 1
crypto_kem/kyber768/clean/cbd.h View File

@@ -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);



+ 181
- 185
crypto_kem/kyber768/clean/indcpa.c View File

@@ -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);


+ 5
- 9
crypto_kem/kyber768/clean/indcpa.h View File

@@ -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

+ 86
- 66
crypto_kem/kyber768/clean/kem.c View File

@@ -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;
}

+ 27
- 33
crypto_kem/kyber768/clean/kex.c View File

@@ -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);
}

+ 9
- 10
crypto_kem/kyber768/clean/kex.h View File

@@ -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

+ 36
- 43
crypto_kem/kyber768/clean/ntt.c View File

@@ -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]));
}

+ 2
- 2
crypto_kem/kyber768/clean/ntt.h View File

@@ -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

+ 16
- 12
crypto_kem/kyber768/clean/params.h View File

@@ -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

+ 176
- 186
crypto_kem/kyber768/clean/poly.c View File

@@ -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;
}
}


+ 6
- 6
crypto_kem/kyber768/clean/poly.h View File

@@ -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);



+ 146
- 123
crypto_kem/kyber768/clean/polyvec.c View File

@@ -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]);

}

+ 2
- 2
crypto_kem/kyber768/clean/polyvec.h View File

@@ -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);


+ 59
- 44
crypto_kem/kyber768/clean/precomp.c View File

@@ -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};

+ 38
- 41
crypto_kem/kyber768/clean/reduce.c View File

@@ -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;
}

+ 29
- 30
crypto_kem/kyber768/clean/verify.c View File

@@ -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]);
}

+ 2
- 1
crypto_kem/kyber768/clean/verify.h View File

@@ -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

+ 24
- 34
crypto_kem/test.c View File

@@ -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;
}

Loading…
Cancel
Save