📄 keccakpermutationreference.c
字号:
/*Algorithm Name: KeccakAuthors: Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van AsscheDate: January 9, 2009This code, originally by Guido Bertoni, Joan Daemen, Michaël Peeters andGilles Van Assche as a part of the SHA-3 submission, is hereby put in thepublic domain. It is given as is, without any guarantee.For more information, feedback or questions, please refer to our website:http://keccak.noekeon.org/*/#include <stdio.h>#include <string.h>#include "brg_endian.h"#include "displayIntermediateValues.h"#include "KeccakNISTInterface.h"#include "KeccakPermutationInterface.h"typedef unsigned char UINT8;typedef unsigned long long int UINT64;#define nrRounds 18UINT64 KeccakRoundConstants[nrRounds];#define nrWords 25unsigned int KeccakRhoOffsets[nrWords];void KeccakPermutationOnWords(UINT64 *state);void theta(UINT64 *A);void rho(UINT64 *A);void pi(UINT64 *A);void chi(UINT64 *A);void iota(UINT64 *A, unsigned int indexRound);void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state){ unsigned int i, j; for(i=0; i<(KeccakPermutationSize/64); i++) { stateAsWords[i] = 0; for(j=0; j<(64/8); j++) stateAsWords[i] |= (UINT64)(state[i*(64/8)+j]) << (8*j); }}void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords){ unsigned int i, j; for(i=0; i<(KeccakPermutationSize/64); i++) for(j=0; j<(64/8); j++) state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;}void KeccakPermutation(unsigned char *state){#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) UINT64 stateAsWords[KeccakPermutationSize/64];#endif displayStateAsBytes(1, "Input of permutation", state);#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) KeccakPermutationOnWords((UINT64*)state);#else fromBytesToWords(stateAsWords, state); KeccakPermutationOnWords(stateAsWords); fromWordsToBytes(state, stateAsWords);#endif displayStateAsBytes(1, "State after permutation", state);}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);}void KeccakPermutationOnWords(UINT64 *state){ unsigned int i; displayStateAsWords(3, "Same, as words", state); for(i=0; i<nrRounds; i++) { displayRoundNumber(3, i); theta(state); displayStateAsWords(3, "After theta", state); rho(state); displayStateAsWords(3, "After rho", state); pi(state); displayStateAsWords(3, "After pi", state); chi(state); displayStateAsWords(3, "After chi", state); iota(state, i); displayStateAsWords(3, "After iota", state); }}#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)]; D[x] = ROL64(C[x], 1); } for(x=0; x<5; x++) for(y=0; y<5; y++) A[index(x, y)] ^= D[(x+1)%5] ^ C[(x+4)%5];}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; unsigned int i, j, bitPosition; for(i=0; i<nrRounds; i++) { KeccakRoundConstants[i] = 0; for(j=0; j<7; j++) { bitPosition = (1<<j)-1; //2^j-1 if (LFSR86540(&LFSRstate)) KeccakRoundConstants[i] ^= (UINT64)1<<bitPosition; } }}void KeccakInitializeRhoOffsets(){ unsigned int x, y, t, newX, newY; KeccakRhoOffsets[index(0, 0)] = 0; x = 1; y = 0; for(t=0; t<24; t++) { KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % 64; newX = (0*x+1*y) % 5; newY = (2*x+3*y) % 5; x = newX; y = newY; }}void KeccakInitialize(){ KeccakInitializeRoundConstants(); KeccakInitializeRhoOffsets();}void displayRoundConstants(FILE *f){ unsigned int i; for(i=0; i<nrRounds; i++) { fprintf(f, "RC[%02i][0][0] = ", i); fprintf(f, "%08X", (KeccakRoundConstants[i] >> 32)); fprintf(f, "%08X", (KeccakRoundConstants[i] & 0xFFFFFFFFULL)); fprintf(f, "\n"); } fprintf(f, "\n");}void displayRhoOffsets(FILE *f){ unsigned int x, y; for(y=0; y<5; y++) for(x=0; x<5; x++) { fprintf(f, "RhoOffset[%i][%i] = ", x, y); fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]); fprintf(f, "\n"); } fprintf(f, "\n");}void KeccakInitializeState(unsigned char *state){ memset(state, 0, KeccakPermutationSizeInBytes);}void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data){ KeccakPermutationAfterXor(state, data, 128);}void KeccakAbsorb512bits(unsigned char *state, const unsigned char *data){ KeccakPermutationAfterXor(state, data, 64);}void KeccakExtract1024bits(const unsigned char *state, unsigned char *data){ memcpy(data, state, 128);}void KeccakExtract512bits(const unsigned char *state, unsigned char *data){ memcpy(data, state, 64);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -