Initialize Keccak before use

This commit is contained in:
Bill Cox
2017-03-26 08:26:15 -07:00
parent d10212367b
commit 3e406cfbb2
4 changed files with 105 additions and 99 deletions

View File

@@ -18,6 +18,7 @@ http://creativecommons.org/publicdomain/zero/1.0/
#define KeccakPermutationSize 1600 #define KeccakPermutationSize 1600
#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
void KeccakInitialize(void);
void KeccakInitializeState(unsigned char *state); void KeccakInitializeState(unsigned char *state);
void KeccakPermutation(unsigned char *state); void KeccakPermutation(unsigned char *state);
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount); void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount);

View File

@@ -20,18 +20,21 @@ typedef unsigned char UINT8;
typedef unsigned long long int UINT64; typedef unsigned long long int UINT64;
#define nrRounds 24 #define nrRounds 24
UINT64 KeccakRoundConstants[nrRounds]; static UINT64 KeccakRoundConstants[nrRounds];
#define nrLanes 25 #define nrLanes 25
unsigned int KeccakRhoOffsets[nrLanes]; static unsigned int KeccakRhoOffsets[nrLanes];
/*
void KeccakPermutationOnWords(UINT64 *state); void KeccakPermutationOnWords(UINT64 *state);
void theta(UINT64 *A); void theta(UINT64 *A);
void rho(UINT64 *A); void rho(UINT64 *A);
void pi(UINT64 *A); void pi(UINT64 *A);
void chi(UINT64 *A); void chi(UINT64 *A);
void iota(UINT64 *A, unsigned int indexRound); void iota(UINT64 *A, unsigned int indexRound);
*/
void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state) #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
static void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state)
{ {
unsigned int i, j; unsigned int i, j;
@@ -42,7 +45,7 @@ void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state)
} }
} }
void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords) static void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords)
{ {
unsigned int i, j; unsigned int i, j;
@@ -50,6 +53,97 @@ void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords)
for(j=0; j<(64/8); j++) for(j=0; j<(64/8); j++)
state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF; state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
} }
#endif
void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes)
{
unsigned int i;
for(i=0; i<dataLengthInBytes; i++)
state[i] ^= data[i];
KeccakPermutation(state);
}
#define index(x, y) (((x)%5)+5*((y)%5))
#define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
static void theta(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5], D[5];
for(x=0; x<5; x++) {
C[x] = 0;
for(y=0; y<5; y++)
C[x] ^= A[index(x, y)];
}
for(x=0; x<5; x++)
D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
for(x=0; x<5; x++)
for(y=0; y<5; y++)
A[index(x, y)] ^= D[x];
}
static void rho(UINT64 *A)
{
unsigned int x, y;
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
}
static void pi(UINT64 *A)
{
unsigned int x, y;
UINT64 tempA[25];
for(x=0; x<5; x++) for(y=0; y<5; y++)
tempA[index(x, y)] = A[index(x, y)];
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
}
static void chi(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5];
for(y=0; y<5; y++) {
for(x=0; x<5; x++)
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
for(x=0; x<5; x++)
A[index(x, y)] = C[x];
}
}
static void iota(UINT64 *A, unsigned int indexRound)
{
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
}
static int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
void KeccakPermutationOnWords(UINT64 *state)
{
unsigned int i;
for(i=0; i<nrRounds; i++) {
theta(state);
rho(state);
pi(state);
chi(state);
iota(state, i);
}
}
void KeccakPermutation(unsigned char *state) void KeccakPermutation(unsigned char *state)
{ {
@@ -66,97 +160,7 @@ void KeccakPermutation(unsigned char *state)
#endif #endif
} }
void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes) static void KeccakInitializeRoundConstants()
{
unsigned int i;
for(i=0; i<dataLengthInBytes; i++)
state[i] ^= data[i];
KeccakPermutation(state);
}
void KeccakPermutationOnWords(UINT64 *state)
{
unsigned int i;
for(i=0; i<nrRounds; i++) {
theta(state);
rho(state);
pi(state);
chi(state);
iota(state, i);
}
}
#define index(x, y) (((x)%5)+5*((y)%5))
#define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
void theta(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5], D[5];
for(x=0; x<5; x++) {
C[x] = 0;
for(y=0; y<5; y++)
C[x] ^= A[index(x, y)];
}
for(x=0; x<5; x++)
D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
for(x=0; x<5; x++)
for(y=0; y<5; y++)
A[index(x, y)] ^= D[x];
}
void rho(UINT64 *A)
{
unsigned int x, y;
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
}
void pi(UINT64 *A)
{
unsigned int x, y;
UINT64 tempA[25];
for(x=0; x<5; x++) for(y=0; y<5; y++)
tempA[index(x, y)] = A[index(x, y)];
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
}
void chi(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5];
for(y=0; y<5; y++) {
for(x=0; x<5; x++)
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
for(x=0; x<5; x++)
A[index(x, y)] = C[x];
}
}
void iota(UINT64 *A, unsigned int indexRound)
{
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
}
int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
void KeccakInitializeRoundConstants()
{ {
UINT8 LFSRstate = 0x01; UINT8 LFSRstate = 0x01;
unsigned int i, j, bitPosition; unsigned int i, j, bitPosition;
@@ -171,7 +175,7 @@ void KeccakInitializeRoundConstants()
} }
} }
void KeccakInitializeRhoOffsets() static void KeccakInitializeRhoOffsets()
{ {
unsigned int x, y, t, newX, newY; unsigned int x, y, t, newX, newY;
@@ -187,7 +191,7 @@ void KeccakInitializeRhoOffsets()
} }
} }
void KeccakInitialize() void KeccakInitialize(void)
{ {
KeccakInitializeRoundConstants(); KeccakInitializeRoundConstants();
KeccakInitializeRhoOffsets(); KeccakInitializeRhoOffsets();

View File

@@ -1,7 +1,7 @@
CFLAGS = -Wall -Wextra -Werror -std=c99 -O3 -I Keccak -I /usr/include/libftdi1 CFLAGS = -Wall -Wextra -Werror -std=c99 -O3 -I Keccak -I /usr/include/libftdi1
@_= $(shell ld -lftdi 2> /dev/null) FOUND = $(shell ldconfig -p | grep --silent libftdi.so && echo found)
ifeq ($$?, 0) ifeq ($(FOUND), found)
FTDI= -lftdi FTDI= -lftdi
else else
FTDI= -lftdi1 FTDI= -lftdi1

View File

@@ -251,6 +251,7 @@ int main(int argc, char **argv)
fputs("Can't intialize health checker\n", stderr); fputs("Can't intialize health checker\n", stderr);
return 1; return 1;
} }
KeccakInitialize();
uint8_t keccakState[KeccakPermutationSizeInBytes]; uint8_t keccakState[KeccakPermutationSizeInBytes];
KeccakInitializeState(keccakState); KeccakInitializeState(keccakState);