/* The eXtended Keccak Code Package (XKCP) https://github.com/XKCP/XKCP The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche. Implementation by Ronny Van Keer, hereby denoted as "the implementer". For more information, feedback or questions, please refer to the Keccak Team website: https://keccak.team/ To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ --- This file implements Keccak-p[800] in a SnP-compatible way. Please refer to SnP-documentation.h for more details. This implementation comes with KeccakP-800-SnP.h in the same folder. Please refer to LowLevel.build for the exact list of other files it must be combined with. */ #include #include #include #include "brg_endian.h" #include "KeccakP-800-SnP.h" #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) #error Not yet implemented #endif #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 uint_fast8_t tSmallUInt; typedef uint32_t tKeccakLane; #if defined (__arm__) && !defined(__GNUC__) #define ROL32(a, offset) __ror(a, 32-(offset)) #elif defined(_MSC_VER) #define ROL32(a, offset) _rotl(a, offset) #else #define ROL32(a, offset) ((((uint32_t)a) << offset) ^ (((uint32_t)a) >> (32-offset))) #endif #define cKeccakNumberOfRounds 22 const uint8_t KeccakP800_RotationConstants[25] = { 1, 3, 6, 10, 15, 21, 28, 4, 13, 23, 2, 14, 27, 9, 24, 8, 25, 11, 30, 18, 7, 29, 20, 12 }; const uint8_t KeccakP800_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_t KeccakP800_Mod5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 }; #define MOD5(argValue) KeccakP800_Mod5[argValue] #endif /* ---------------------------------------------------------------- */ void KeccakP800_Initialize(void *argState) { #if defined(USE_MEMSET) memset( argState, 0, 25 * sizeof(tKeccakLane) ); #else tSmallUInt i; tKeccakLane *state; state = (tKeccakLane*)argState; i = 25; do { *(state++) = 0; } while ( --i != 0 ); #endif } /* ---------------------------------------------------------------- */ void KeccakP800_AddByte(void *state, unsigned char data, unsigned int offset) { ((unsigned char *)state)[offset] ^= data; } /* ---------------------------------------------------------------- */ void KeccakP800_AddBytes(void *argState, const unsigned char *data, unsigned int offset, unsigned int length) { tSmallUInt i; unsigned char * state = (unsigned char*)argState + offset; for(i=0; i