aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/codegen')
-rw-r--r--pyecsca/codegen/Makefile10
-rw-r--r--pyecsca/codegen/bn.c9
-rw-r--r--pyecsca/codegen/bn.h12
-rw-r--r--pyecsca/codegen/coords.h8
-rw-r--r--pyecsca/codegen/curve.h4
-rw-r--r--pyecsca/codegen/formulas.h12
-rw-r--r--pyecsca/codegen/hal/Makefile.hal5
-rw-r--r--pyecsca/codegen/hal/hal.h3
-rw-r--r--pyecsca/codegen/hal/host/Makefile.host10
-rw-r--r--pyecsca/codegen/hal/host/host_hal.c2
-rw-r--r--pyecsca/codegen/hal/host/host_hal.h14
-rw-r--r--pyecsca/codegen/hal/host/uart.c7
-rw-r--r--pyecsca/codegen/hal/host/uart.h13
-rw-r--r--pyecsca/codegen/hash/sha1.c2
-rw-r--r--pyecsca/codegen/hash/sha2.c2
-rw-r--r--pyecsca/codegen/main.c14
-rw-r--r--pyecsca/codegen/mult/double_and_add.c15
-rw-r--r--pyecsca/codegen/prng/KeccakDuplex-common.h37
-rw-r--r--pyecsca/codegen/prng/KeccakDuplex.inc192
-rw-r--r--pyecsca/codegen/prng/KeccakDuplexWidth200.c29
-rw-r--r--pyecsca/codegen/prng/KeccakDuplexWidth200.h25
-rw-r--r--pyecsca/codegen/prng/KeccakP-200-SnP.h34
-rw-r--r--pyecsca/codegen/prng/KeccakP-200-compact.c185
-rw-r--r--pyecsca/codegen/prng/KeccakPRG-common.h28
-rw-r--r--pyecsca/codegen/prng/KeccakPRG.h20
-rw-r--r--pyecsca/codegen/prng/KeccakPRG.inc123
-rw-r--r--pyecsca/codegen/prng/KeccakPRGWidth200.c22
-rw-r--r--pyecsca/codegen/prng/KeccakPRGWidth200.h24
-rw-r--r--pyecsca/codegen/prng/align.h32
-rw-r--r--pyecsca/codegen/prng/prng.c28
-rw-r--r--pyecsca/codegen/prng/prng.h8
-rw-r--r--pyecsca/codegen/simpleserial/simpleserial.c12
32 files changed, 912 insertions, 29 deletions
diff --git a/pyecsca/codegen/Makefile b/pyecsca/codegen/Makefile
index 50c1940..d99a1ce 100644
--- a/pyecsca/codegen/Makefile
+++ b/pyecsca/codegen/Makefile
@@ -1,12 +1,14 @@
TARGET = pyecsca-codegen
-SRC += main.c ecdh.c ecdsa.c hash/hash.c
+SRC += main.c bn.c ecdh.c ecdsa.c hash/hash.c prng/prng.c
-CDEFS += -DHASH=HASH_SHA1
+CDEFS += -DHASH=HASH_SHA224
-MKDIR_LIST += hash
+MKDIR_LIST += hash prng
-EXTRAINCDIRS += hash
+EXTRAINCDIRS += hash prng ../../ext/libtommath/
+
+LDFLAGS += ../../ext/libtommath/libtommath.a
include simpleserial/Makefile.simpleserial
diff --git a/pyecsca/codegen/bn.c b/pyecsca/codegen/bn.c
new file mode 100644
index 0000000..dfd433a
--- /dev/null
+++ b/pyecsca/codegen/bn.c
@@ -0,0 +1,9 @@
+#include "bn.h"
+
+bn_err bn_init(bn_t *bn) {
+ return mp_init(bn);
+}
+
+void bn_clear(bn_t *bn) {
+ mp_clear(bn);
+} \ No newline at end of file
diff --git a/pyecsca/codegen/bn.h b/pyecsca/codegen/bn.h
index 01519c1..ff0ba37 100644
--- a/pyecsca/codegen/bn.h
+++ b/pyecsca/codegen/bn.h
@@ -1,17 +1,18 @@
#ifndef BN_H_
#define BN_H_
-//bn_t definition is variable
-//BN_SIZE definition is variable
+#include <tommath.h>
+
+#define bn_t mp_int
+#define bn_err mp_err
typedef struct {
char name;
bn_t value;
} named_bn_t;
-//heap based
-bn_t *bn_new();
-void bn_free(bn_t *bn);)
+bn_err bn_init(bn_t *bn);
+void bn_clear(bn_t *bn);
int bn_from_hex(const char *data, bn_t *out);
int bn_from_int(uint64_t value, bn_t *out);
@@ -22,5 +23,6 @@ void bn_mod_div(bn_t *one, bn_t *other, bn_t *mod, bn_t *out);
void bn_mod_inv(bn_t *one, bn_t *mod, bn_t *out);
int bn_get_bit(bn_t *bn, int which);
void bn_set_bit(bn_t *bn, int which, int value);
+int bn_bit_length(bn_t *bn);
#endif //BN_H_ \ No newline at end of file
diff --git a/pyecsca/codegen/coords.h b/pyecsca/codegen/coords.h
index 9f3323d..751aeb6 100644
--- a/pyecsca/codegen/coords.h
+++ b/pyecsca/codegen/coords.h
@@ -10,6 +10,14 @@ typedef struct {
} point_t;
*/
+point_t *point_new();
+
+point_t *point_copy(const point_t *from);
+
+void point_set(const point_t *from, point_t *out);
+
+void point_free(point_t *point);
+
int point_to_affine(point_t *point, const char coord, curve_t *curve, bn_t *out);
int point_from_affine(bn_t *x, bn_t *y, curve_t *curve, point_t *out);
diff --git a/pyecsca/codegen/curve.h b/pyecsca/codegen/curve.h
index 5ac7b1a..81eb526 100644
--- a/pyecsca/codegen/curve.h
+++ b/pyecsca/codegen/curve.h
@@ -4,8 +4,8 @@
//curve_t definition is variable
/*
typedef struct {
- bn_t a;
- bn_t b;
+ bn_t n;
+ point_t *neutral;
} curve_t;
*/
diff --git a/pyecsca/codegen/formulas.h b/pyecsca/codegen/formulas.h
index 1566f98..6cd6120 100644
--- a/pyecsca/codegen/formulas.h
+++ b/pyecsca/codegen/formulas.h
@@ -1,16 +1,16 @@
#ifndef FORMULAS_H_
#define FORMULAS_H_
-int point_add(point_t *one, point_t *other, curve_t *curve, point_t *out);
+int point_add(const point_t *one, const point_t *other, const curve_t *curve, point_t *out);
-int point_dbl(point_t *one, curve_t *curve, point_t *out);
+int point_dbl(const point_t *one, const curve_t *curve, point_t *out);
-int point_neg(point_t *one, curve_t *curve, point_t *out);
+int point_neg(const point_t *one, const curve_t *curve, point_t *out);
-int point_scl(point_t *one, curve_t *curve, point_t *out);
+int point_scl(const point_t *one, const curve_t *curve, point_t *out);
-int point_dadd(point_t *one, point_t *other, point_t *diff, curve_t *curve, point_t *out);
+int point_dadd(const point_t *one, const point_t *other, const point_t *diff, const curve_t *curve, point_t *out);
-int point_ldr(point_t *one, point_t *other, point_t *diff, curve_t *curve, point_t *out_one, point_t *out_other);
+int point_ldr(const point_t *one, const point_t *other, const point_t *diff, const curve_t *curve, point_t *out_one, point_t *out_other);
#endif //FORMULAS_H_ \ No newline at end of file
diff --git a/pyecsca/codegen/hal/Makefile.hal b/pyecsca/codegen/hal/Makefile.hal
index 14d4c97..3c81d00 100644
--- a/pyecsca/codegen/hal/Makefile.hal
+++ b/pyecsca/codegen/hal/Makefile.hal
@@ -20,6 +20,8 @@ define KNOWN_PLATFORMS
+-------------------------------------------------------+
| CW308_STM32F3 | CW308T-STM32F3 (ST Micro STM32F3) |
+-------------------------------------------------------+
+| HOST | Host machine |
++-------------------------------------------------------+
endef
@@ -44,6 +46,9 @@ else ifeq ($(PLATFORM),CW308_STM32F0)
else ifeq ($(PLATFORM),CW308_STM32F3)
HAL = stm32f3
PLTNAME = CW308T: STM32F3 Target
+else ifeq ($(PLATFORM),HOST)
+ HAL = host
+ PLTNAME = HOST: Host machine target
else
$(error Invalid or empty PLATFORM: $(PLATFORM). Known platforms: $(KNOWN_PLATFORMS))
endif
diff --git a/pyecsca/codegen/hal/hal.h b/pyecsca/codegen/hal/hal.h
index 831276f..b14dacf 100644
--- a/pyecsca/codegen/hal/hal.h
+++ b/pyecsca/codegen/hal/hal.h
@@ -24,6 +24,7 @@ void platform_init(void);
#define HAL_xmega 1
#define HAL_stm32f0 2
#define HAL_stm32f3 3
+#define HAL_host 4
#if HAL == HAL_xmega
#include <avr/io.h>
@@ -34,6 +35,8 @@ void platform_init(void);
#include "stm32f0/stm32f0_hal.h"
#elif HAL == HAL_stm32f3
#include "stm32f3/stm32f3_hal.h"
+#elif HAL == HAL_host
+ #include "host/host_hal.h"
#else
#error "Unsupported HAL Type"
#endif
diff --git a/pyecsca/codegen/hal/host/Makefile.host b/pyecsca/codegen/hal/host/Makefile.host
new file mode 100644
index 0000000..933c899
--- /dev/null
+++ b/pyecsca/codegen/hal/host/Makefile.host
@@ -0,0 +1,10 @@
+VPATH += :$(HALPATH)/host
+SRC += uart.c host_hal.c
+EXTRAINCDIRS += $(HALPATH)/host
+
+CC = gcc
+OBJCOPY = objcopy
+OBJDUMP = objdump
+SIZE = size
+AR = ar rcs
+NM = nm \ No newline at end of file
diff --git a/pyecsca/codegen/hal/host/host_hal.c b/pyecsca/codegen/hal/host/host_hal.c
new file mode 100644
index 0000000..fe71aab
--- /dev/null
+++ b/pyecsca/codegen/hal/host/host_hal.c
@@ -0,0 +1,2 @@
+
+void platform_init(void) {} \ No newline at end of file
diff --git a/pyecsca/codegen/hal/host/host_hal.h b/pyecsca/codegen/hal/host/host_hal.h
new file mode 100644
index 0000000..b78172c
--- /dev/null
+++ b/pyecsca/codegen/hal/host/host_hal.h
@@ -0,0 +1,14 @@
+#ifndef HOST_HAL_H_
+#define HOST_HAL_H_
+
+#include "uart.h"
+
+#define trigger_setup()
+#define trigger_high()
+#define trigger_low()
+
+#define init_uart init_uart0
+#define putch output_ch_0
+#define getch input_ch_0
+
+#endif //HOST_HAL_H_
diff --git a/pyecsca/codegen/hal/host/uart.c b/pyecsca/codegen/hal/host/uart.c
new file mode 100644
index 0000000..3931d6d
--- /dev/null
+++ b/pyecsca/codegen/hal/host/uart.c
@@ -0,0 +1,7 @@
+#include "uart.h"
+
+void init_uart0(void) {}
+
+char input_ch_0(void) { return getchar(); }
+
+void output_ch_0(char data) { putchar(data); } \ No newline at end of file
diff --git a/pyecsca/codegen/hal/host/uart.h b/pyecsca/codegen/hal/host/uart.h
new file mode 100644
index 0000000..d6063bc
--- /dev/null
+++ b/pyecsca/codegen/hal/host/uart.h
@@ -0,0 +1,13 @@
+#ifndef UART_H_
+#define UART_H_
+
+#include <stdio.h>
+
+
+void init_uart0(void);
+
+char input_ch_0(void);
+
+void output_ch_0(char data);
+
+#endif //UART_H_ \ No newline at end of file
diff --git a/pyecsca/codegen/hash/sha1.c b/pyecsca/codegen/hash/sha1.c
index 8ef9723..cf6ca3e 100644
--- a/pyecsca/codegen/hash/sha1.c
+++ b/pyecsca/codegen/hash/sha1.c
@@ -24,7 +24,9 @@
#include <stdlib.h>
#include "sha1.h"
+#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN
+#endif
/********************************************************************************************************/
diff --git a/pyecsca/codegen/hash/sha2.c b/pyecsca/codegen/hash/sha2.c
index fb33650..d2ddf6f 100644
--- a/pyecsca/codegen/hash/sha2.c
+++ b/pyecsca/codegen/hash/sha2.c
@@ -49,7 +49,9 @@
#define CH(x,y,z) (((x)&(y)) ^ ((~(x))&(z)))
#define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
+#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN
+#endif
#if HASH == HASH_SHA224 || HASH == HASH_SHA256
#define SIGMA_0(x) (rotr32((x), 2) ^ rotr32((x),13) ^ rotl32((x),10))
diff --git a/pyecsca/codegen/main.c b/pyecsca/codegen/main.c
index 65cf444..fba5dc2 100644
--- a/pyecsca/codegen/main.c
+++ b/pyecsca/codegen/main.c
@@ -4,22 +4,22 @@
#include "hal/hal.h"
#include "simpleserial/simpleserial.h"
#include "hash/hash.h"
+#include "bn.h"
+#include "prng.h"
+#include <string.h>
-uint8_t cmd_set_curve(uint8_t *data, uint16_t len) {
+uint8_t cmd_init_prng(uint8_t *data, uint16_t len) {
+ prng_seed(data, len);
return 0;
}
int main(void) {
platform_init();
+ prng_init();
init_uart();
trigger_setup();
simpleserial_init();
- void *ctx = hash_new_ctx();
- uint8_t thing[10] = {1,2,3,4,5,6,7,8,9,10};
- uint8_t out[hash_size(10)];
- hash_init(ctx);
- hash_final(ctx, 10, thing, out);
- simpleserial_addcmd('a', 256, cmd_set_curve);
+ simpleserial_addcmd('i', 4, cmd_init_prng);
while(1)
simpleserial_get();
return 0;
diff --git a/pyecsca/codegen/mult/double_and_add.c b/pyecsca/codegen/mult/double_and_add.c
index 91ad6e3..1fd3c9e 100644
--- a/pyecsca/codegen/mult/double_and_add.c
+++ b/pyecsca/codegen/mult/double_and_add.c
@@ -1,5 +1,18 @@
#include "mult.h"
void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) {
-
+ point_t *q = point_copy(point);
+ point_t *r = point_copy(curve->neutral);
+
+ int nbits = bn_bit_length(curve->n);
+ for (int i = nbits; i >= 0; i--) {
+ point_dbl(r, curve, r);
+ if (bn_get_bit(scalar, i) == 1) {
+ point_add(q, r, curve, r);
+ }
+ }
+ point_scl(r, curve, r);
+ point_set(r, out);
+ point_free(q);
+ point_free(r);
} \ No newline at end of file
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);
+
diff --git a/pyecsca/codegen/simpleserial/simpleserial.c b/pyecsca/codegen/simpleserial/simpleserial.c
index 8205ed4..ca7c54d 100644
--- a/pyecsca/codegen/simpleserial/simpleserial.c
+++ b/pyecsca/codegen/simpleserial/simpleserial.c
@@ -3,6 +3,7 @@
#include "simpleserial.h"
#include <stdint.h>
#include "hal.h"
+#include <stdio.h>
typedef struct ss_cmd
{
@@ -28,10 +29,13 @@ static char hex_lookup[16] =
int hex_decode(int len, char* ascii_buf, uint8_t* data_buf)
{
- for(int i = 0; i < len; i++)
+ if (len % 2 != 0)
+ return 1;
+
+ for(int i = 0; i < len; i+=2)
{
- char n_hi = ascii_buf[2*i];
- char n_lo = ascii_buf[2*i+1];
+ char n_hi = ascii_buf[i];
+ char n_lo = ascii_buf[i+1];
if(n_lo >= '0' && n_lo <= '9')
data_buf[i] = n_lo - '0';
@@ -125,7 +129,7 @@ void simpleserial_get(void)
// Callback
uint8_t ret[1];
- ret[0] = commands[cmd].fp(data_buf, i);
+ ret[0] = commands[cmd].fp(data_buf, i/2);
// Acknowledge (if version is 1.1)
#if SS_VER == SS_VER_1_1