diff options
| author | J08nY | 2019-11-25 17:45:35 +0100 |
|---|---|---|
| committer | J08nY | 2019-11-25 17:45:35 +0100 |
| commit | 8a56c7a95e662862cfe78b834ccb091e95d5372f (patch) | |
| tree | 1fd57480b7fc681f00c0bfb6c0e5cfea86762f87 /pyecsca/codegen/prng | |
| parent | c8d0bff46001bd5636825c5b0bb4c896cb34a4e6 (diff) | |
| download | pyecsca-codegen-8a56c7a95e662862cfe78b834ccb091e95d5372f.tar.gz pyecsca-codegen-8a56c7a95e662862cfe78b834ccb091e95d5372f.tar.zst pyecsca-codegen-8a56c7a95e662862cfe78b834ccb091e95d5372f.zip | |
Add libtommath, HOST build, and a simple PRNG.
Diffstat (limited to 'pyecsca/codegen/prng')
| -rw-r--r-- | pyecsca/codegen/prng/KeccakDuplex-common.h | 37 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakDuplex.inc | 192 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakDuplexWidth200.c | 29 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakDuplexWidth200.h | 25 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakP-200-SnP.h | 34 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakP-200-compact.c | 185 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakPRG-common.h | 28 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakPRG.h | 20 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakPRG.inc | 123 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakPRGWidth200.c | 22 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/KeccakPRGWidth200.h | 24 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/align.h | 32 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/prng.c | 28 | ||||
| -rw-r--r-- | pyecsca/codegen/prng/prng.h | 8 |
14 files changed, 787 insertions, 0 deletions
diff --git a/pyecsca/codegen/prng/KeccakDuplex-common.h b/pyecsca/codegen/prng/KeccakDuplex-common.h new file mode 100644 index 0000000..6371611 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplex-common.h @@ -0,0 +1,37 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _KeccakDuplexCommon_h_ +#define _KeccakDuplexCommon_h_ + +#include "align.h" + +#define KCP_DeclareDuplexStructure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_DuplexInstanceStruct { \ + unsigned char state[size]; \ + unsigned int rate; \ + unsigned int byteInputIndex; \ + unsigned int byteOutputIndex; \ + } prefix##_DuplexInstance; + +#define KCP_DeclareDuplexFunctions(prefix) \ + int prefix##_DuplexInitialize(prefix##_DuplexInstance *duplexInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_Duplexing(prefix##_DuplexInstance *duplexInstance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd); \ + int prefix##_DuplexingFeedPartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingFeedZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwritePartialInput(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_DuplexingOverwriteWithZeroes(prefix##_DuplexInstance *duplexInstance, unsigned int inputByteLen); \ + int prefix##_DuplexingGetFurtherOutput(prefix##_DuplexInstance *duplexInstance, unsigned char *out, unsigned int outByteLen); \ + int prefix##_DuplexingGetFurtherOutputAndAdd(prefix##_DuplexInstance *duplexInstance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen); + +#endif diff --git a/pyecsca/codegen/prng/KeccakDuplex.inc b/pyecsca/codegen/prng/KeccakDuplex.inc new file mode 100644 index 0000000..bd58043 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplex.inc @@ -0,0 +1,192 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define DuplexInstance JOIN(prefix, _DuplexInstance) +#define DuplexInitialize JOIN(prefix, _DuplexInitialize) +#define Duplexing JOIN(prefix, _Duplexing) +#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput) +#define DuplexingFeedZeroes JOIN(prefix, _DuplexingFeedZeroes) +#define DuplexingOverwritePartialInput JOIN(prefix, _DuplexingOverwritePartialInput) +#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes) +#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput) +#define DuplexingGetFurtherOutputAndAdd JOIN(prefix, _DuplexingGetFurtherOutputAndAdd) + +#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) +#define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) +#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) +#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) + +int DuplexInitialize(DuplexInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 2) || (rate > SnP_width)) + return 1; + SnP_StaticInitialize(); + instance->rate = rate; + SnP_Initialize(instance->state); + instance->byteInputIndex = 0; + instance->byteOutputIndex = (instance->rate+7)/8; + return 0; +} + +int Duplexing(DuplexInstance *instance, const unsigned char *sigmaBegin, unsigned int sigmaBeginByteLen, unsigned char *Z, unsigned int ZByteLen, unsigned char delimitedSigmaEnd) +{ + const unsigned int rho_max = instance->rate - 2; + + if (delimitedSigmaEnd == 0) + return 1; + if ((instance->byteInputIndex+sigmaBeginByteLen)*8 > rho_max) + return 1; + if (rho_max - sigmaBeginByteLen*8 < 7) { + unsigned int maxBitsInDelimitedSigmaEnd = rho_max - sigmaBeginByteLen*8; + if (delimitedSigmaEnd >= (1 << (maxBitsInDelimitedSigmaEnd+1))) + return 1; + } + if (ZByteLen > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_AddBytes(instance->state, sigmaBegin, instance->byteInputIndex, sigmaBeginByteLen); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memcpy(block, sigmaBegin, sigmaBeginByteLen); + block[sigmaBeginByteLen] = delimitedSigmaEnd; + memset(block+sigmaBeginByteLen+1, 0, sizeof(block)-sigmaBeginByteLen-1); + block[(instance->rate-1)/8] |= 1 << ((instance->rate-1) % 8); + displayBytes(1, "Block to be absorbed (after padding)", block, (instance->rate+7)/8); + } + #endif + + /* Last few bits, whose delimiter coincides with first bit of padding */ + SnP_AddByte(instance->state, delimitedSigmaEnd, instance->byteInputIndex+sigmaBeginByteLen); + /* Second bit of padding */ + SnP_AddByte(instance->state, (unsigned char)1 << ((instance->rate - 1)%8), (instance->rate - 1)/8); + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, Z, 0, ZByteLen); + + if (ZByteLen*8 > instance->rate) { + unsigned char mask = (unsigned char)(1 << (instance->rate % 8)) - 1; + Z[ZByteLen-1] &= mask; + } + + instance->byteInputIndex = 0; + instance->byteOutputIndex = ZByteLen; + + return 0; +} + +int DuplexingFeedPartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_AddBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingFeedZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwritePartialInput(DuplexInstance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex+inputByteLen)*8 > rho_max) + return 1; + + SnP_OverwriteBytes(instance->state, input, instance->byteInputIndex, inputByteLen); + instance->byteInputIndex += inputByteLen; + return 0; +} + +int DuplexingOverwriteWithZeroes(DuplexInstance *instance, unsigned int inputByteLen) +{ + const unsigned int rho_max = instance->rate - 2; + + if ((instance->byteInputIndex != 0) || (inputByteLen*8 > rho_max)) + return 1; + + SnP_OverwriteWithZeroes(instance->state, inputByteLen); + instance->byteInputIndex = inputByteLen; + + return 0; +} + +int DuplexingGetFurtherOutput(DuplexInstance *instance, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractBytes(instance->state, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +int DuplexingGetFurtherOutputAndAdd(DuplexInstance *instance, const unsigned char *input, unsigned char *output, unsigned int outputByteLen) +{ + if ((outputByteLen+instance->byteOutputIndex) > (instance->rate+7)/8) + return 1; /* The output length must not be greater than the rate (rounded up to a byte) */ + + SnP_ExtractAndAddBytes(instance->state, input, output, instance->byteOutputIndex, outputByteLen); + instance->byteOutputIndex += outputByteLen; + if (instance->byteOutputIndex*8 > instance->rate) { + unsigned char mask = (1 << (instance->rate % 8)) - 1; + output[outputByteLen-1] &= mask; + } + return 0; +} + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingFeedZeroes +#undef DuplexingOverwritePartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexingGetFurtherOutputAndAdd +#undef SnP_stateSizeInBytes +#undef SnP_stateAlignment +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_OverwriteBytes +#undef SnP_OverwriteWithZeroes +#undef SnP_ExtractBytes +#undef SnP_ExtractAndAddBytes diff --git a/pyecsca/codegen/prng/KeccakDuplexWidth200.c b/pyecsca/codegen/prng/KeccakDuplexWidth200.c new file mode 100644 index 0000000..d6f56d2 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplexWidth200.c @@ -0,0 +1,29 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#include "KeccakDuplexWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #include "KeccakDuplex.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/pyecsca/codegen/prng/KeccakDuplexWidth200.h b/pyecsca/codegen/prng/KeccakDuplexWidth200.h new file mode 100644 index 0000000..8bb76f4 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakDuplexWidth200.h @@ -0,0 +1,25 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _KeccakDuplexWidth200_h_ +#define _KeccakDuplexWidth200_h_ + +#include "KeccakDuplex-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareDuplexStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareDuplexFunctions(KeccakWidth200) +#endif + +#endif diff --git a/pyecsca/codegen/prng/KeccakP-200-SnP.h b/pyecsca/codegen/prng/KeccakP-200-SnP.h new file mode 100644 index 0000000..4acf932 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakP-200-SnP.h @@ -0,0 +1,34 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ + +--- + +Please refer to SnP-documentation.h for more details. +*/ + +#ifndef _KeccakP_200_SnP_h_ +#define _KeccakP_200_SnP_h_ + +#define KeccakP200_implementation "8-bit compact implementation" +#define KeccakP200_stateSizeInBytes 25 +#define KeccakP200_stateAlignment 1 + +#define KeccakP200_StaticInitialize() +void KeccakP200_Initialize(void *state); +void KeccakP200_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP200_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP200_Permute_Nrounds(void *state, unsigned int nrounds); +void KeccakP200_Permute_18rounds(void *state); +void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP200_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/pyecsca/codegen/prng/KeccakP-200-compact.c b/pyecsca/codegen/prng/KeccakP-200-compact.c new file mode 100644 index 0000000..42c972b --- /dev/null +++ b/pyecsca/codegen/prng/KeccakP-200-compact.c @@ -0,0 +1,185 @@ +/* +Implementation by Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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[200] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-200-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include <string.h> +#include <stdlib.h> +#include "KeccakP-200-SnP.h" + +// #define DIVISION_INSTRUCTION /* comment if no division instruction or more compact when not using division */ +#define UNROLL_CHILOOP /* comment if more compact using for loop */ + +typedef unsigned char UINT8; +typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */ +typedef UINT8 tKeccakLane; + +#define ROL8(a, offset) (UINT8)((((UINT8)a) << (offset&7)) ^ (((UINT8)a) >> (8-(offset&7)))) + +const UINT8 KeccakP200_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 KeccakP200_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 KeccakP200_Mod5[10] = +{ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 +}; +#define MOD5(argValue) KeccakP200_Mod5[argValue] +#endif + +const UINT8 KeccakF200_RoundConstants[] = +{ + 0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80 +}; + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Initialize(void *argState) +{ + memset( argState, 0, 25 * sizeof(tKeccakLane) ); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddByte(void *argState, unsigned char byte, unsigned int offset) +{ + ((tKeccakLane*)argState)[offset] ^= byte; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_AddBytes(void *argState, const unsigned char *data, unsigned int offset, unsigned int length) +{ + tSmallUInt i; + tKeccakLane * state = (tKeccakLane*)argState + offset; + for(i=0; i<length; i++) + state[i] ^= data[i]; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + memcpy((unsigned char*)state+offset, data, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_OverwriteWithZeroes(void *state, unsigned int byteCount) +{ + memset(state, 0, byteCount); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Permute_Nrounds(void *argState, unsigned int nr) +{ + tSmallUInt x, y; + tKeccakLane temp; + tKeccakLane BC[5]; + tKeccakLane *state; + const tKeccakLane *rc; + + state = (tKeccakLane*)argState; + rc = KeccakF200_RoundConstants + 18 - nr; + do + { + /* Theta */ + for ( x = 0; x < 5; ++x ) + { + BC[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^ state[15 + x] ^ state[20 + x]; + } + for ( x = 0; x < 5; ++x ) + { + temp = BC[MOD5(x+4)] ^ ROL8(BC[MOD5(x+1)], 1); + for ( y = 0; y < 25; y += 5 ) + { + state[y + x] ^= temp; + } + } + + /* Rho Pi */ + temp = state[1]; + for ( x = 0; x < 24; ++x ) + { + BC[0] = state[KeccakP200_PiLane[x]]; + state[KeccakP200_PiLane[x]] = ROL8( temp, KeccakP200_RotationConstants[x] ); + temp = BC[0]; + } + + /* Chi */ + for ( y = 0; y < 25; y += 5 ) + { +#if defined(UNROLL_CHILOOP) + BC[0] = state[y + 0]; + BC[1] = state[y + 1]; + BC[2] = state[y + 2]; + BC[3] = state[y + 3]; + BC[4] = state[y + 4]; +#else + for ( x = 0; x < 5; ++x ) + { + BC[x] = state[y + x]; + } +#endif + for ( x = 0; x < 5; ++x ) + { + state[y + x] = BC[x] ^((~BC[MOD5(x+1)]) & BC[MOD5(x+2)]); + } + } + + /* Iota */ + temp = *(rc++); + state[0] ^= temp; + } + while( temp != 0x80 ); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_Permute_18rounds(void *argState) +{ + KeccakP200_Permute_Nrounds(argState, 18); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + memcpy(data, (UINT8*)state+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP200_ExtractAndAddBytes(const void *argState, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + unsigned int i; + tKeccakLane * state = (tKeccakLane*)argState + offset; + for(i=0; i<length; i++) + output[i] = input[i] ^ state[i]; +} + +/* ---------------------------------------------------------------- */ diff --git a/pyecsca/codegen/prng/KeccakPRG-common.h b/pyecsca/codegen/prng/KeccakPRG-common.h new file mode 100644 index 0000000..eca5d2e --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG-common.h @@ -0,0 +1,28 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _KeccakPRGCommon_h_ +#define _KeccakPRGCommon_h_ + +#include "align.h" + +#define KCP_DeclareSpongePRG_Structure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_SpongePRG_InstanceStruct { \ + prefix##_DuplexInstance duplex; \ + } prefix##_SpongePRG_Instance; + +#define KCP_DeclareSpongePRG_Functions(prefix) \ + int prefix##_SpongePRG_Initialize(prefix##_SpongePRG_Instance *instance, unsigned int capacity); \ + int prefix##_SpongePRG_Feed(prefix##_SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen); \ + int prefix##_SpongePRG_Fetch(prefix##_SpongePRG_Instance *Instance, unsigned char *out, unsigned int outByteLen); \ + int prefix##_SpongePRG_Forget(prefix##_SpongePRG_Instance *instance); + +#endif diff --git a/pyecsca/codegen/prng/KeccakPRG.h b/pyecsca/codegen/prng/KeccakPRG.h new file mode 100644 index 0000000..83a2144 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG.h @@ -0,0 +1,20 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _KeccakPRG_h_ +#define _KeccakPRG_h_ + +/* For the documentation, please follow the link: */ +/* #include "KeccakPRG-documentation.h" */ + +#include "KeccakPRGWidth200.h" + +#endif diff --git a/pyecsca/codegen/prng/KeccakPRG.inc b/pyecsca/codegen/prng/KeccakPRG.inc new file mode 100644 index 0000000..aa65db0 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRG.inc @@ -0,0 +1,123 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define SpongePRG_Instance JOIN(prefix, _SpongePRG_Instance) +#define SpongePRG_Initialize JOIN(prefix, _SpongePRG_Initialize) +#define SpongePRG_Feed JOIN(prefix, _SpongePRG_Feed) +#define SpongePRG_Fetch JOIN(prefix, _SpongePRG_Fetch) +#define SpongePRG_Forget JOIN(prefix, _SpongePRG_Forget) + +#define DuplexInstance JOIN(prefix, _DuplexInstance) +#define DuplexInitialize JOIN(prefix, _DuplexInitialize) +#define Duplexing JOIN(prefix, _Duplexing) +#define DuplexingFeedPartialInput JOIN(prefix, _DuplexingFeedPartialInput) +#define DuplexingOverwriteWithZeroes JOIN(prefix, _DuplexingOverwriteWithZeroes) +#define DuplexingGetFurtherOutput JOIN(prefix, _DuplexingGetFurtherOutput) +#define DuplexGetInputIndex(duplex) (duplex)->byteInputIndex +#define DuplexGetOutputIndex(duplex) (duplex)->byteOutputIndex +#define DuplexSetOutputIndex(duplex, i) (duplex)->byteOutputIndex = (i) + +int SpongePRG_Initialize(SpongePRG_Instance *instance, unsigned int capacity) +{ + unsigned int rate; + unsigned int rhoInBytes; + + if (capacity > (SnP_width-10)) + return 1; + + rate = SnP_width - capacity; + rhoInBytes = (rate-2)/8; + + if ( (rhoInBytes == 0) || (rhoInBytes >= SnP_width/8) ) + return 1; + return DuplexInitialize(&instance->duplex, rate, capacity); +} + +int SpongePRG_Feed(SpongePRG_Instance *instance, const unsigned char *input, unsigned int inputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + while( !error && ((DuplexGetInputIndex(&instance->duplex) + inputByteLen) >= rhoInBytes)) { + unsigned int localSize = rhoInBytes - DuplexGetInputIndex(&instance->duplex); + error |= DuplexingFeedPartialInput(&instance->duplex, input, localSize); + error |= Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + input += localSize; + inputByteLen -= localSize; + } + if (!error) + error = DuplexingFeedPartialInput(&instance->duplex, input, inputByteLen); + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +int SpongePRG_Fetch(SpongePRG_Instance *instance, unsigned char *output, unsigned int outputByteLen) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + int error = 0; + + if (DuplexGetOutputIndex(&instance->duplex) < rhoInBytes) { + unsigned int localSize = rhoInBytes - DuplexGetOutputIndex(&instance->duplex); + localSize = (localSize <= outputByteLen) ? localSize : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + + while( !error && (outputByteLen > 0) ) { + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if (!error) { + unsigned int localSize = (rhoInBytes <= outputByteLen) ? rhoInBytes : outputByteLen; + error = DuplexingGetFurtherOutput(&instance->duplex, output, localSize); + output += localSize; + outputByteLen -= localSize; + } + } + return error; +} + +int SpongePRG_Forget(SpongePRG_Instance *instance) +{ + unsigned int rhoInBytes = (instance->duplex.rate-2)/8; + unsigned int capacity = SnP_width - instance->duplex.rate; + int error; + + if ((rhoInBytes*8) < capacity) + return 1; + + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + if ( !error ) { + error = DuplexingOverwriteWithZeroes(&instance->duplex, rhoInBytes); + if ( !error ) + error = Duplexing(&instance->duplex, 0, 0, 0, 0, 0x01); + } + DuplexSetOutputIndex(&instance->duplex, rhoInBytes); + return error; +} + +#undef SpongePRG_Instance +#undef SpongePRG_Initialize +#undef SpongePRG_Feed +#undef SpongePRG_Fetch +#undef SpongePRG_Forget + +#undef DuplexInstance +#undef DuplexInitialize +#undef Duplexing +#undef DuplexingFeedPartialInput +#undef DuplexingOverwriteWithZeroes +#undef DuplexingGetFurtherOutput +#undef DuplexGetInputIndex +#undef DuplexGetOutputIndex +#undef DuplexSetOutputIndex diff --git a/pyecsca/codegen/prng/KeccakPRGWidth200.c b/pyecsca/codegen/prng/KeccakPRGWidth200.c new file mode 100644 index 0000000..067375e --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRGWidth200.c @@ -0,0 +1,22 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#include "KeccakPRGWidth200.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP_width 200 + #include "KeccakPRG.inc" + #undef prefix + #undef SnP_width +#endif diff --git a/pyecsca/codegen/prng/KeccakPRGWidth200.h b/pyecsca/codegen/prng/KeccakPRGWidth200.h new file mode 100644 index 0000000..d7cfcc9 --- /dev/null +++ b/pyecsca/codegen/prng/KeccakPRGWidth200.h @@ -0,0 +1,24 @@ +/* +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _KeccakPRGWidth200_h_ +#define _KeccakPRGWidth200_h_ + +#include "KeccakDuplexWidth200.h" +#include "KeccakPRG-common.h" + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" + KCP_DeclareSpongePRG_Structure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongePRG_Functions(KeccakWidth200) +#endif + +#endif diff --git a/pyecsca/codegen/prng/align.h b/pyecsca/codegen/prng/align.h new file mode 100644 index 0000000..90c1b37 --- /dev/null +++ b/pyecsca/codegen/prng/align.h @@ -0,0 +1,32 @@ +/* +Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, +Michaël Peeters, Gilles Van Assche and Ronny Van Keer, +hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to our 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/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/pyecsca/codegen/prng/prng.c b/pyecsca/codegen/prng/prng.c new file mode 100644 index 0000000..934fe72 --- /dev/null +++ b/pyecsca/codegen/prng/prng.c @@ -0,0 +1,28 @@ +#include "KeccakPRG.h" +#include "KeccakP-200-compact.c" +#include "KeccakDuplexWidth200.c" +#include "KeccakPRGWidth200.c" +#include "prng.h" +#include <tommath.h> + + +static KeccakWidth200_SpongePRG_Instance keccak; + +mp_err prng_mp_rand(void *out, size_t size) { + return (prng_get(out, size) == 0) ? MP_OKAY : MP_ERR; +} + +void prng_init(void) { + KeccakWidth200_SpongePRG_Initialize(&keccak, 70); + mp_rand_source(prng_mp_rand); +} + +int prng_get(uint8_t *out, size_t size) { + return KeccakWidth200_SpongePRG_Fetch(&keccak, out, size); +} + +void prng_seed(uint8_t *seed, size_t size) { + KeccakWidth200_SpongePRG_Feed(&keccak, seed, size); + KeccakWidth200_SpongePRG_Forget(&keccak); +} + diff --git a/pyecsca/codegen/prng/prng.h b/pyecsca/codegen/prng/prng.h new file mode 100644 index 0000000..b399a6c --- /dev/null +++ b/pyecsca/codegen/prng/prng.h @@ -0,0 +1,8 @@ +#include <stdint.h> + +void prng_init(void); + +int prng_get(uint8_t *out, size_t size); + +void prng_seed(uint8_t *seed, size_t size); + |
