diff --git a/crypto/SHA-3/SnP/KeccakP-1600-compact64.c b/crypto/SHA-3/SnP/KeccakP-1600-compact64.c new file mode 100644 index 00000000..1c9f3feb --- /dev/null +++ b/crypto/SHA-3/SnP/KeccakP-1600-compact64.c @@ -0,0 +1,397 @@ +#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); +} + +/* ---------------------------------------------------------------- */