#include #include #include "brg_endian.h" #include "KeccakP-1600-SnP.h" #include "SnP-Relaned.h" #define USE_MEMSET /* #define DIVISION_INSTRUCTION */ /* comment if no division instruction or more compact when not using division */ #define UNROLL_CHILOOP /* comment more compact using for loop */ typedef unsigned char UINT8; typedef unsigned long long int UINT64; typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */ typedef UINT64 tKeccakLane; #if defined(_MSC_VER) #define ROL64(a, offset) _rotl64(a, offset) #elif defined(UseSHLD) #define ROL64(x,N) ({ \ register UINT64 __out; \ register UINT64 __in = x; \ __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ __out; \ }) #else #define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) #endif #define cKeccakNumberOfRounds 24 const UINT8 KeccakP1600_RotationConstants[25] = { 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 }; const UINT8 KeccakP1600_PiLane[25] = { 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 }; #if defined(DIVISION_INSTRUCTION) #define MOD5(argValue) ((argValue) % 5) #else const UINT8 KeccakP1600_Mod5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 }; #define MOD5(argValue) KeccakP1600_Mod5[argValue] #endif /* ---------------------------------------------------------------- */ static tKeccakLane KeccakF1600_GetNextRoundConstant( UINT8 *LFSR ); static tKeccakLane KeccakF1600_GetNextRoundConstant( UINT8 *LFSR ) { tSmallUInt i; tKeccakLane roundConstant; tSmallUInt doXOR; tSmallUInt tempLSFR; roundConstant = 0; tempLSFR = *LFSR; for(i=1; i<128; i <<= 1) { doXOR = tempLSFR & 1; if ((tempLSFR & 0x80) != 0) /* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */ tempLSFR = (tempLSFR << 1) ^ 0x71; else tempLSFR <<= 1; if ( doXOR != 0 ) roundConstant ^= (tKeccakLane)1ULL << (i - 1); } *LFSR = (UINT8)tempLSFR; return ( roundConstant ); } /* ---------------------------------------------------------------- */ void KeccakP1600_Initialize(void *argState) { #if defined(USE_MEMSET) memset( argState, 0, 25 * 8 ); #else tSmallUInt i; tKeccakLane *state; state = argState; i = 25; do { *(state++) = 0; } while ( --i != 0 ); #endif } /* ---------------------------------------------------------------- */ void KeccakP1600_AddBytesInLane(void *argState, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) { unsigned int i; #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) unsigned char * state = (unsigned char*)argState + lanePosition * sizeof(tKeccakLane) + offset; for(i=0; i>= offset*8; for(i=0; i>= 8; } #endif } /* ---------------------------------------------------------------- */ void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) { #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) memcpy(data, state, laneCount*8); #else tSmallUInt i, j; for(i=0; i> (8*j)) & 0xFF; } } #endif } /* ---------------------------------------------------------------- */ void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) { SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); } /* ---------------------------------------------------------------- */ void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) { tSmallUInt i; tKeccakLane lane = ((tKeccakLane*)state)[lanePosition]; lane >>= offset*8; for(i=0; i>= 8; } } /* ---------------------------------------------------------------- */ void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) { #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) tSmallUInt i; for(i=0; i> (8*j)) & 0xFF); } } #endif } /* ---------------------------------------------------------------- */ void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) { SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); } /* ---------------------------------------------------------------- */