]> git.cryptolib.org Git - avr-crypto-lib.git/commitdiff
new, derived from old avr/crypto + cast5
authorbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Mon, 31 Jul 2006 16:04:26 +0000 (16:04 +0000)
committerbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Mon, 31 Jul 2006 16:04:26 +0000 (16:04 +0000)
30 files changed:
A5_1.c [new file with mode: 0644]
A5_1.h [new file with mode: 0644]
Makefile [new file with mode: 0644]
arcfour-asm.S [new file with mode: 0644]
arcfour.c [new file with mode: 0644]
arcfour.h [new file with mode: 0644]
cast5-sbox.h [new file with mode: 0644]
cast5.c [new file with mode: 0644]
cast5.h [new file with mode: 0644]
config.h [new file with mode: 0644]
debug.c [new file with mode: 0644]
debug.h [new file with mode: 0644]
hmac-sha256.c [new file with mode: 0644]
main-cast5-test.c [new file with mode: 0644]
main.c [new file with mode: 0644]
md5.c [new file with mode: 0644]
md5.h [new file with mode: 0644]
prng.c [new file with mode: 0644]
prng.h [new file with mode: 0644]
serial-tools.c [new file with mode: 0644]
serial-tools.h [new file with mode: 0644]
sha256-asm.S [new file with mode: 0644]
sha256-asm.h [new file with mode: 0644]
sha256.c [new file with mode: 0644]
sha256.h [new file with mode: 0644]
uart.c [new file with mode: 0644]
uart.h [new file with mode: 0644]
xtea-asm.S [new file with mode: 0644]
xtea.c [new file with mode: 0644]
xtea.h [new file with mode: 0644]

diff --git a/A5_1.c b/A5_1.c
new file mode 100644 (file)
index 0000000..6e64078
--- /dev/null
+++ b/A5_1.c
@@ -0,0 +1,59 @@
+/* 
+ * File:               A5_1.c
+ * Author:     Daniel Otte
+ * Date:       24.06.2006
+ * License: GPL
+ * Description: Implementation of the A5/1 stream cipher algorithm, as used in GSM.
+ * ! Warning, this is weak crypto !
+ * 
+ */
+#include <stdint.h>
+#include "A5_1.h"
+
+/*
+ * length is length of key in bytes!
+ */
+#define BYTEn(p,s) (*(((uint8_t*)&(p))+s))
+
+void           a5_1_init(a5_1_ctx_t *c, uint8_t *key, uint8_t length);
+
+bool    a5_1_clock(a5_1_ctx_t *c){
+       bool x1,x2,x3, maj;
+       x1 = PARITY_LOOKUP & (1<< ((BYTEn(c->r1,2)+BYTEn(c->r1,1)>>5) & 0x7);
+       x2 = PARITY_LOOKUP & (1<< (BYTEn(c->r2,2)>>4));
+       x3 = PARITY_LLOKUP & (1<< ((BYTEn(c->r3,2)>>4+BYTEn(c->r3,0)>>7) & 0x7));
+       maj = (((c->r1 & (1<<R1_CLK))?1:0)+((c->r2 & (1<<R2_CLK))?1:0)+((c->r3 & (1<<R3_CLK))?1:0))>=2;
+       if (((c->r1 & (1<<R1_CLK))>>R1_CLK) == maj)
+               c->r1 = c->r1<<1 + x1;
+       if (((c->r2 & (1<<R2_CLK))>>R2_CLK) == maj)
+               c->r2 = c->r2<<1 + x2;
+       if (((c->r3 & (1<<R3_CLK))>>R3_CLK) == maj)
+               c->r3 = c->r3<<1 + x3;
+               
+       return ((c->r1)>>(R1_LENGTH-1)+(c->r2)>>(R2_LENGTH-1)+(c->r3)>>(R3_LENGTH-1))&0x1;
+}
+
+uint8_t a5_1_gen(a5_   1_ctx_t *c){
+       uint8_t ret=0;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       ret <<= 1;
+       ret = a5_1_clock(c);
+       return ret;
+}
+
+
+
+
diff --git a/A5_1.h b/A5_1.h
new file mode 100644 (file)
index 0000000..8803198
--- /dev/null
+++ b/A5_1.h
@@ -0,0 +1,46 @@
+/* 
+ * File:               A5_1.h
+ * Author:     Daniel Otte
+ * Date:       24.06.2006
+ * License: GPL
+ * Description: Implementation of the A5/1 stream cipher algorithm, as used in GSM.
+ * ! Warning, this is weak crypto !
+ * 
+ */
+#ifndef A5_1_H_
+#define A5_1_H_
+
+#include <stdint.h>
+
+#define R1_LENGTH 19
+#define R2_LENGTH 22
+#define R3_LENGTH 23
+#define R1_CLK 11
+#define R2_CLK 12
+#define R3_CLK 13
+
+/* 3-Bit word parity lookup table (Byte) 
+ * 0: 0
+ * 1: 1
+ * 2: 1
+ * 3: 0
+ * 4: 1
+ * 5: 0
+ * 6: 0
+ * 7: 1
+ * => 1001.0110 = 0x96
+ * 
+ */
+
+#define PARITY_LOOKUP 0x96
+
+typedef struct {
+       uint32_t r1,r2,r3; /* the three regs, 19,22,23 bit in length  */
+} a5_1_ctx_t;
+
+void           a5_1_init(a5_1_ctx_t *c, uint8_t *key, uint8_t length);
+bool           a5_1_clock(a5_1_ctx_t *c);
+uint8_t a5_1_gen(a5_   1_ctx_t *c);
+
+#endif
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..89f8913
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,92 @@
+PRG        = cast5
+# cryptotest
+OBJ        = main-cast5-test.o debug.o uart.o serial-tools.o cast5.o
+# main.o debug.o uart.o serial-tools.o sha256-asm.o xtea-asm.o arcfour-asm.o prng.o cast5.o
+MCU_TARGET     = atmega32
+OPTIMIZE       = -Os
+
+DEFS      =
+LIBS      =
+
+# You should not have to change anything below here.
+
+CC          = avr-gcc
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS        = -Wall -Wstrict-prototypes  $(OPTIMIZE) -mmcu=$(MCU_TARGET) 
+$(DEFS)
+override LDFLAGS       = -Wl,-Map,$(PRG).map
+override ASFLAGS = -mmcu=$(MCU_TARGET)
+
+OBJCOPY        = avr-objcopy
+OBJDUMP        = avr-objdump
+
+all: $(PRG).elf lst text eeprom
+
+$(PRG).elf: $(OBJ)
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+       rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak 
+       rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
+
+lst:  $(PRG).lst
+
+%.lst: %.elf
+       $(OBJDUMP) -h -S $< > $@
+
+# Rules for building the .text rom images
+
+text: hex bin srec
+
+hex:  $(PRG).hex
+bin:  $(PRG).bin
+srec: $(PRG).srec
+
+%.hex: %.elf
+       $(OBJCOPY) -j .text -j .data -O ihex $< $@
+
+%.srec: %.elf
+       $(OBJCOPY) -j .text -j .data -O srec $< $@
+
+%.bin: %.elf
+       $(OBJCOPY) -j .text -j .data -O binary $< $@
+
+# Rules for building the .eeprom rom images
+
+eeprom: ehex ebin esrec
+
+ehex:  $(PRG)_eeprom.hex
+ebin:  $(PRG)_eeprom.bin
+esrec: $(PRG)_eeprom.srec
+
+%_eeprom.hex: %.elf
+       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
+
+%_eeprom.srec: %.elf
+       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@
+
+%_eeprom.bin: %.elf
+       $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
+
+# Every thing below here is used by avr-libc's build system and can be ignored
+# by the casual user.
+
+FIG2DEV                 = fig2dev
+EXTRA_CLEAN_FILES       = *.hex *.bin *.srec
+
+dox: eps png pdf
+
+eps: $(PRG).eps
+png: $(PRG).png
+pdf: $(PRG).pdf
+
+%.eps: %.fig
+       $(FIG2DEV) -L eps $< $@
+
+%.pdf: %.fig
+       $(FIG2DEV) -L pdf $< $@
+
+%.png: %.fig
+       $(FIG2DEV) -L png $< $@
diff --git a/arcfour-asm.S b/arcfour-asm.S
new file mode 100644 (file)
index 0000000..78d0491
--- /dev/null
@@ -0,0 +1,122 @@
+/* 
+ * File:               arcfour-asm.S
+ * Author:     Daniel Otte
+ * Date:       07.06.2006
+ * License: GPL
+ * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ * 
+ */
+ /* +---+---+---------------------+
+ *  | i | j | ......<256>........ |
+ *  +---+---+---------------------+
+ */
+.global arcfour_init
+
+;== arcfour_init ==
+;  this function initialises the context
+; param1: 16-bit pointer to a ctx struct
+;      given in r25,r24
+; param2: 16-bit pointer to a key
+;      given in r23,r22
+; param1: 8-bit integer indicating keylength in byte
+;      given in        r20
+
+arcfour_init:
+       push r29
+       push r28
+       push r2
+       
+       movw r26, r24   /* X points to ctx */
+       movw r30, r22   /* Z points to key */
+       st X+, r1
+       st X+, r1               /* X points to S */
+       
+1:             
+       st X+, r1 
+       inc r1
+       brne 1b
+       
+       adiw r24, 2             /* r24:r25 points to S */
+       clr r21                 /* r21 is j */
+       mov r18, r20            /* r18 is keyindex counter */
+       clr r0
+2:
+       movw r26, r24
+       ld r19, Z+
+       add r21, r19            /* j+= key[i%length] */
+       
+       add r26, r1
+       adc r27, r0
+       ld r19, X
+       add r21, r19            /* j += S[i] */
+       
+       dec r18         /* check the key-index counter */
+       brne 3f
+       movw r30, r22
+       mov r18, r20
+3:     /* now swap(S[i], S[j]) */ /* r19 is still S[i] */
+       movw r28, r24 
+       add r28, r21
+       adc r29, r0             /* Y points to S[j]*/
+       ld r2, Y
+       st Y, r19
+       st X, r2        
+       inc r1
+       brne 2b 
+       
+       pop r2
+       pop r28
+       pop r29
+       ret
+
+/*
+uint8_t arcfour_gen(arcfour_ctx_t *c){
+       uint8_t t;
+       c->i++;
+       c->j += c->s[c->i];
+       t = c->s[c->j];
+       c->s[c->j] = c->s[c->i];
+       c->s[c->i] = t;
+       return c->s[(c->s[c->j] + c->s[c->i]) & 0xff];
+}
+*/
+.global arcfour_gen
+
+;== arcfour_gen ==
+;  this function initialises the context
+; param1: 16-bit pointer to a ctx struct
+;      given in r25,r24
+
+arcfour_gen:
+       movw r26, r24
+       ld r18, X
+       inc r18
+       st X+, r18
+       movw r30, r26
+       ld r19, X+
+       add r26, r18
+       adc r27, r1
+       ld r20, X
+       add r19, r20
+       st Z+, r19              /* i,j loaded&saved; X->S[i]; Z->S[0]; r20=S[i] */
+       add r30, r19
+       adc r31, r1
+       ld r21, Z               /* X->S[i]; Z->S[j]; r20=S[i]; r21=S[j]*/
+       st Z, r20
+       st X, r21
+       add r20, r21
+       adiw r24, 2
+       movw r26, r24 /* X and Z point to S */
+       add r26, r20
+       adc r27, r1
+       ld r24, X
+       clr r25
+       ret
+
+
+
+
+
+
diff --git a/arcfour.c b/arcfour.c
new file mode 100644 (file)
index 0000000..863b7ac
--- /dev/null
+++ b/arcfour.c
@@ -0,0 +1,43 @@
+/* 
+ * File:               arcfour.c
+ * Author:     Daniel Otte
+ * Date:       07.06.2006
+ * License: GPL
+ * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ * 
+ */
+#include <stdint.h>
+#include "arcfour.h"
+
+/*
+ * length is length of key in bytes!
+ */
+
+void arcfour_init(arcfour_ctx_t *c, uint8_t *key, uint8_t length){
+       uint8_t t;
+       unsigned x,y=0;
+       for(x=0; x<= 255; ++x)
+               c->s[x]=x;
+       
+       for(x=0; x<= 255; ++x){
+               y += c->s[x] + key[x % length];
+               y &= 0xff;
+               t = c->s[y];
+               c->s[y] = c->s[x];
+               c->s[x] = t;
+       };
+               
+       c->i = c->j = 0;
+}
+
+uint8_t arcfour_gen(arcfour_ctx_t *c){
+       uint8_t t;
+       c->i++;
+       c->j += c->s[c->i];
+       t = c->s[c->j];
+       c->s[c->j] = c->s[c->i];
+       c->s[c->i] = t;
+       return c->s[(c->s[c->j] + c->s[c->i]) & 0xff];
+}
+
diff --git a/arcfour.h b/arcfour.h
new file mode 100644 (file)
index 0000000..f73dd40
--- /dev/null
+++ b/arcfour.h
@@ -0,0 +1,23 @@
+/* 
+ * File:       arcfour.h
+ * Author:     Daniel Otte
+ * Date:       07.06.2006
+ * License: GPL
+ * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ * 
+ */
+#ifndef ARCFOUR_H_
+#define ARCFOUR_H_
+
+#include <stdint.h>
+
+typedef struct {
+       uint8_t i,j;
+       uint8_t s[256];
+} arcfour_ctx_t;
+
+void arcfour_init(arcfour_ctx_t *c, uint8_t *key, uint8_t length);
+uint8_t arcfour_gen(arcfour_ctx_t *c);
+
+#endif
diff --git a/cast5-sbox.h b/cast5-sbox.h
new file mode 100644 (file)
index 0000000..b59489e
--- /dev/null
@@ -0,0 +1,583 @@
+/* 
+ * File:       cast5-sbox.h
+ * Author:     Daniel Otte
+ * Date:       26.07.2006
+ * License: GPL
+ * Description: sboxes for CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144.
+ * 
+ */
+#ifndef CAST5_SBOX_H_
+#define CAST5_SBOX_H_
+
+#include <avr/pgmspace.h>
+#include <stdint.h>
+
+#ifndef BIG_ENDIAN
+
+uint32_t s1[] PROGMEM = {
+0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, 0x6003e540UL, 0xcf9fc949UL,
+0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, 0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL,
+0x28683b6fUL, 0xc07fd059UL, 0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL,
+0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, 0x22568e3aUL, 0xa2d341d0UL,
+0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, 0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL,
+0xb82cbaefUL, 0xd751d159UL, 0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL,
+0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, 0xb48ee411UL, 0x4bff345dUL,
+0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, 0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL,
+0x882240f2UL, 0x0c6e4f38UL, 0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL,
+0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, 0xe63d37e0UL, 0x2a54f6b3UL,
+0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, 0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL,
+0x38901091UL, 0xc6b505ebUL, 0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL,
+0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, 0xa0bebc3cUL, 0x54623779UL,
+0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, 0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL,
+0x81383f05UL, 0x6963c5c8UL, 0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL,
+0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, 0xaa573b04UL, 0x4a805d8dUL,
+0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, 0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL,
+0x6b54bfabUL, 0x2b0b1426UL, 0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL,
+0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, 0xe31231b2UL, 0x2ad5ad6cUL,
+0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, 0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL,
+0x7b5a41f0UL, 0xd37cfbadUL, 0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL,
+0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, 0x5ad328d8UL, 0xb347cc96UL,
+0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, 0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL,
+0x3f04442fUL, 0x6188b153UL, 0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL,
+0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, 0xdd24cb9eUL, 0x7e1c54bdUL,
+0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, 0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL,
+0x580304f0UL, 0xca042cf1UL, 0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL,
+0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, 0xd5ea50f1UL, 0x85a92872UL,
+0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, 0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL,
+0x474d6ad7UL, 0x7c0c5e5cUL, 0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL,
+0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, 0xb141ab08UL, 0x7cca89b9UL,
+0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, 0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL};
+
+uint32_t s2[] PROGMEM = {
+0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, 0x55889c94UL, 0x72fc0651UL,
+0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, 0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL,
+0xa0b52f7bUL, 0x59e83605UL, 0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL,
+0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, 0x25a1ff41UL, 0xe180f806UL,
+0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, 0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL,
+0xe113c85bUL, 0xacc40083UL, 0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL,
+0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, 0x361e3084UL, 0xe4eb573bUL,
+0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, 0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL,
+0x10843094UL, 0x2537a95eUL, 0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL,
+0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, 0x721d9bfdUL, 0xa58684bbUL,
+0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, 0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL,
+0xc5d655ddUL, 0xeb667064UL, 0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL,
+0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, 0x83ca6b94UL, 0x2d6ed23bUL,
+0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, 0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL,
+0x81ed6f61UL, 0x20e74364UL, 0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL,
+0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, 0xa4b09f6bUL, 0x1ca815cfUL,
+0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, 0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL,
+0xee41e729UL, 0x6e1d2d7cUL, 0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL,
+0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, 0x7cbad9a2UL, 0x2180036fUL,
+0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, 0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL,
+0xcdf0b680UL, 0x17844d3bUL, 0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL,
+0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, 0xef8579ccUL, 0xd152de58UL,
+0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, 0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL,
+0xb8da230cUL, 0x80823028UL, 0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL,
+0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, 0x273be979UL, 0xb0ffeaa6UL,
+0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, 0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL,
+0xdc8637a0UL, 0x16a7d3b1UL, 0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL,
+0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, 0x145892f5UL, 0x91584f7fUL,
+0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, 0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL,
+0xb284600cUL, 0xd835731dUL, 0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL,
+0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, 0x5c038323UL, 0x3e5d3bb9UL,
+0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, 0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL};
+
+uint32_t s3[] PROGMEM = {
+0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, 0x8c1fc644UL, 0xaececa90UL,
+0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, 0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL,
+0x11107d9fUL, 0x07647db9UL, 0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL,
+0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, 0x9255c5edUL, 0x1257a240UL,
+0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, 0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL,
+0xa8c01db7UL, 0x579fc264UL, 0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL,
+0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, 0xc5884a28UL, 0xccc36f71UL,
+0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, 0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL,
+0xa747d2d0UL, 0x1651192eUL, 0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL,
+0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, 0x796fb449UL, 0x8252dc15UL,
+0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, 0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL,
+0x23efe941UL, 0xa903f12eUL, 0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL,
+0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, 0x96bbb682UL, 0x93b4b148UL,
+0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, 0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL,
+0x8b907ceeUL, 0xb51fd240UL, 0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL,
+0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, 0x127dadaaUL, 0x438a074eUL,
+0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, 0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL,
+0x68cc7bfbUL, 0xd90f2788UL, 0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL,
+0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, 0x27627545UL, 0x825cf47aUL,
+0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, 0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL,
+0x285ba1c8UL, 0x3c62f44fUL, 0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL,
+0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, 0x12deca4dUL, 0x2c3f8cc5UL,
+0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, 0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL,
+0x3a609437UL, 0xec00c9a9UL, 0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL,
+0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, 0xa2e53f55UL, 0xb9e6d4bcUL,
+0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, 0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL,
+0x947b0001UL, 0x570075d2UL, 0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL,
+0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, 0xf1ac2571UL, 0xcc8239c2UL,
+0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, 0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL,
+0x5727c148UL, 0x2be98a1dUL, 0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL,
+0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, 0x52bce688UL, 0x1b03588aUL,
+0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, 0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL};
+
+uint32_t s4[] PROGMEM = {
+0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, 0x85510443UL, 0xfa020ed1UL,
+0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, 0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL,
+0x28147f5fUL, 0x4fa2b8cdUL, 0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL,
+0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, 0x081b08caUL, 0x05170121UL,
+0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, 0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL,
+0xce84ffdfUL, 0xf5718801UL, 0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL,
+0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, 0x72500e03UL, 0xf80eb2bbUL,
+0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, 0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL,
+0x4d351805UL, 0x7f3d5ce3UL, 0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL,
+0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, 0x18f8931eUL, 0x281658e6UL,
+0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, 0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL,
+0x69dead38UL, 0x1574ca16UL, 0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL,
+0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, 0x0ce5c2ecUL, 0x4db4bba6UL,
+0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, 0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL,
+0x6e85cb75UL, 0xbe07c002UL, 0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL,
+0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, 0x041afa32UL, 0x1d16625aUL,
+0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, 0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL,
+0x026a4cebUL, 0x52437effUL, 0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL,
+0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, 0x213d42f6UL, 0x2c1c7c26UL,
+0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, 0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL,
+0x63315c21UL, 0x5e0a72ecUL, 0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL,
+0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, 0xcfcbd12fUL, 0xc1de8417UL,
+0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, 0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL,
+0x6f7de532UL, 0x58fd7eb6UL, 0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL,
+0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, 0xaf9eb3dbUL, 0x29c9ed2aUL,
+0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, 0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL,
+0x77079103UL, 0xdea03af6UL, 0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL,
+0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, 0xf3e0eb5bUL, 0xd6cc9876UL,
+0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, 0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL,
+0xb5676e69UL, 0x9bd3dddaUL, 0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL,
+0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, 0xb657c34dUL, 0x4edfd282UL,
+0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, 0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL};
+
+#else
+
+uint32_t s1[] PROGMEM = {
+0xd440fb30UL, 0x0bffa09fUL, 0x2fcdec6bUL, 0x7a8c253fUL, 0x2f3f211eUL, 0xd34d009cUL, 0x40e50360UL, 0x49c99fcfUL,
+0x27afd4bfUL, 0xb5bdbb88UL, 0x904003e2UL, 0x7596d098UL, 0xe0a0636eUL, 0xd261c315UL, 0x1d66e7c2UL, 0x8effd422UL,
+0x6f3b6828UL, 0x59d07fc0UL, 0xc87923ffUL, 0xe2505f77UL, 0xd340c343UL, 0x56862fdfUL, 0x1aa47c88UL, 0x2dbdd2a2UL,
+0xd6e0c9a1UL, 0x19486c34UL, 0x876db761UL, 0x2f0f5422UL, 0xe132be2aUL, 0x6b1654aaUL, 0x3a8e5622UL, 0xd041d3a2UL,
+0xc840db66UL, 0x2f3984a7UL, 0x2fff4d00UL, 0xded2b92dUL, 0xac3f9497UL, 0xd8c1974aUL, 0xb7447652UL, 0xa737f4b5UL,
+0xefba2cb8UL, 0x59d151d7UL, 0xedf0f76fUL, 0x1f7a095aUL, 0xd0687b82UL, 0x2ef5ec90UL, 0x54c0b022UL, 0x35598ebcUL,
+0x7f2f6d4bUL, 0xa264bb50UL, 0x104966d2UL, 0x2d81e5beUL, 0x902233b7UL, 0x9f153be9UL, 0x11e48eb4UL, 0x5d34ff4bUL,
+0x40c245fdUL, 0x3f9731adUL, 0x2ed0f6c4UL, 0x6581fc55UL, 0xadcab1d5UL, 0xae2daca1UL, 0x6db7d4a2UL, 0x500c9bc1UL,
+0xf2402288UL, 0x384f6e0cUL, 0xd7bfe4a4UL, 0x72a25b4fUL, 0x2f1d4c56UL, 0x19539cc5UL, 0x54e349b9UL, 0xfe6946b0UL,
+0x8aabb6b1UL, 0xdd5813c7UL, 0x45c58563UL, 0x5d930f11UL, 0xd58a5357UL, 0x9304396aUL, 0xe0373de6UL, 0xb3f6542aUL,
+0x5f7d783aUL, 0xb5a07662UL, 0xdffca619UL, 0x6a20427aUL, 0xd5d4f929UL, 0x91181bf6UL, 0x5e2772bbUL, 0x678150aaUL,
+0x91109038UL, 0xeb05b5c6UL, 0x8ccbc784UL, 0x0f5ad72aUL, 0x27144a87UL, 0x6b93d1a2UL, 0xaf86d22aUL, 0x91d256aaUL,
+0x604389d7UL, 0x0d755c42UL, 0x269eb393UL, 0xc9847118UL, 0x2db3006cUL, 0x14bbe273UL, 0x3cbcbea0UL, 0x79376254UL,
+0xab9e4564UL, 0x828b323fUL, 0x82cf1877UL, 0xa6cea259UL, 0x2e00ee04UL, 0xe678fe89UL, 0x5009ab3fUL, 0xc2f65f32UL,
+0x053f3881UL, 0xc8c56369UL, 0xd65acb76UL, 0xc97499d4UL, 0xcf0d18caUL, 0xd5820738UL, 0xf65cfac7UL, 0x1115c38aUL,
+0x139ee735UL, 0xd091da47UL, 0x86900ff4UL, 0x9e41e2a7UL, 0x41623631UL, 0x95f41e05UL, 0x043b57aaUL, 0x8d5d804aUL,
+0xd0008354UL, 0x3c2a3200UL, 0xdfcd64bfUL, 0x8ea657baUL, 0x2b37c675UL, 0x41d3af50UL, 0x7532c1a7UL, 0xf50b5a91UL,
+0xabbf546bUL, 0x26140b2bUL, 0xd7c94cabUL, 0x82cd9c44UL, 0x65f2fbf7UL, 0xf3c585abUL, 0x94db551bUL, 0x24e3d4aaUL,
+0x3fbda4cfUL, 0xe2a3ea2dUL, 0x024d209eUL, 0xac25bdc8UL, 0xb355dfeaUL, 0x989ebdd5UL, 0xb23112e3UL, 0x6cadd52aUL,
+0xde294395UL, 0x2845beadUL, 0x690f71d8UL, 0x0fc951aaUL, 0xf66b78aaUL, 0x1e3f5122UL, 0x9ba751aaUL, 0xcc44d32aUL,
+0xf0415a7bUL, 0xadfb7cd3UL, 0x0595061bUL, 0x91e4ec41UL, 0xe632c3b4UL, 0xd4682203UL, 0xcc0a60c9UL, 0x6d7e38ceUL,
+0x6cb16bbfUL, 0x78fb706aUL, 0xc9d9030dUL, 0xde39dfd4UL, 0xda6310e0UL, 0x64f43647UL, 0xd828d35aUL, 0x96cc47b3UL,
+0xc30fbb75UL, 0xfb1b5198UL, 0x35ccfb4fUL, 0x6acf8bb5UL, 0xbc0a1fe1UL, 0x4afec5bfUL, 0x10ec0aa7UL, 0x0a5739acUL,
+0x2f44043fUL, 0x53b18861UL, 0x2e7a39e0UL, 0x79cb2757UL, 0x8f41eb9cUL, 0x8dd6ac1cUL, 0x967cd32aUL, 0x9dcb7501UL,
+0x09ff9dc6UL, 0xf0655bc7UL, 0xd840dbd9UL, 0x79770eecUL, 0xd4ea4447UL, 0x74321cb1UL, 0x9ecb24ddUL, 0xbd541c7eUL,
+0xf94411f0UL, 0xb10e24d2UL, 0xfdb37596UL, 0x5537aca3UL, 0xaf277cd4UL, 0x4d5fc851UL, 0x96759056UL, 0xe615bba5UL,
+0xf0040358UL, 0xf12c04caUL, 0xea371a01UL, 0xdbaabf8dUL, 0x4a3eba35UL, 0xa0ff2635UL, 0x094d7bc3UL, 0xd96e30bcUL,
+0x6626a598UL, 0x25f74856UL, 0x9d565effUL, 0xd063ed0cUL, 0xcfb2637cUL, 0xe1450b70UL, 0xf150ead5UL, 0x7228a985UL,
+0xa7bd1fafUL, 0x704823d4UL, 0xf30b87a7UL, 0x794d3b2dUL, 0x9841e042UL, 0xe7edd00cUL, 0xb80d4726UL, 0x4c8181f8UL,
+0xd76a4d47UL, 0x5c5e0c7cUL, 0x591923d1UL, 0x98721b38UL, 0xdbf4d2f5UL, 0x538683abUL, 0x231e2f6eUL, 0x9e9c7183UL,
+0x46e091bdUL, 0x6e45569aUL, 0x0c2039dcUL, 0x71c5c820UL, 0x1cda2b96UL, 0xff96e6e1UL, 0x08ab41b1UL, 0xb989ca7cUL,
+0x83e7691aUL, 0x4348cc02UL, 0x79c5f7a2UL, 0x7df49e42UL, 0x9c167b42UL, 0x49f0c95aUL, 0x000f8fddUL, 0xbf65815cUL};
+
+uint32_t s2[] PROGMEM = {
+0x9410201fUL, 0x5ba70befUL, 0x7ecfe369UL, 0x80433f39UL, 0x7acf61feUL, 0x7a20c5eeUL, 0x949c8855UL, 0x5106fc72UL,
+0x79efa7adUL, 0x35721d4eUL, 0xce635ad5UL, 0xba3604deUL, 0xef30c499UL, 0x94070c5fUL, 0x7ddbdc18UL, 0xf3efd6a1UL,
+0x7b2fb5a0UL, 0x0536e859UL, 0x94b015eeUL, 0x09d9ffe9UL, 0x860044dcUL, 0x594494efUL, 0xb3cc83baUL, 0xfbcdc3e0UL,
+0x8141dad1UL, 0xb12a093bUL, 0xc1f197f9UL, 0x7bcfe6a5UL, 0xdb0d4201UL, 0x5befe7e4UL, 0x41ffa125UL, 0x06f880e1UL,
+0x8010c41fUL, 0x7aee9b17UL, 0xa9c67ad3UL, 0xa43058feUL, 0x7f8bde98UL, 0x4e3fe877UL, 0x69929279UL, 0x7b9ffa24UL,
+0x5bc813e1UL, 0x8300c4acUL, 0x253550d7UL, 0x5f61eaf7UL, 0x54311462UL, 0x634b550dUL, 0x2111685dUL, 0x59c366c8UL,
+0x73cf633dUL, 0xc034e2ceUL, 0x877ed8d4UL, 0x212b675cUL, 0x81611f07UL, 0x7f62f739UL, 0x84301e36UL, 0x3b57ebe4UL,
+0xa4642f60UL, 0x9ccd3ad6UL, 0x3546bc1bUL, 0x2d03819eUL, 0x0cf50127UL, 0xb47a8499UL, 0x79dfe3a0UL, 0x8cf36cbaUL,
+0x94308410UL, 0x5ea93725UL, 0xfe6f6ff4UL, 0x1f3bffa1UL, 0x6afb8c20UL, 0x748c458fUL, 0x27a2e0d9UL, 0x343ac74eUL,
+0x694f88fcUL, 0xdfe84d3eUL, 0x88000eefUL, 0x8d645935UL, 0x8c38458aUL, 0x6643801dUL, 0xfd9b1d72UL, 0xbb8486a5UL,
+0x336325e8UL, 0x12824e84UL, 0x98808d12UL, 0xb43fd3feUL, 0xe10a28ceUL, 0xa59be127UL, 0x52c2a6d5UL, 0xbd5497e4UL,
+0xdd55d6c5UL, 0x647066ebUL, 0x4d0b8477UL, 0x01a8b6a1UL, 0xa926db84UL, 0x1467b5e0UL, 0xb743f021UL, 0x6058d0e5UL,
+0x8430f054UL, 0x72f46f06UL, 0x53a11aa3UL, 0x5547dcdaUL, 0xbf5d62b5UL, 0xe61b5668UL, 0x946bca83UL, 0x3bd26e2dUL,
+0xdb01cfecUL, 0xbad0d3a6UL, 0x5c3d80b6UL, 0x09a777afUL, 0x4ca3b433UL, 0xd6c87b39UL, 0x952be25eUL, 0x04530e5fUL,
+0x616fed81UL, 0x6443e720UL, 0x78135eb4UL, 0x9b6318deUL, 0x22a11c88UL, 0xd12667b9UL, 0xe8a74980UL, 0x7bdab722UL,
+0x252d555eUL, 0x37d27252UL, 0x1c95d279UL, 0x4c890dc6UL, 0x02b48c48UL, 0x5bfea41bUL, 0x6b9fb0a4UL, 0xcf15a81cUL,
+0x05300ca2UL, 0x63df7188UL, 0xcb2fdeb9UL, 0xe9c9c60cUL, 0x53ffee0bUL, 0x174521e3UL, 0x352854b4UL, 0x3c29639fUL,
+0x29e741eeUL, 0x7c2d1d6eUL, 0x86520450UL, 0xf385661eUL, 0xc60134f3UL, 0x952ca230UL, 0x5008a731UL, 0x130f9360UL,
+0x1784f973UL, 0x599826a1UL, 0x445c64ecUL, 0xa977c852UL, 0xa633ffcdUL, 0x41172ba0UL, 0xa2d9ba7cUL, 0x6f038021UL,
+0x089cd950UL, 0x61483fcbUL, 0x65d76bc2UL, 0xabf6a364UL, 0x76263480UL, 0x7b5ea725UL, 0xfcd1e6e4UL, 0xe610c720UL,
+0x80b6f0cdUL, 0x3b4d8417UL, 0x4df8ee31UL, 0xe424087eUL, 0xeb49cb2cUL, 0xae3b6a84UL, 0x8878f78fUL, 0xf6605deeUL,
+0x7356f77aUL, 0xdb5cdd2fUL, 0xc13116a1UL, 0x436ff630UL, 0x54ecfab3UL, 0xfad77f15UL, 0xcc7985efUL, 0x58de52d1UL,
+0x5efd2fdbUL, 0x19ce328fUL, 0x7af96a30UL, 0xf83ef002UL, 0xd59a3199UL, 0x0ffa42c2UL, 0xb0ebe3a7UL, 0x06498ec6UL,
+0x0c23dab8UL, 0x28308280UL, 0xc8f3dedcUL, 0x71b15fd3UL, 0xc81b8a08UL, 0x60c5c0beUL, 0xe8c9a361UL, 0x4df5a8bcUL,
+0xfaef2fc7UL, 0x992e8222UL, 0xb470c582UL, 0x894ed9d8UL, 0xbc341c8bUL, 0xe6161e30UL, 0x79e93b27UL, 0xa6eaffb0UL,
+0xc6b8d961UL, 0x6948b200UL, 0x3fceffb7UL, 0x3b28dc08UL, 0x5af6da43UL, 0x9897e1f7UL, 0x2fb71976UL, 0xa49b1c8fUL,
+0xa03786dcUL, 0xb1d3a716UL, 0xb793c39fUL, 0xeb6e13a7UL, 0x3ec6bcc6UL, 0x4237511aUL, 0xbc2868efUL, 0xd6650352UL,
+0xab776a2dUL, 0x4bed2735UL, 0x16d21f82UL, 0x2e6e5c09UL, 0xfbf292dbUL, 0xcb29ea5eUL, 0xf5925814UL, 0x7f4f5891UL,
+0x7b698354UL, 0xcca86726UL, 0x48601985UL, 0xeaac4b8cUL, 0xd4603883UL, 0xf9e0230dUL, 0x8a7e386cUL, 0x49d2e60aUL,
+0x0c6084b2UL, 0x1d7335d8UL, 0x47c6b1dcUL, 0xea564cacUL, 0xb381bd3eUL, 0xb0ab0e23UL, 0x87bc3864UL, 0xfab1b5f0UL,
+0xb3a25e8fUL, 0x424618fcUL, 0x7a6b030aUL, 0xbd89b04fUL, 0x89a59d64UL, 0x5e4145a3UL, 0x2383035cUL, 0xb93b5d3eUL,
+0x7295d743UL, 0x7cd06d7eUL, 0x1edfdf06UL, 0xefc46c6cUL, 0x39a56071UL, 0x70bebf73UL, 0x05768783UL, 0xf1ec2345UL};
+
+uint32_t s3[] PROGMEM = {
+0x40c2ef8dUL, 0x9f5dfa25UL, 0xbf3d90ebUL, 0x07c910e8UL, 0xff7f6047UL, 0x4be49f36UL, 0x44c61f8cUL, 0x90caceaeUL,
+0xbff9b1beUL, 0xeacafbeeUL, 0x5019cfe8UL, 0xae07df51UL, 0x06880e92UL, 0x4805adf0UL, 0x838d3ce1UL, 0xd5107092UL,
+0x9f7d1011UL, 0xb97d6407UL, 0xd4e4e3b2UL, 0x5e284f3dUL, 0x20a8afb9UL, 0xe082defaUL, 0x8b2667a0UL, 0x2e797282UL,
+0xc0b23f55UL, 0x2be29a48UL, 0x9497efd4UL, 0xbc3f5e12UL, 0xeefcff21UL, 0xfd1b5b82UL, 0xedc55592UL, 0x40a25712UL,
+0x02831a4eUL, 0xff7fe0baUL, 0xe7468252UL, 0x0e14578eUL, 0xbff77333UL, 0x88819f8cUL, 0xe84efca6UL, 0xa5b582c9UL,
+0xb71dc0a8UL, 0x64c29f57UL, 0x314f0967UL, 0x5f3fbdf2UL, 0xc1f7ff40UL, 0xfc8db71fUL, 0xc1d26b8eUL, 0x9be57b43UL,
+0xbf3db099UL, 0x4bc6dbb5UL, 0xe6c08d63UL, 0x999d8155UL, 0x1cc897a1UL, 0x6e2d014aUL, 0x284a88c5UL, 0x716fc3ccUL,
+0x13c243b8UL, 0xf143076cUL, 0x3c890983UL, 0x5fdded0fUL, 0x50e87f2fUL, 0x7e7fc0d7UL, 0xbf7f5002UL, 0x049afb5aUL,
+0xd0d247a7UL, 0x2e195116UL, 0x3ebf70afUL, 0x8013c358UL, 0x2e30985fUL, 0xc4c37c72UL, 0x02b40f0aUL, 0x82ef7f0fUL,
+0xadfd968cUL, 0xae2a2c5dUL, 0x499ae98eUL, 0xb888da50UL, 0xa0f42784UL, 0x9057ac1eUL, 0x49b46f79UL, 0x15dc5282UL,
+0x9b7dbdefUL, 0x7d5972a6UL, 0xd840a8adUL, 0x0445f545UL, 0x03745dfaUL, 0x05c33ee8UL, 0x1a75914fUL, 0xc2695692UL,
+0x41e9ef23UL, 0x2ef103a9UL, 0xf20d2760UL, 0xb6e47602UL, 0x7465fd94UL, 0xb2857992UL, 0xcbdb7682UL, 0x76817702UL,
+0x8d91aff8UL, 0x9ef7484eUL, 0xdf6d618fUL, 0x0e849de2UL, 0x837d2f84UL, 0xc8e50c34UL, 0x82b6bb96UL, 0x48b1b493UL,
+0xab3c30efUL, 0x28af4f98UL, 0x9baf9f77UL, 0x0d56dc92UL, 0x201e4d22UL, 0x88aa3784UL, 0x96dc297dUL, 0xdcd35627UL,
+0xee7c908bUL, 0x40d21fb5UL, 0xe37cc0e7UL, 0xa1b466e5UL, 0x5e61e9c3UL, 0x9d20f83cUL, 0xe3d19460UL, 0x41a39ccdUL,
+0x0e46765cUL, 0x3b98ea00UL, 0x8178d6d4UL, 0x2c5747fdUL, 0xd9ed6cf7UL, 0x9c22a8bdUL, 0xaaad7d12UL, 0x4e078a43UL,
+0x90c0971fUL, 0x8adb1b08UL, 0xbe7ea093UL, 0x15ca38b9UL, 0xff3cb097UL, 0xf8c0c23dUL, 0xecb21a8dUL, 0x510e3864UL,
+0xfb7bcc68UL, 0x88270fd9UL, 0x81014912UL, 0xd4ffe55dUL, 0x6af87eddUL, 0x14e2a276UL, 0x6803a4b9UL, 0x8f955d92UL,
+0xfaff394bUL, 0xe9ae39baUL, 0x0bd3ffa4UL, 0x3b93f7faUL, 0x2386496dUL, 0xfabc3c19UL, 0x45756227UL, 0x7af45c82UL,
+0xa08bbd61UL, 0xd1421ed1UL, 0xf404adceUL, 0x92a37e12UL, 0xb78d4210UL, 0x72a97282UL, 0xa8c47092UL, 0x0be57d12UL,
+0xc8a15b28UL, 0x4ff4623cUL, 0xa5eac035UL, 0x31d205e8UL, 0xfb298942UL, 0x82dffcb4UL, 0x536ab64fUL, 0x5bc17d0eUL,
+0xab1f081fUL, 0xae188610UL, 0x6d08fdfcUL, 0x8928fff9UL, 0x11cc4b69UL, 0xae5c6a23UL, 0x4dcade12UL, 0xc58c3f2cUL,
+0xfe2dd0d2UL, 0x9658eff8UL, 0xda52cfe4UL, 0x675b1595UL, 0x8c484a49UL, 0x0ca8b6b9UL, 0xbc828f5cUL, 0x456bd389UL,
+0x3794603aUL, 0xa9c900ecUL, 0x53527144UL, 0x494b870aUL, 0x40bc73d7UL, 0x1c67347cUL, 0xf67e7102UL, 0x3655eb4fUL,
+0xff2fd0a2UL, 0xc460bfd2UL, 0xc0033fd4UL, 0x6defb450UL, 0xd18c4707UL, 0x88186e00UL, 0x553fe5a2UL, 0xbcd4e6b9UL,
+0x168004a2UL, 0x33385797UL, 0x677d20d7UL, 0x3d8f0fdeUL, 0x337bf872UL, 0x334fccabUL, 0x5dc58876UL, 0xb0a6007bUL,
+0x01007b94UL, 0xd2750057UL, 0xf888bbf9UL, 0x9e014289UL, 0xffa56442UL, 0xe0026385UL, 0x2bd9db72UL, 0x691b97eeUL,
+0xde2fa26eUL, 0x2bae085fUL, 0x6d617aafUL, 0x6787c9e5UL, 0xd2eb1fcfUL, 0xc2c8ef61UL, 0x7125acf1UL, 0xc23982ccUL,
+0xb84c2167UL, 0xd183e5b1UL, 0x623edcb7UL, 0xcebd107fUL, 0x385c0af9UL, 0x3d44f00fUL, 0xc66d6e60UL, 0x493a5460UL,
+0x48c12757UL, 0x1d8ae92bUL, 0x3817b48aUL, 0x24bee120UL, 0x0fda96afUL, 0x25844568UL, 0xe53b8399UL, 0x7d450d60UL,
+0x50932f28UL, 0x62b33483UL, 0x20111dd9UL, 0xa08d6d2bUL, 0x311e2b64UL, 0x005a309cUL, 0x88e6bc52UL, 0x8a58031bUL,
+0xd5efbaf7UL, 0x9ced4241UL, 0x115c31a4UL, 0xc53e3283UL, 0x3646efdfUL, 0x01c533a1UL, 0x1c53d3e9UL, 0x833735eeUL};
+
+uint32_t s4[] PROGMEM = {
+0x2004b39dUL, 0xdee9b61fUL, 0xef7bbea7UL, 0x98a273d2UL, 0xdb7b4f4aUL, 0x578cad64UL, 0x43045185UL, 0xd10e02faUL,
+0xff7a287eUL, 0x63b60fe6UL, 0xa1355f09UL, 0x20f1eb79UL, 0x439d05fdUL, 0xb1b79764UL, 0x631f64f3UL, 0xdf4a1e24UL,
+0x5f7f1428UL, 0xcdb8a24fUL, 0x400043c9UL, 0x2022c30cUL, 0x300bd3fdUL, 0x4f37a5c0UL, 0xd9002d1dUL, 0x157b1424UL,
+0x1a114deeUL, 0x6751ca0fUL, 0x4c90ff71UL, 0xfe5f192dUL, 0x5f64051aUL, 0xfefe130cUL, 0xca081b08UL, 0x21011705UL,
+0x00015380UL, 0xfe5e3ee8UL, 0xf8f49aacUL, 0x0127e77fUL, 0x5feeb8d2UL, 0x6142df06UL, 0x8a9b9ebbUL, 0x25ea9372UL,
+0xdfff84ceUL, 0x018871f5UL, 0x044bd63dUL, 0x3b266fa2UL, 0x0084d47eUL, 0xe6eb7e54UL, 0xa04c6d44UL, 0xf5d6f36cUL,
+0xdfab4926UL, 0xf5c7a0aeUL, 0xc18c3336UL, 0x937e3f50UL, 0x612077d3UL, 0xe138b611UL, 0x030e5072UL, 0xbbb20ef8UL,
+0x2e50e0abUL, 0xde778decUL, 0x811e9757UL, 0x46674fe1UL, 0x005433c9UL, 0x8f312069UL, 0x99bb1d08UL, 0xa504c3ffUL,
+0x0518354dUL, 0xe35c3d7fUL, 0xc666c8a6UL, 0xa9cc5b5dUL, 0xea6fecdaUL, 0x916f929fUL, 0x2f22469fUL, 0x7d469139UL,
+0x8e6dbfa5UL, 0x4fc44311UL, 0x02839543UL, 0xeb4e21d0UL, 0xb8832002UL, 0x0c18b63fUL, 0x1e93f818UL, 0xe6581628UL,
+0x3e6e4826UL, 0x708ad78bUL, 0xc1e47774UL, 0x7ce006b5UL, 0x250a2df3UL, 0x028b0979UL, 0x81bbeae4UL, 0x233b1228UL,
+0x38adde69UL, 0x16ca7415UL, 0x621b87dfUL, 0xb7401c21UL, 0xf99e1aa5UL, 0x7b371400UL, 0xc88a1e04UL, 0x03401109UL,
+0xd2e459bdUL, 0xd556d1e3UL, 0xd576e84fUL, 0x40a3912fUL, 0xdee87b55UL, 0xa7e4ea00UL, 0xecc2e50cUL, 0xa6bbb44dUL,
+0xffbd56e7UL, 0xac6933ddUL, 0x35b017ecUL, 0x27235706UL, 0xb0c8af99UL, 0x91c3c856UL, 0x1c81656bUL, 0x1961145eUL,
+0x75cb856eUL, 0x02c007beUL, 0x775532c2UL, 0xecf43f89UL, 0x2dc9bf5bUL, 0x253becd0UL, 0xb71a80b7UL, 0x243b6d8dUL,
+0xef63c720UL, 0xfca566c3UL, 0x8028389cUL, 0x0532ce0aUL, 0x8a54c9aaUL, 0xc7d7a1ecUL, 0x32fa1a04UL, 0x5a62161dUL,
+0x2c900167UL, 0x547a759bUL, 0xf777d431UL, 0x31b02691UL, 0xdb6fcc36UL, 0x468b0bc7UL, 0x486ae6d9UL, 0x795ae556UL,
+0xeb4c6a02UL, 0xff7e4352UL, 0xb4768f2fUL, 0xa580f90dUL, 0xe3cd7486UL, 0xeb04daedUL, 0x04bea917UL, 0xdff4182cUL,
+0x9d7f74b7UL, 0xb4f72aabUL, 0x204dc3efUL, 0x7c6b092eUL, 0x54a24117UL, 0x35a0b6e5UL, 0xf6423d21UL, 0x267c1c2cUL,
+0x0ff5c261UL, 0xf9da5265UL, 0xf831c2d2UL, 0x690f1325UL, 0xa27f16d8UL, 0xc8f21804UL, 0xa6961a00UL, 0xab26150dUL,
+0x215c3163UL, 0xec720a5eUL, 0xfdfeba49UL, 0xd9087918UL, 0x86bd0d8dUL, 0xa7701131UL, 0x0c649b3eUL, 0xd7103eccUL,
+0xb6d3cad5UL, 0x88c3ae0cUL, 0xe10130f7UL, 0xff8a726cUL, 0xa1e2ea71UL, 0x6ef39a1fUL, 0x2fd1cbcfUL, 0x1784dec1UL,
+0x6bbe07acUL, 0xd8a144cbUL, 0x560f9b8bUL, 0xc3883901UL, 0xca2fc5b1UL, 0xcd31beb4UL, 0x062878d8UL, 0xe2a4a312UL,
+0x32e57d6fUL, 0xb67efd58UL, 0x00e91ed0UL, 0xc2ffad24UL, 0xc50f99f4UL, 0xc5aa1197UL, 0x957b1d00UL, 0xd2e7e582UL,
+0xf6739810UL, 0x96306100UL, 0x21952dc3UL, 0xff21a1adUL, 0x15849029UL, 0x7f97bb7fUL, 0xdbb39eafUL, 0x2aedc929UL,
+0x65a4e25cUL, 0x2cf330a7UL, 0xe83faad0UL, 0x91c05c8aUL, 0xe72c9ed4UL, 0xa954e40cUL, 0x86cd0ad6UL, 0x19195f01UL,
+0x03910777UL, 0xf63aa0deUL, 0x5e56a878UL, 0xdf56e3deUL, 0xbe5cf021UL, 0x87e3758bUL, 0x5106c5b3UL, 0xefc3a5b8UL,
+0xd2b6eed8UL, 0x77be23e5UL, 0x294515c2UL, 0xdfef692fUL, 0xfb7ae6afUL, 0xb2c470f4UL, 0x5bebe0f3UL, 0x7698ccd6UL,
+0x0c46e439UL, 0x3885da1fUL, 0x2f838719UL, 0x677300caUL, 0xf84491a9UL, 0x9e296b29UL, 0x95c22f49UL, 0xabbe6692UL,
+0x696e67b5UL, 0xdaddd39bUL, 0x2f057edfUL, 0x1c7025dbUL, 0xee515e1bUL, 0xe62453f6UL, 0x6ce3fc6aUL, 0x04cc1603UL,
+0x3e214486UL, 0xd059dcb7UL, 0x1f296579UL, 0x43fdd6ccUL, 0x79398241UL, 0xf6cd2b93UL, 0x4dc357b6UL, 0x82d2df4eUL,
+0x0c29e57aUL, 0x6b53b93cUL, 0xfe201e85UL, 0x7e553398UL, 0xb0f0ec13UL, 0x72b3ffd3UL, 0xc1c5853fUL, 0xd27eef0aUL};
+
+#endif
+
+/*********************************************************************************************************/
+
+#ifdef BIG_ENDIAN
+
+uint32_t s5[] PROGMEM = {
+0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, 0x44dd9d44UL, 0x1731167fUL,
+0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, 0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL,
+0xe6a2e77fUL, 0xf0c720cdUL, 0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL,
+0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, 0x8dba1cfeUL, 0x41a99b02UL,
+0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, 0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL,
+0xf2f3f763UL, 0x68af8040UL, 0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL,
+0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, 0x2261be02UL, 0xd642a0c9UL,
+0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, 0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL,
+0x5c1ff900UL, 0xfe38d399UL, 0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL,
+0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, 0xdfdd55bcUL, 0x29de0655UL,
+0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, 0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL,
+0xbcf3f0aaUL, 0x87ac36e9UL, 0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL,
+0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, 0xf24766e3UL, 0x8eca36c1UL,
+0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, 0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL,
+0x26e46695UL, 0xb7566419UL, 0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL,
+0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, 0x68cb3e47UL, 0x086c010fUL,
+0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, 0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL,
+0x0ab378d5UL, 0xd951fb0cUL, 0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL,
+0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, 0x646c6bd7UL, 0x44904db3UL,
+0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, 0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL,
+0x76f0ae02UL, 0x083be84dUL, 0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL,
+0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, 0x9cad9010UL, 0xaf462ba2UL,
+0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, 0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL,
+0x445f7382UL, 0x175683f4UL, 0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL,
+0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, 0x1ad2fff3UL, 0x8c25404eUL,
+0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, 0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL,
+0x44094f85UL, 0x3f481d87UL, 0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL,
+0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, 0x1b5ad7a8UL, 0xf61ed5adUL,
+0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, 0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL,
+0x5ce96c28UL, 0xe176eda3UL, 0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL,
+0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, 0x34010718UL, 0xbb30cab8UL,
+0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, 0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL};
+
+
+uint32_t s6[] PROGMEM = {
+0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, 0xeced5cbcUL, 0x325553acUL,
+0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, 0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL,
+0x33f14961UL, 0xc01937bdUL, 0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL,
+0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, 0xa888614aUL, 0x2900af98UL,
+0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, 0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL,
+0xfd41197eUL, 0x9305a6b0UL, 0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL,
+0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, 0x2c0e636aUL, 0xba7dd9cdUL,
+0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, 0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL,
+0x284caf89UL, 0xaa928223UL, 0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL,
+0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, 0x9a69a02fUL, 0x68818a54UL,
+0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, 0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL,
+0x53bddb65UL, 0xe76ffbe7UL, 0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL,
+0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, 0xfd339fedUL, 0xb87834bfUL,
+0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, 0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL,
+0x4ec75b95UL, 0x24f2c3c0UL, 0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL,
+0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, 0xe9a9d848UL, 0xf3160289UL,
+0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, 0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL,
+0x36f73523UL, 0x4cfb6e87UL, 0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL,
+0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, 0xdc049441UL, 0xc8098f9bUL,
+0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, 0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL,
+0xbf32679dUL, 0xd45b5b75UL, 0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL,
+0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, 0x3cc2acfbUL, 0x3fc06976UL,
+0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, 0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL,
+0x3007cd3eUL, 0x74719eefUL, 0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL,
+0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, 0xbc60b42aUL, 0x953498daUL,
+0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, 0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL,
+0xe8816f4aUL, 0x3814f200UL, 0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL,
+0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, 0x3a479c3aUL, 0x5302da25UL,
+0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, 0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL,
+0xb81a928aUL, 0x60ed5869UL, 0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL,
+0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, 0xb0e93524UL, 0xbebb8fbdUL,
+0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, 0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL};
+
+
+uint32_t s7[] PROGMEM = {
+0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, 0xde6008a1UL, 0x2028da1fUL,
+0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, 0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL,
+0xa05fbcf6UL, 0xcd4181e9UL, 0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL,
+0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, 0x1286becfUL, 0xb6eacb19UL,
+0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, 0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL,
+0x107789beUL, 0xb3b2e9ceUL, 0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL,
+0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, 0xd0d854c0UL, 0xcb3a6c88UL,
+0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, 0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL,
+0x0a961288UL, 0xe1a5c06eUL, 0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL,
+0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, 0xc6e6fa14UL, 0xbae8584aUL,
+0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, 0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL,
+0x92544a8bUL, 0x009b4fc3UL, 0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL,
+0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, 0x16746233UL, 0x3c034c28UL,
+0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, 0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL,
+0x0c4fb99aUL, 0xbb325778UL, 0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL,
+0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, 0xbe8b9d2dUL, 0x7979fb06UL,
+0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, 0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL,
+0xf28ebfb0UL, 0xf5b9c310UL, 0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL,
+0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, 0x488dcf25UL, 0x36c9d566UL,
+0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, 0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL,
+0xf22b017dUL, 0xa4173f70UL, 0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL,
+0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, 0x058745b9UL, 0x3453dc1eUL,
+0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, 0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL,
+0x66626c1cUL, 0x7154c24cUL, 0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL,
+0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, 0xe4f2dfa6UL, 0x693ed285UL,
+0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, 0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL,
+0xc79f022fUL, 0x3c997e7eUL, 0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL,
+0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, 0xcfd2a87fUL, 0x60aeb767UL,
+0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, 0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL,
+0x97fd61a9UL, 0xea7759f4UL, 0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL,
+0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, 0xc3c0bdaeUL, 0x4958c24cUL,
+0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, 0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL};
+
+
+uint32_t s8[] PROGMEM = {
+0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, 0x0e241600UL, 0x052ce8b5UL,
+0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, 0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL,
+0xde9adeb1UL, 0x0a0cc32cUL, 0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL,
+0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, 0x72df191bUL, 0x7580330dUL,
+0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, 0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL,
+0x12a8ddecUL, 0xfdaa335dUL, 0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL,
+0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, 0x57e8726eUL, 0x647a78fcUL,
+0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, 0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL,
+0xbbd35049UL, 0x2998df04UL, 0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL,
+0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, 0x424f7618UL, 0x35856039UL,
+0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, 0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL,
+0x7170c608UL, 0x2d5e3354UL, 0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL,
+0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, 0x7895cda5UL, 0x859c15a5UL,
+0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, 0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL,
+0x835ffcb8UL, 0x6df4c1f2UL, 0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL,
+0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, 0x7cd16efcUL, 0x1436876cUL,
+0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, 0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL,
+0xa842eedfUL, 0xfdba60b4UL, 0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL,
+0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, 0xbae7dfdcUL, 0x42cbda70UL,
+0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, 0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL,
+0x77853b53UL, 0x37effcb5UL, 0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL,
+0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, 0xc4248289UL, 0xacf3ebc3UL,
+0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, 0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL,
+0xe87b40e4UL, 0xe98ea084UL, 0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL,
+0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, 0xe0779695UL, 0xf9c17a8fUL,
+0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, 0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL,
+0x11403092UL, 0x00da6d77UL, 0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL,
+0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, 0xdf09822bUL, 0xbd691a6cUL,
+0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, 0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL,
+0x5938fa0fUL, 0x42399ef3UL, 0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL,
+0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, 0xa466bb1eUL, 0xf8da0a82UL,
+0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, 0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL};
+
+#else
+
+uint32_t s5[] PROGMEM = {
+0x040cc97eUL, 0xb9746e2cUL, 0xdf660e9bUL, 0x117933a6UL, 0xff7f6ab8UL, 0xf558d31dUL, 0x449ddd44UL, 0x7f163117UL,
+0xfaf1fb08UL, 0xcc11f5e7UL, 0x001b05d2UL, 0x00ba5a73UL, 0xd822b72aUL, 0xcb816338UL, 0x3a24f6acUL, 0x7afdbe69UL,
+0x7fe7a2e6UL, 0xcd20c7f0UL, 0x164849c4UL, 0x80c1f5ccUL, 0x40168538UL, 0x48a8b015UL, 0xcb188be6UL, 0xffdeaa4cUL,
+0x010a485fUL, 0xaab21204UL, 0xfc149825UL, 0xe2efd041UL, 0x8db4404eUL, 0xfbb68e24UL, 0xfe1cba8dUL, 0x029ba941UL,
+0x040a551aUL, 0xcb658fbaUL, 0xe7f45172UL, 0x2517a595UL, 0xd7ec06c1UL, 0x0a98a597UL, 0xaab939c5UL, 0x6afe794dUL,
+0x63f7f3f2UL, 0x4080af68UL, 0x569e0cedUL, 0x8b95b411UL, 0x885aebe1UL, 0xb0e60987UL, 0x5671e0d7UL, 0xa7fe294eUL,
+0x2de56663UL, 0x00c0d102UL, 0x058eacc4UL, 0x71f57793UL, 0x2a37050cUL, 0xf2358557UL, 0x02be6122UL, 0xc9a042d6UL,
+0x80a213dfUL, 0xd25bb574UL, 0xc0992168UL, 0xece521d4UL, 0xe83cfb53UL, 0xb3edadc8UL, 0xc97fa828UL, 0x8199953dUL,
+0x00f91f5cUL, 0x99d338feUL, 0x0bff4e0cUL, 0xea072406UL, 0xb14f2faaUL, 0x7669b94fUL, 0x0595c790UL, 0x74a7a8b0UL,
+0xffa155efUL, 0xc2a29ce5UL, 0x272db6a6UL, 0x63426ae6UL, 0x1f0065dfUL, 0x6609c50eUL, 0xbc55dddfUL, 0x5506de29UL,
+0x9a731e91UL, 0x7589af17UL, 0x1c91c732UL, 0x6894f889UL, 0x80e9010dUL, 0xf4554752UL, 0xc93cb603UL, 0xb244c80cUL,
+0xaaf0f3bcUL, 0xe936ac87UL, 0x26743ae5UL, 0x2bd8b301UL, 0x49749e1aUL, 0x7e2dee64UL, 0xdab1dbcdUL, 0x1049c901UL,
+0x80bf68b8UL, 0xfdf3260dUL, 0xe7ed4293UL, 0x84c2a504UL, 0xb6376763UL, 0x16b6f550UL, 0xe36647f2UL, 0xc136ca8eUL,
+0xdb056e13UL, 0x9183f1feUL, 0x377a88fbUL, 0xd4f7e7d6UL, 0xc97dfbc7UL, 0xdffc6330UL, 0xde89f5b6UL, 0xda4129ecUL,
+0x9566e426UL, 0x196456b7UL, 0xc5ef54f6UL, 0xb7588dd0UL, 0x01549248UL, 0x7fcbbac1UL, 0x0f55ffe5UL, 0x493008b6UL,
+0xe8d0b55bUL, 0x5a2ed787UL, 0xe16e6aabUL, 0xce663a22UL, 0xcdf32bc6UL, 0xf985089eUL, 0x473ecb68UL, 0x0f016c08UL,
+0x20e81da2UL, 0xde698bd1UL, 0x7757f6f3UL, 0xf6c302faUL, 0xc3da7e40UL, 0x50d5b3cbUL, 0x4d089317UL, 0xba0ed7b0UL,
+0xd578b30aUL, 0x0cfb51d9UL, 0x56dad7deUL, 0xe4bb2441UL, 0x560bca94UL, 0xd155570fUL, 0x6ee5e1e0UL, 0xbeb58461UL,
+0x9f240a58UL, 0xc04bf794UL, 0x8e8827e3UL, 0x61557b9fUL, 0x8002dcc3UL, 0x15776805UL, 0xd76b6c64UL, 0xb34d9044UL,
+0xa3f0b466UL, 0x8a64f1c0UL, 0xafd57e69UL, 0xf62fe949UL, 0x4f379e30UL, 0x6a35b62cUL, 0x73858085UL, 0x40f89149UL,
+0x02aef076UL, 0x4de83b08UL, 0x9a1c4228UL, 0x06944844UL, 0xb84c6e73UL, 0x102909c1UL, 0xc65fc98bUL, 0xf49c867dUL,
+0x6f614f13UL, 0x8d11772eUL, 0xe12b1bb3UL, 0x72b490aaUL, 0x17d7a53cUL, 0xba1b167dUL, 0x1090ad9cUL, 0xa22b46afUL,
+0xd259e49fUL, 0x5945d345UL, 0x13daf2d9UL, 0x8754c6dbUL, 0x4ef9e4f3UL, 0x6f486d17UL, 0xea137c09UL, 0xc7a51d63UL,
+0x82735f44UL, 0xf4835617UL, 0x976ac6cdUL, 0x8802be70UL, 0x72cfcdb3UL, 0xf3d25d6eUL, 0x79609320UL, 0xa5809b45UL,
+0xdbe260beUL, 0x0131c2a9UL, 0x5c31a5ebUL, 0xf2424e22UL, 0x72155c1cUL, 0x2c1b72f6UL, 0xf3ffd21aUL, 0x4e40258cUL,
+0x2fd74e32UL, 0xfdb76740UL, 0x8e132305UL, 0x78bca35cUL, 0x6ed60fdcUL, 0x83229275UL, 0x176b4d78UL, 0x6eb1eb58UL,
+0x854f0944UL, 0x871d483fUL, 0x7baefefcUL, 0x76ffb577UL, 0xbf02238cUL, 0x5675f4aaUL, 0x2ab0465fUL, 0x0128092bUL,
+0xf7f5383dUL, 0x361fa80cUL, 0x8a4aaf52UL, 0xc0e7d566UL, 0x74083bdfUL, 0x10510595UL, 0xa8d75a1bUL, 0xadd51ef6UL,
+0x79e4f66cUL, 0x84817520UL, 0x65faced0UL, 0x58bef788UL, 0x2668044aUL, 0xf3f8f60fUL, 0x707f9ca0UL, 0xa0ab4653UL,
+0x286ce95cUL, 0xa3ed76e1UL, 0x7f30ac6bUL, 0xd2296837UL, 0xa90f3685UL, 0x2afee317UL, 0x6797b724UL, 0x206ba9f5UL,
+0x9525cdd6UL, 0xbf1eff68UL, 0x2c445575UL, 0xbe069ff1UL, 0x9a65e0f9UL, 0x1d49b9eeUL, 0x18070134UL, 0xb8ca30bbUL,
+0x15fe22e8UL, 0x83095788UL, 0x49620e75UL, 0x557e62daUL, 0xa8ff765eUL, 0x464553b1UL, 0x08de476dUL, 0xd4e7e9efUL};
+
+
+uint32_t s6[] PROGMEM = {
+0x9d8ffaf6UL, 0xe16cac2cUL, 0x6748a34cUL, 0x7c7f33e2UL, 0xe708db95UL, 0xb4436801UL, 0xbc5cedecUL, 0xac535532UL,
+0x60099fbfUL, 0xede2a1dfUL, 0x9d57f083UL, 0xb986ed63UL, 0xb8a6b61aUL, 0x39be5edeUL, 0x32f78ff3UL, 0x38b18989UL,
+0x6149f133UL, 0xbd3719c0UL, 0xdac606f5UL, 0x7e5e62e4UL, 0x99ea08a3UL, 0x3ce3234eUL, 0xccd7cb79UL, 0x6743a148UL,
+0x199614a3UL, 0xd54bc9feUL, 0x4a1714a1UL, 0x6618a0eaUL, 0x2ddb84a0UL, 0x6f48a809UL, 0x4a6188a8UL, 0x98af0029UL,
+0x91596601UL, 0x632899e1UL, 0x600cf3c8UL, 0x3cef782eUL, 0x3219d5d0UL, 0x14ec0fcfUL, 0xd207caf7UL, 0x7220a8d0UL,
+0x7e1941fdUL, 0xb0a60593UL, 0xdae36be8UL, 0xcdd3be74UL, 0x3ca52d37UL, 0x48447f4cUL, 0x40d4b5daUL, 0xc30eba6dUL,
+0xa7193908UL, 0xd9eeba9fUL, 0xb0cfdb49UL, 0x530c674eUL, 0x019c3d5cUL, 0x41b9bd64UL, 0x6a630e2cUL, 0xcdd97dbaUL,
+0x88736feaUL, 0x62c70be7UL, 0xdb9af235UL, 0x8ddd4c5cUL, 0x8c8dd4f0UL, 0xe25381b8UL, 0x6698a108UL, 0xc8eae21aUL,
+0x89af4c28UL, 0x238292aaUL, 0x53be3493UL, 0xbf213a3bUL, 0xe34b4316UL, 0x0639ea9aUL, 0x6ec3e8efUL, 0xd9cd90f8UL,
+0xae6d2280UL, 0xa3a440c3UL, 0x099c7edfUL, 0x07a894a6UL, 0xcc5e7c5bUL, 0xa6b31d22UL, 0x2fa0699aUL, 0x548a8168UL,
+0x6f29b2ceUL, 0x3a84c053UL, 0x553689feUL, 0x8ae6bf25UL, 0xbc8a62b4UL, 0xbf2e22cfUL, 0x486fac25UL, 0x8793a9a9UL,
+0x65dbbd53UL, 0xe7fb6fe7UL, 0x78fd67e9UL, 0x6335a90bUL, 0xc12b348eUL, 0xe91ba1e8UL, 0x0d748049UL, 0xfc7d08c8UL,
+0x99bfe48dUL, 0xa00111a1UL, 0x7579d37fUL, 0xc0265adaUL, 0x4f991fe8UL, 0x89cd2895UL, 0xed9f33fdUL, 0xbf3478b8UL,
+0x6d45045fUL, 0x98862522UL, 0x3bc8c4c9UL, 0xbe56c12dUL, 0xaa8d624fUL, 0xc55ef557UL, 0xbe0a22e2UL, 0xbf6e91d2UL,
+0x955bc74eUL, 0xc0c3f224UL, 0x995dd142UL, 0xa07f0dcdUL, 0xff276e7bUL, 0xf08adca8UL, 0x06c14573UL, 0x2f231ef4UL,
+0x86231635UL, 0x2689eae6UL, 0x94b03333UL, 0xf2c67e15UL, 0xaf742b37UL, 0xe4732569UL, 0x48d8a9e9UL, 0x890216f3UL,
+0x1def623aUL, 0x38e287a7UL, 0x76f6a5f3UL, 0x53483674UL, 0x63109520UL, 0x8d697645UL, 0x07d4fab6UL, 0x50f92a59UL,
+0x2335f736UL, 0x876efb4cUL, 0xc0cea47dUL, 0xaa2d156cUL, 0xa89603cbUL, 0x5dfe0dc5UL, 0xab07d7fcUL, 0x2fc42109UL,
+0xbbf0df89UL, 0x78bee25fUL, 0x334f8f44UL, 0xc9134675UL, 0x8dd0052bUL, 0x85d5b948UL, 0x419404dcUL, 0x9b8f09c8UL,
+0x86e7ed7dUL, 0x73339ac3UL, 0x05004142UL, 0x5117096aUL, 0xa6c8f30eUL, 0xd6720089UL, 0x82762028UL, 0xbef7a9a9UL,
+0x9d6732bfUL, 0x755b5bd4UL, 0x00fd53b3UL, 0x58e3b0cbUL, 0x0a220f83UL, 0x14b28f1fUL, 0x08cf72d3UL, 0x134a3cccUL,
+0x6631f68cUL, 0xbe871c06UL, 0x888fc988UL, 0x97e36260UL, 0x7a8ecf47UL, 0x8352c8b6UL, 0xfbacc23cUL, 0x7669c03fUL,
+0x52028f4eUL, 0x4d31d864UL, 0xe37038daUL, 0x5954661eUL, 0xf00809c1UL, 0xa5213051UL, 0xb7685b6cUL, 0xa08a2f82UL,
+0x3ecd0730UL, 0xef9e7174UL, 0x812687dcUL, 0xd4403307UL, 0xd92f437eUL, 0x41c25e0cUL, 0x6c280988UL, 0x91d892f5UL,
+0xf630a908UL, 0x05f37e95UL, 0xbdfffbb7UL, 0x6fe966c2UL, 0x98ace46fUL, 0xc0ec73b1UL, 0x2ab460bcUL, 0xda983495UL,
+0x12aea1fbUL, 0x36d74b2dUL, 0xabfa250fUL, 0xebfcf3a4UL, 0x239196e2UL, 0x3d0c7f25UL, 0x49af4893UL, 0xbc001436UL,
+0x4a6f81e8UL, 0x00f21438UL, 0x4340f9a3UL, 0xc2547a9cUL, 0x574f70bcUL, 0xf9e741daUL, 0x3ad35ac2UL, 0x84a0f454UL,
+0x05557fb1UL, 0xbe7c3559UL, 0xc815bdedUL, 0xabc5977fUL, 0xb5c75abaUL, 0xafdef6b6UL, 0x3a9c473aUL, 0x25da0253UL,
+0x6a7e3d65UL, 0x498d2654UL, 0xea77a451UL, 0x5bd51750UL, 0x885dd2d7UL, 0x766c1344UL, 0xc8a80404UL, 0x21a1e5b8UL,
+0x8a921ab8UL, 0x6958ed60UL, 0x965bc597UL, 0x1b99eceaUL, 0x13599329UL, 0xf1b7fd01UL, 0xfa8d8e08UL, 0xf5f6b69aUL,
+0x9fbf4c3bUL, 0xabe35d4aUL, 0x351d05e6UL, 0x55d8e1a0UL, 0xf14c6bd3UL, 0xebed44f5UL, 0x2435e9b0UL, 0xbd8fbbbeUL,
+0xcf62d7a2UL, 0x542fc949UL, 0x31f3b538UL, 0x54a42871UL, 0x05293948UL, 0xb81d5ba6UL, 0xbd971c85UL, 0x2fcf75d6UL};
+
+
+uint32_t s7[] PROGMEM = {
+0x1940e085UL, 0x67f52b33UL, 0xffbf2d66UL, 0x9356c6cfUL, 0x6f7f8d2aUL, 0x12c99babUL, 0xa10860deUL, 0x1fda2820UL,
+0xe7bc2702UL, 0x1629644dUL, 0x00c3fa18UL, 0x828bf150UL, 0x11cbb22cUL, 0x5ce732b2UL, 0xf295364bUL, 0xde0787b2UL,
+0xf6bc5fa0UL, 0xe98141cdUL, 0x0c2150e1UL, 0xbdf14ee2UL, 0x81c368b1UL, 0x89e7e4fdUL, 0xd8b0795cUL, 0x43fd8b1eUL,
+0x0150494dUL, 0x4143be38UL, 0x1dee3c91UL, 0x3f9ca792UL, 0xbe669708UL, 0xf4adeebaUL, 0xcfbe8612UL, 0x19cbeab6UL,
+0x00c26026UL, 0xe4bd6575UL, 0x7a1f2464UL, 0xa9dc4882UL, 0x66adb3c3UL, 0x86601328UL, 0xa8dfd80bUL, 0xf21c6d35UL,
+0xbe897710UL, 0xcee9b2b3UL, 0x8faa0205UL, 0x1e35c00bUL, 0x2af56b16UL, 0x82ff12ebUL, 0x116948e3UL, 0x16754dd3UL,
+0xff3a7b4eUL, 0x1b67435fUL, 0x37e0f69cUL, 0x83ac8149UL, 0xce664233UL, 0xb741938cUL, 0xc054d8d0UL, 0x886c3acbUL,
+0x2928bc47UL, 0x37ba2547UL, 0x2bd26aa6UL, 0x1e1fd67aUL, 0xfaba5c0cUL, 0x07f13744UL, 0x6299e7b6UL, 0x16d8d242UL,
+0x8812960aUL, 0x6ec0a5e1UL, 0x679e7413UL, 0x1a08fc72UL, 0xf739d1b1UL, 0x453758f9UL, 0x58df19cfUL, 0x56f7c3beUL,
+0x30ba6ec0UL, 0x241b2107UL, 0x2988c245UL, 0x7f315ec9UL, 0x11c58ebcUL, 0xe946bc38UL, 0x14fae6c6UL, 0x4a58e8baUL,
+0x46bc4eadUL, 0x8b508f46UL, 0x5f432978UL, 0x3b1824f1UL, 0x9fba1d82UL, 0xf40ff6afUL, 0x6d4e2ceaUL, 0x6492e316UL,
+0x8b4a5492UL, 0xc34f9b00UL, 0xed8ca6abUL, 0x786fc99aUL, 0x9ab7a506UL, 0x6e6e85b2UL, 0xa93cec1aUL, 0x888683beUL,
+0xe904080eUL, 0x56bef155UL, 0x3b36e5e7UL, 0x5df2a1b3UL, 0x85bbdef7UL, 0x3c03fe61UL, 0x33627416UL, 0x284c033cUL,
+0x740c6ddaUL, 0x6cc5aa79UL, 0xade1e43cUL, 0x02c8f051UL, 0x5af3f898UL, 0x9fa42616UL, 0x292bd8eeUL, 0xe32f381dUL,
+0x9ab94f0cUL, 0x785732bbUL, 0x7bd9c63eUL, 0xa9a6776eUL, 0x5c8b65cbUL, 0xc73052d4UL, 0x8b40d12bUL, 0xb73ec060UL,
+0x788d06b9UL, 0xf45437a3UL, 0x7dc830f4UL, 0x0213a7c8UL, 0x328c6db9UL, 0xbee7d4ebUL, 0x2d9d8bbeUL, 0x06fb7979UL,
+0x085322e7UL, 0x77cf758bUL, 0xa48def11UL, 0x58c883e0UL, 0x6f786b8dUL, 0xa617635aUL, 0xa0f75cfaUL, 0x3300da5dUL,
+0xb0bf8ef2UL, 0x10c3b9f5UL, 0x80c2eaa0UL, 0x7a76b908UL, 0xb0d2d9a3UL, 0x1742d379UL, 0x8d711a02UL, 0x6a33c69aUL,
+0x60fd1127UL, 0xe3508043UL, 0xa8089906UL, 0xc4ed7f3dUL, 0xef2b6d82UL, 0x7684eb4eUL, 0x25cf8d48UL, 0x66d5c936UL,
+0x414ee728UL, 0xca0a61c2UL, 0xcfa9493dUL, 0xdfb9e3baUL, 0xe68d5fb6UL, 0x64afae92UL, 0xe6d5c73aUL, 0x0905a89eUL,
+0x7d012bf2UL, 0x703f17a4UL, 0xc3161eddUL, 0xf9d7e015UL, 0x87b8b150UL, 0xd54f9f2bUL, 0x82ba5a62UL, 0x6279016aUL,
+0x9c1bc02eUL, 0xa98a4815UL, 0x40e716d7UL, 0x2c5a0540UL, 0x229ad293UL, 0x9abf2de3UL, 0xb9458705UL, 0x1edc5334UL,
+0x6e2999d6UL, 0x6fff6c49UL, 0x86499f1cUL, 0x07ede2dfUL, 0xd14272b8UL, 0xae7ede19UL, 0x1a563e05UL, 0x8c6fad15UL,
+0x1c6c6266UL, 0x4cc25471UL, 0x2a2b08eaUL, 0x3929eb93UL, 0xf0b0dc17UL, 0xaef2d458UL, 0xfb94a29eUL, 0x4c56cf52UL,
+0x66fe8398UL, 0x8105c42eUL, 0xc3533976UL, 0x2e69d601UL, 0x08c1a0d3UL, 0x0e16e7a1UL, 0xa6dff2e4UL, 0x85d23e69UL,
+0x98469074UL, 0xdd0e2b4cUL, 0x5676754fUL, 0x7833395dUL, 0x4f2332a1UL, 0x5d1c323dUL, 0x94e1f5c3UL, 0x0193264bUL,
+0x2f029fc7UL, 0x7e7e993cUL, 0x04954f5eUL, 0xbdfbfa3fUL, 0x0eadf776UL, 0xf4936629UL, 0x6fce1f3dUL, 0xbe451ec6UL,
+0x34abb5d3UL, 0xb7f92bf7UL, 0xc034041bUL, 0x67b5724eUL, 0x3da39255UL, 0x019322b5UL, 0x7fa8d2cfUL, 0x67b7ae60UL,
+0x6b381418UL, 0x3dc3bc30UL, 0x7dc0a038UL, 0xf20616fdUL, 0x9b5163c3UL, 0x90d39d58UL, 0xe6f87954UL, 0x47d6b81cUL,
+0xa961fd97UL, 0xf45977eaUL, 0x9d53572dUL, 0xcf589a56UL, 0xad634ee8UL, 0x781b2e46UL, 0x7ef88065UL, 0x147981f3UL,
+0xf455da91UL, 0xf330a240UL, 0x358f98d1UL, 0xd218e3b6UL, 0xbc50fa3fUL, 0x21f0403dUL, 0xaebdc0c3UL, 0x4cc25849UL,
+0xb2368f51UL, 0x70d3b184UL, 0x83ceed0fUL, 0xdada8d87UL, 0xc779a2f2UL, 0xe81be094UL, 0x4b6f7190UL, 0xa38a4b95UL};
+
+
+uint32_t s8[] PROGMEM = {
+0x0d3016e2UL, 0xfcffddbbUL, 0xbddaeba7UL, 0x95806435UL, 0xb7f88977UL, 0x1b12c1e6UL, 0x0016240eUL, 0xb5e82c05UL,
+0xb0cfa911UL, 0x112f95e5UL, 0x0a99e7ecUL, 0x74d18693UL, 0x1c93422aUL, 0x1181e376UL, 0x3aef2db1UL, 0xfcdddd37UL,
+0xb1de9adeUL, 0x2cc30c0aUL, 0x297019beUL, 0x4009a084UL, 0x0f3a24bbUL, 0xcf37d1b4UL, 0xf0794eb4UL, 0xfded9e04UL,
+0x5da1150bUL, 0x68310d48UL, 0x5adebb8bUL, 0x42ed9d66UL, 0x31e8ecc7UL, 0xe7958f3fUL, 0x1b19df72UL, 0x0d338075UL,
+0x51420794UL, 0xfacd7d5cUL, 0x636dbeabUL, 0x642140aaUL, 0x0ad401b3UL, 0xcad1e702UL, 0xae1d5753UL, 0xa282317aUL,
+0xecdda812UL, 0x5d33aafdUL, 0xe8436f17UL, 0xd446fb71UL, 0x22901238UL, 0xd49a94ceUL, 0xad6947b8UL, 0x62d85b96UL,
+0x55d0f382UL, 0x6797fb66UL, 0x4e0bb815UL, 0xa0475b1dUL, 0x6fe0fd4cUL, 0xb8c48ec2UL, 0x6e72e857UL, 0xfc787a64UL,
+0x445d8699UL, 0x93d58b60UL, 0x030e206cUL, 0xf65fdc39UL, 0xa3000b5dUL, 0xf2af63aeUL, 0x32d68b7eUL, 0x0c8c1070UL,
+0x4950d3bbUL, 0x04df9829UL, 0x2af40c98UL, 0x91f46d9bUL, 0x53dd7e9eUL, 0x48859106UL, 0x077ecb58UL, 0x2eef743bUL,
+0xb1ff2f52UL, 0xcc0847d2UL, 0xcd277e1cUL, 0x5b21eba4UL, 0xe2d2f13cUL, 0x387ab419UL, 0x18764f42UL, 0x39608535UL,
+0xe7de179dUL, 0xe635eb27UL, 0x7bf6afc9UL, 0xb8f5ba36UL, 0xcd67c409UL, 0xb11089c1UL, 0x7bbf1de1UL, 0xf81acd06UL,
+0x08c67071UL, 0x54335e2dUL, 0x5a49ded4UL, 0x06d0c664UL, 0x2cc6c0bcUL, 0xb30dd03dUL, 0x348f8f70UL, 0x421bd577UL,
+0x0f624f26UL, 0xbfd2b824UL, 0x9eb7c115UL, 0x6425a546UL, 0x4ee5d7f8UL, 0x6081373eUL, 0xa5cd9578UL, 0xa5159c85UL,
+0x889745e6UL, 0x5fc77bc3UL, 0x0cba07dbUL, 0xaba37606UL, 0x1e9b227fUL, 0x7b2e8431UL, 0xd79f2524UL, 0x72f4bef8UL,
+0xb8fc5f83UL, 0xf2c1f46dUL, 0x95b1f596UL, 0xfcf00afdUL, 0x4c13feb0UL, 0x3d6d50e2UL, 0xea129b4fUL, 0x25f215f2UL,
+0x6f7323a2UL, 0x28c4b49fUL, 0x7949d025UL, 0xf813c734UL, 0x878161c4UL, 0x986e7aeaUL, 0xfc6ed17cUL, 0x6c873614UL,
+0x074154f1UL, 0x14eedebeUL, 0x27afe956UL, 0x41a44aa0UL, 0x99c8f73cUL, 0xe6baec92UL, 0x6d0167ddUL, 0xeb821615UL,
+0xdfee42a8UL, 0xb460bafdUL, 0x757b90f1UL, 0x0f03e320UL, 0x9ec2d824UL, 0x3b6739e1UL, 0xb83fa6efUL, 0x54308771UL,
+0x3bcff2b6UL, 0x4264329fUL, 0xcca415cbUL, 0x04451ab0UL, 0x8d7de4f1UL, 0xe51b4a84UL, 0xdcdfe7baUL, 0x70dacb42UL,
+0x0aae7dcdUL, 0x7a5be857UL, 0xf65a3fd5UL, 0x8c4dcf20UL, 0x28d4a4ceUL, 0xa430d179UL, 0xfbeb8634UL, 0xdccdd333UL,
+0x533b8577UL, 0xb5fcef37UL, 0x788706c5UL, 0xe6b380e5UL, 0xf4b8684eUL, 0x7eb3c8c5UL, 0xa29e800dUL, 0x7ceb8f39UL,
+0x944f2a13UL, 0x0e95b743UL, 0x1c7dee2fUL, 0xbd133622UL, 0xa2ca06ddUL, 0x2b93df37UL, 0x898224c4UL, 0xc3ebf3acUL,
+0xb7f61557UL, 0xdd7834efUL, 0x6f6167f2UL, 0xe4cb48c1UL, 0x5e815290UL, 0xab0f415eUL, 0x65248ab4UL, 0xa47fda2eUL,
+0xe4407be8UL, 0x84a08ee9UL, 0xe1e98958UL, 0xfc90d3efUL, 0x5bd307ddUL, 0x945648dbUL, 0xb2e5d738UL, 0x01017257UL,
+0xbcde0e73UL, 0x1331645bUL, 0x4f7e9194UL, 0xba2f3c50UL, 0x82126f64UL, 0x4ad22375UL, 0x959677e0UL, 0x8f7ac1f9UL,
+0x21215b7aUL, 0x96b887d1UL, 0x4d3a2629UL, 0xdf0c51baUL, 0x9f7cf481UL, 0xed6311adUL, 0x65597beaUL, 0x6e72001aUL,
+0x92304011UL, 0x776dda00UL, 0x61dd0c4aUL, 0x03461fadUL, 0xb0df5b60UL, 0x64c3ed9eUL, 0xa8e6eb22UL, 0x8ad2e7ceUL,
+0xa036e7a0UL, 0xb9a66455UL, 0x09328510UL, 0x378febc7UL, 0xca05e72dUL, 0x0f575189UL, 0x2b8209dfUL, 0x6c1a69bdUL,
+0xf2e412aaUL, 0x0f1c4587UL, 0x7aa2f6e0UL, 0x1948da3aUL, 0x4f76f14cUL, 0x2b1c770dUL, 0x56b1cd67UL, 0x84830d35UL,
+0x0ffa3859UL, 0xf39e3942UL, 0x077b9936UL, 0x3d09840eUL, 0x613ea94aUL, 0x7bd86083UL, 0x0c8ba91fUL, 0x2c384911UL,
+0xa52576e9UL, 0xb7d11406UL, 0x4b24250eUL, 0x4783760cUL, 0x828d9e58UL, 0xd159200dUL, 0x1ebb66a4UL, 0x820adaf8UL,
+0x3091f104UL, 0xc04e6ebaUL, 0x64512699UL, 0x0d23e71eUL, 0x80adb250UL, 0x0168eeeaUL, 0x83a2b28dUL, 0x9ef58beaUL};
+
+
+#endif 
+
+
+#endif
+
diff --git a/cast5.c b/cast5.c
new file mode 100644 (file)
index 0000000..ebe1ce6
--- /dev/null
+++ b/cast5.c
@@ -0,0 +1,444 @@
+/* 
+ * File:       cast5.c
+ * Author:     Daniel Otte
+ * Date:       26.07.2006
+ * License: GPL
+ * Description: Implementation of the CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144
+ * 
+ */
+ //pgm_read_dword
+ #include <stdint.h>
+ #include <string.h>
+ #include "cast5.h"
+ #include "config.h"
+ #include "uart.h"
+ #include "debug.h"
+ #undef DEBUG
+#include "cast5-sbox.h"
+
+
+#define S5(x) pgm_read_dword(&s5[(x)])
+#define S6(x) pgm_read_dword(&s6[(x)])
+#define S7(x) pgm_read_dword(&s7[(x)])
+#define S8(x) pgm_read_dword(&s8[(x)])
+
+void cast5_init_A(uint8_t *dest, uint8_t *src, bool bmode){
+       uint8_t mask = bmode?0x8:0;
+       *((uint32_t*)(&dest[0x0])) = *((uint32_t*)(&src[0x0^mask])) ^ S5(src[0xD^mask]) ^ S6(src[0xF^mask]) ^ S7(src[0xC^mask]) ^ S8(src[0xE^mask]) ^ S7(src[0x8^mask]);
+       *((uint32_t*)(&dest[0x4])) = *((uint32_t*)(&src[0x8^mask])) ^ S5(dest[0x0]) ^ S6(dest[0x2]) ^ S7(dest[0x1]) ^ S8(dest[0x3]) ^ S8(src[0xA^mask]);
+       *((uint32_t*)(&dest[0x8])) = *((uint32_t*)(&src[0xC^mask])) ^ S5(dest[0x7]) ^ S6(dest[0x6]) ^ S7(dest[0x5]) ^ S8(dest[0x4]) ^ S5(src[0x9^mask]);
+       *((uint32_t*)(&dest[0xC])) = *((uint32_t*)(&src[0x4^mask])) ^ S5(dest[0xA]) ^ S6(dest[0x9]) ^ S7(dest[0xB]) ^ S8(dest[0x8]) ^ S6(src[0xB^mask]);
+}
+
+void cast5_init_M(uint8_t *dest, uint8_t *src, bool nmode, bool xmode){
+       uint8_t nmt[] = {0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4}; /* nmode table */
+       uint8_t xmt[4][4] = {{0x2, 0x6, 0x9, 0xC}, {0x8, 0xD, 0x3, 0x7}, {0x3, 0x7, 0x8, 0xD}, {0x9, 0xC, 0x2, 0x6}};
+       #define NMT(x) (src[nmode?nmt[(x)]:(x)])
+       #define XMT(x) (src[xmt[(xmode<<1) + nmode][(x)]])
+       *((uint32_t*)(&dest[0x0])) = S5(NMT(0x8)) ^ S6(NMT(0x9)) ^ S7(NMT(0x7)) ^ S8(NMT(0x6)) ^ S5(XMT(0));
+       *((uint32_t*)(&dest[0x4])) = S5(NMT(0xA)) ^ S6(NMT(0xB)) ^ S7(NMT(0x5)) ^ S8(NMT(0x4)) ^ S6(XMT(1));
+       *((uint32_t*)(&dest[0x8])) = S5(NMT(0xC)) ^ S6(NMT(0xD)) ^ S7(NMT(0x3)) ^ S8(NMT(0x2)) ^ S7(XMT(2));
+       *((uint32_t*)(&dest[0xC])) = S5(NMT(0xE)) ^ S6(NMT(0xF)) ^ S7(NMT(0x1)) ^ S8(NMT(0x0)) ^ S8(XMT(3));
+}
+
+#define S5B(x) pgm_read_byte(3+(uint8_t*)(&s5[(x)]))
+#define S6B(x) pgm_read_byte(3+(uint8_t*)(&s6[(x)]))
+#define S7B(x) pgm_read_byte(3+(uint8_t*)(&s7[(x)]))
+#define S8B(x) pgm_read_byte(3+(uint8_t*)(&s8[(x)]))
+
+void cast5_init_rM(uint8_t *klo, uint8_t *khi, uint8_t offset, uint8_t *src, bool nmode, bool xmode){
+       uint8_t nmt[] = {0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4}; /* nmode table */
+       uint8_t xmt[4][4] = {{0x2, 0x6, 0x9, 0xC}, {0x8, 0xD, 0x3, 0x7}, {0x3, 0x7, 0x8, 0xD}, {0x9, 0xC, 0x2, 0x6}};
+       uint8_t t, h=0; 
+       t = S5B(NMT(0x8)) ^ S6B(NMT(0x9)) ^ S7B(NMT(0x7)) ^ S8B(NMT(0x6)) ^ S5B(XMT(0));
+               klo[offset*2] |= (t & 0x0f);
+               h |= (t&0x10); h>>=1;
+       t = S5B(NMT(0xA)) ^ S6B(NMT(0xB)) ^ S7B(NMT(0x5)) ^ S8B(NMT(0x4)) ^ S6B(XMT(1));
+               klo[offset*2] |= (t<<4) & 0xf0;
+               h |= t&0x10; h>>=1;
+       t = S5B(NMT(0xC)) ^ S6B(NMT(0xD)) ^ S7B(NMT(0x3)) ^ S8B(NMT(0x2)) ^ S7B(XMT(2));
+               klo[offset*2+1] |= t&0xf;
+               h |= t&0x10; h>>=1;
+       t = S5B(NMT(0xE)) ^ S6B(NMT(0xF)) ^ S7B(NMT(0x1)) ^ S8B(NMT(0x0)) ^ S8B(XMT(3));
+               klo[offset*2+1] |= t<<4;
+               h |= t&0x10; h >>=1;
+       #ifdef DEBUG
+               uart_putstr("\r\n\t h="); uart_hexdump(&h,1);
+       #endif
+       khi[offset>>1] |= h<<((offset&0x1)?4:0);
+}
+
+#define S_5X(s) pgm_read_dword(&s5[BPX[(s)]])
+#define S_6X(s) pgm_read_dword(&s6[BPX[(s)]])
+#define S_7X(s) pgm_read_dword(&s7[BPX[(s)]])
+#define S_8X(s) pgm_read_dword(&s8[BPX[(s)]])
+
+#define S_5Z(s) pgm_read_dword(&s5[BPZ[(s)]])
+#define S_6Z(s) pgm_read_dword(&s6[BPZ[(s)]])
+#define S_7Z(s) pgm_read_dword(&s7[BPZ[(s)]])
+#define S_8Z(s) pgm_read_dword(&s8[BPZ[(s)]])
+
+
+
+
+void cast5_init(cast5_ctx_t* s, uint8_t* key, uint8_t keylength){
+        /* we migth return if the key is valid and if setup was sucessfull */
+       uint32_t x[4], z[4];
+       #define BPX ((uint8_t*)&(x[0]))
+       #define BPZ ((uint8_t*)&(z[0]))
+       s->shortkey = (keylength<=80);
+       /* littel endian only! */
+       memset(&(x[0]), 0 ,16); /* set x to zero */
+       memcpy(&(x[0]), key, keylength/8);
+       
+
+       /* todo: merge a and b and compress the whole stuff */
+       /***** A *****/
+       cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);      
+       /***** M *****/
+       cast5_init_M((uint8_t*)(&(s->mask[0])), (uint8_t*)(&z[0]), false, false);
+       /***** B *****/
+       cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
+       /***** N *****/
+       cast5_init_M((uint8_t*)(&(s->mask[4])), (uint8_t*)(&x[0]), true, false);
+       /***** A *****/
+       cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
+       /***** N' *****/
+       cast5_init_M((uint8_t*)(&(s->mask[8])), (uint8_t*)(&z[0]), true, true);
+       /***** B *****/
+       cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
+       /***** M' *****/
+       cast5_init_M((uint8_t*)(&(s->mask[12])), (uint8_t*)(&x[0]), false, true);
+       
+       /* that were the masking keys, now the rotation keys */
+       /* set the keys to zero */
+       memset(&(s->rotl[0]),0,8);
+       s->roth[0]=s->roth[1]=0;
+       /***** A *****/
+       cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
+       /***** M *****/
+       cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 0, (uint8_t*)(&z[0]), false, false);
+       /***** B *****/
+       cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
+       /***** N *****/
+       cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 1, (uint8_t*)(&x[0]), true, false);
+       /***** A *****/
+       cast5_init_A((uint8_t*)(&z[0]), (uint8_t*)(&x[0]), false);
+       /***** N' *****/
+       cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 2, (uint8_t*)(&z[0]), true, true);
+       /***** B *****/
+       cast5_init_A((uint8_t*)(&x[0]), (uint8_t*)(&z[0]), true);
+       /***** M' *****/
+       cast5_init_rM(&(s->rotl[0]), &(s->roth[0]), 3, (uint8_t*)(&x[0]), false, true);
+       /* done ;-) */
+}
+
+
+
+/********************************************************************************************************/
+
+#define ROTL32(a,n) ((a)<<(n) | (a)>>(32-(n)))
+#define CHANGE_ENDIAN32(x) ((x)<<24 | (x)>>24 | ((x)&0xff00)<<8 | ((x)&0xff0000)>>8 )
+
+typedef uint32_t cast5_f_t(uint32_t,uint32_t,uint8_t);
+
+#define IA 3
+#define IB 2
+#define IC 1
+#define ID 0
+
+
+uint32_t cast5_f1(uint32_t d, uint32_t m, uint8_t r){
+       uint32_t t;
+       t = ROTL32((d + m),r);
+#ifdef DEBUG
+       uint32_t ia,ib,ic,id;
+       uart_putstr("\r\n f1("); uart_hexdump(&d, 4); uart_putc(',');
+               uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
+               uart_hexdump(&t, 4);
+       ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
+       ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
+       ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
+       id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
+       uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
+       uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
+       uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
+       uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
+
+       return (((ia ^ ib) - ic) + id);
+
+#else
+       
+       return (((pgm_read_dword(&s1[((uint8_t*)&t)[IA]] ) ^ pgm_read_dword(&s2[((uint8_t*)&t)[IB]] )) 
+               - pgm_read_dword(&s3[((uint8_t*)&t)[IC]] )) + pgm_read_dword(&s4[((uint8_t*)&t)[ID]]));
+
+#endif
+}
+
+
+uint32_t cast5_f2(uint32_t d, uint32_t m, uint8_t r){
+       uint32_t t;
+       t = ROTL32((d ^ m),r);
+#ifdef DEBUG
+       uint32_t ia,ib,ic,id;
+       uart_putstr("\r\n f2("); uart_hexdump(&d, 4); uart_putc(',');
+               uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
+               uart_hexdump(&t, 4);
+
+       ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
+       ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
+       ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
+       id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
+       
+       uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
+       uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
+       uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
+       uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
+
+       return (((ia - ib) + ic) ^ id);
+#else
+       
+       return (((pgm_read_dword(&s1[((uint8_t*)&t)[IA]] ) - pgm_read_dword(&s2[((uint8_t*)&t)[IB]] )) 
+               + pgm_read_dword(&s3[((uint8_t*)&t)[IC]] )) ^ pgm_read_dword(&s4[((uint8_t*)&t)[ID]]));
+
+#endif
+}
+
+uint32_t cast5_f3(uint32_t d, uint32_t m, uint8_t r){
+       uint32_t t;
+       t = ROTL32((m - d),r);
+
+#ifdef DEBUG
+       uint32_t ia,ib,ic,id;
+
+       uart_putstr("\r\n f3("); uart_hexdump(&d, 4); uart_putc(',');
+               uart_hexdump(&m , 4); uart_putc(','); uart_hexdump(&r, 1);uart_putstr("): I=");
+               uart_hexdump(&t, 4);
+
+       ia = pgm_read_dword(&s1[((uint8_t*)&t)[IA]] );
+       ib = pgm_read_dword(&s2[((uint8_t*)&t)[IB]] );
+       ic = pgm_read_dword(&s3[((uint8_t*)&t)[IC]] );
+       id = pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
+       
+       uart_putstr("\r\n\tIA="); uart_hexdump(&ia, 4);
+       uart_putstr("\r\n\tIB="); uart_hexdump(&ib, 4);
+       uart_putstr("\r\n\tIC="); uart_hexdump(&ic, 4);
+       uart_putstr("\r\n\tID="); uart_hexdump(&id, 4);
+       return (((ia + ib) ^ ic) - id);
+#else
+       return ((pgm_read_dword(&s1[((uint8_t*)&t)[IA]] ) + pgm_read_dword(&s2[((uint8_t*)&t)[IB]] )) 
+               ^ pgm_read_dword(&s3[((uint8_t*)&t)[IC]] )) - pgm_read_dword(&s4[((uint8_t*)&t)[ID]] );
+
+#endif
+}
+
+
+
+void cast5_enc(cast5_ctx_t *s, void* block){
+       uint32_t l,r, x, y;
+       uint8_t i;
+       cast5_f_t* f[]={cast5_f1,cast5_f2,cast5_f3};
+       l=((uint32_t*)block)[0];
+       r=((uint32_t*)block)[1];
+//     uart_putstr("\r\n round[-1] = ");
+//     uart_hexdump(&r, 4);
+       for (i=0;i<(s->shortkey?12:16);++i){
+               x = r;
+               y = (f[i%3])(CHANGE_ENDIAN32(r), CHANGE_ENDIAN32(s->mask[i]), 
+                       (((s->roth[i>>3]) & (1<<(i&0x7)))?0x10:0x00) 
+                        + ( ((s->rotl[i>>1])>>((i&1)?4:0)) & 0x0f) );
+               r = l ^ CHANGE_ENDIAN32(y);
+//             uart_putstr("\r\n round["); DEBUG_B(i); uart_putstr("] = ");
+//             uart_hexdump(&r, 4);
+               l = x;
+       }
+       ((uint32_t*)block)[0]=r;
+       ((uint32_t*)block)[1]=l;
+}
+
+
+void cast5_dec(cast5_ctx_t *s, void* block){
+       uint32_t l,r, x, y;
+       int8_t i, rounds;
+       cast5_f_t* f[]={cast5_f1,cast5_f2,cast5_f3};
+       l=((uint32_t*)block)[0];
+       r=((uint32_t*)block)[1];
+       rounds = (s->shortkey?12:16);
+       for (i=rounds-1; i>=0 ;--i){
+               x = r;
+               y = (f[i%3])(CHANGE_ENDIAN32(r), CHANGE_ENDIAN32(s->mask[i]), 
+                       (((s->roth[i>>3]) & (1<<(i&0x7)))?0x10:0x00) 
+                        + ( ((s->rotl[i>>1])>>((i&1)?4:0)) & 0x0f) );
+               r = l ^ CHANGE_ENDIAN32(y);
+               l = x;
+       }
+       ((uint32_t*)block)[0]=r;
+       ((uint32_t*)block)[1]=l;
+}
+
+
+/*********************************************************************************************************/
+/*********************************************************************************************************/
+/*********************************************************************************************************/
+
+#if 0
+
+void cast5_old_init(cast5_ctx_t* s, uint8_t* key, uint8_t keylength){
+        /* we migth return if the key is valid and if setup was sucessfull */
+       uint32_t x[4], z[4], t;
+       #define BPX ((uint8_t*)&(x[0]))
+       #define BPZ ((uint8_t*)&(z[0]))
+       s->shortkey = (keylength<=80);
+       /* littel endian only! */
+       memset(&(x[0]), 0 ,16); /* set x to zero */
+       memcpy(&(x[0]), key, keylength/8);
+       
+
+       /* todo: merge a and b and compress the whole stuff */
+       /***** A *****/
+       z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);        
+       z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
+       z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
+       z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
+       /***** M *****/
+       s->mask[0] = S_5Z(0x8) ^ S_6Z(0x9) ^ S_7Z(0x7) ^ S_8Z(0x6) ^ S_5Z(0x2);
+       s->mask[1] = S_5Z(0xA) ^ S_6Z(0xB) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_6Z(0x6);
+       s->mask[2] = S_5Z(0xC) ^ S_6Z(0xD) ^ S_7Z(0x3) ^ S_8Z(0x2) ^ S_7Z(0x9);
+       s->mask[3] = S_5Z(0xE) ^ S_6Z(0xF) ^ S_7Z(0x1) ^ S_8Z(0x0) ^ S_8Z(0xC);
+       /***** B *****/
+       x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
+       x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
+       x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
+       x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
+       /***** N *****/
+       s->mask[4] = S_5X(0x3) ^ S_6X(0x2) ^ S_7X(0xC) ^ S_8X(0xD) ^ S_5X(0x8);
+       s->mask[5] = S_5X(0x1) ^ S_6X(0x0) ^ S_7X(0xE) ^ S_8X(0xF) ^ S_6X(0xD);
+       s->mask[6] = S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x8) ^ S_8X(0x9) ^ S_7X(0x3);
+       s->mask[7] = S_5X(0x5) ^ S_6X(0x4) ^ S_7X(0xA) ^ S_8X(0xB) ^ S_8X(0x7);
+       /***** A *****/
+       z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
+       z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
+       z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
+       z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
+       /***** N' *****/
+       s->mask[8] = S_5Z(0x3) ^ S_6Z(0x2) ^ S_7Z(0xC) ^ S_8Z(0xD) ^ S_5Z(0x9);
+       s->mask[9] = S_5Z(0x1) ^ S_6Z(0x0) ^ S_7Z(0xE) ^ S_8Z(0xF) ^ S_6Z(0xC);
+       s->mask[10] = S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x8) ^ S_8Z(0x9) ^ S_7Z(0x2);
+       s->mask[11] = S_5Z(0x5) ^ S_6Z(0x4) ^ S_7Z(0xA) ^ S_8Z(0xB) ^ S_8Z(0x6);
+       /***** B *****/
+       x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
+       x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
+       x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
+       x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
+       /***** M' *****/
+       s->mask[12] = S_5X(0x8) ^ S_6X(0x9) ^ S_7X(0x7) ^ S_8X(0x6) ^ S_5X(0x3);
+       s->mask[13] = S_5X(0xA) ^ S_6X(0xB) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_6X(0x7);
+       s->mask[14] = S_5X(0xC) ^ S_6X(0xD) ^ S_7X(0x3) ^ S_8X(0x2) ^ S_7X(0x8);
+       s->mask[15] = S_5X(0xE) ^ S_6X(0xF) ^ S_7X(0x1) ^ S_8X(0x0) ^ S_8X(0xD);
+
+       /* that were the masking keys, now the rotation keys */
+       /* set the keys to zero */
+       memset(&(s->rotl[0]),0,8);
+       s->roth[0]=s->roth[1]=0;
+       /***** A *****/
+       z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
+       z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
+       z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
+       z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
+       /***** M *****/
+       t = S_5Z(0x8) ^ S_6Z(0x9) ^ S_7Z(0x7) ^ S_8Z(0x6) ^ S_5Z(0x2);
+       t >>= 24;
+       s->rotl[0] |= t & 0x0f;         
+       s->roth[0] |= (t >> 4) & (1<<0);
+       t = S_5Z(0xA) ^ S_6Z(0xB) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_6Z(0x6);
+       t >>= 24;
+       s->rotl[0] |= (t<<4) & 0xf0;
+       s->roth[0] |= (t >> 3) & (1<<1);
+       t = S_5Z(0xC) ^ S_6Z(0xD) ^ S_7Z(0x3) ^ S_8Z(0x2) ^ S_7Z(0x9);
+       t >>= 24;
+       s->rotl[1] |= t & 0x0f;         
+       s->roth[0] |= (t >> 2) & (1<<2);
+       t = S_5Z(0xE) ^ S_6Z(0xF) ^ S_7Z(0x1) ^ S_8Z(0x0) ^ S_8Z(0xC);
+       t >>= 24;
+       s->rotl[1] |= (t<<4) & 0xf0;
+       s->roth[0] |= (t >> 1) & (1<<3);
+       /***** B *****/
+       x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
+       x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
+       x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
+       x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
+       /***** N *****/
+       t = S_5X(0x3) ^ S_6X(0x2) ^ S_7X(0xC) ^ S_8X(0xD) ^ S_5X(0x8);
+       t >>= 24;
+       s->rotl[2] |= t & 0x0f;         
+       s->roth[0] |= t & (1<<4);
+       t = S_5X(0x1) ^ S_6X(0x0) ^ S_7X(0xE) ^ S_8X(0xF) ^ S_6X(0xD);
+       t >>= 24;
+       s->rotl[2] |= (t<<4) & 0xf0;            
+       s->roth[0] |= (t<<1) & (1<<5);
+       t = S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x8) ^ S_8X(0x9) ^ S_7X(0x3);
+       t >>= 24;
+       s->rotl[3] |= t & 0x0f;         
+       s->roth[0] |= (t<<2) & (1<<6);
+       t = S_5X(0x5) ^ S_6X(0x4) ^ S_7X(0xA) ^ S_8X(0xB) ^ S_8X(0x7);
+       t >>= 24;
+       s->rotl[3] |= (t<<4) & 0xf0;            
+       s->roth[0] |= (t<<3) & (1<<7);
+       /***** A *****/
+       z[0] = x[0] ^ S_5X(0xD) ^ S_6X(0xF) ^ S_7X(0xC) ^ S_8X(0xE) ^ S_7X(0x8);
+       z[1] = x[2] ^ S_5Z(0x0) ^ S_6Z(0x2) ^ S_7Z(0x1) ^ S_8Z(0x3) ^ S_8X(0xA);
+       z[2] = x[3] ^ S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x5) ^ S_8Z(0x4) ^ S_5X(0x9);
+       z[3] = x[1] ^ S_5Z(0xA) ^ S_6Z(0x9) ^ S_7Z(0xB) ^ S_8Z(0x8) ^ S_6X(0xB);
+       /***** N' *****/
+       t = S_5Z(0x3) ^ S_6Z(0x2) ^ S_7Z(0xC) ^ S_8Z(0xD) ^ S_5Z(0x9);
+       t >>= 24;
+       s->rotl[4] |= t & 0x0f;         
+       s->roth[1] |= (t>>4) & (1<<0);
+       t = S_5Z(0x1) ^ S_6Z(0x0) ^ S_7Z(0xE) ^ S_8Z(0xF) ^ S_6Z(0xC);
+       t >>= 24;
+       s->rotl[4] |= (t<<4) & 0xf0;            
+       s->roth[1] |= (t>>3) & (1<<1);
+       t = S_5Z(0x7) ^ S_6Z(0x6) ^ S_7Z(0x8) ^ S_8Z(0x9) ^ S_7Z(0x2);
+       t >>= 24;
+       s->rotl[5] |= t & 0x0f;         
+       s->roth[1] |= (t>>2) & (1<<2);
+       t = S_5Z(0x5) ^ S_6Z(0x4) ^ S_7Z(0xA) ^ S_8Z(0xB) ^ S_8Z(0x6);
+       t >>= 24;
+       s->rotl[5] |= (t<<4) & 0xf0;            
+       s->roth[1] |= (t>>1) & (1<<3);
+       /***** B *****/
+       x[0] = z[2] ^ S_5Z(0x5) ^ S_6Z(0x7) ^ S_7Z(0x4) ^ S_8Z(0x6) ^ S_7Z(0x0);
+       x[1] = z[0] ^ S_5X(0x0) ^ S_6X(0x2) ^ S_7X(0x1) ^ S_8X(0x3) ^ S_8Z(0x2);
+       x[2] = z[1] ^ S_5X(0x7) ^ S_6X(0x6) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_5Z(0x1);
+       x[3] = z[3] ^ S_5X(0xA) ^ S_6X(0x9) ^ S_7X(0xB) ^ S_8X(0x8) ^ S_6Z(0x3);
+       /***** M' *****/
+       t = S_5X(0x8) ^ S_6X(0x9) ^ S_7X(0x7) ^ S_8X(0x6) ^ S_5X(0x3);
+       t >>= 24;
+       s->rotl[6] |= t & 0x0f;         
+       s->roth[1] |= t & (1<<4);
+       t = S_5X(0xA) ^ S_6X(0xB) ^ S_7X(0x5) ^ S_8X(0x4) ^ S_6X(0x7);
+       t >>= 24;
+       s->rotl[6] |= (t<<4) & 0xf0;            
+       s->roth[1] |= (t<<1) & (1<<5);
+       t = S_5X(0xC) ^ S_6X(0xD) ^ S_7X(0x3) ^ S_8X(0x2) ^ S_7X(0x8);
+       t >>= 24;
+       s->rotl[7] |= t & 0x0f;         
+       s->roth[1] |= (t<<2) & (1<<6);
+       t = S_5X(0xE) ^ S_6X(0xF) ^ S_7X(0x1) ^ S_8X(0x0) ^ S_8X(0xD);
+       t >>= 24;
+       s->rotl[7] |= (t<<4) & 0xf0;            
+       s->roth[1] |= (t<<3) & (1<<7);
+       
+       /* done ;-) */
+}
+
+#endif
+
+
+
+
diff --git a/cast5.h b/cast5.h
new file mode 100644 (file)
index 0000000..8f34ced
--- /dev/null
+++ b/cast5.h
@@ -0,0 +1,40 @@
+/* 
+ * File:       cast5.h
+ * Author:     Daniel Otte
+ * Date:       26.07.2006
+ * License: GPL
+ * Description: Implementation of the CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144
+ * 
+ */
+#ifndef CAST5_H_
+#define CAST5_H_ 
+
+#include <stdint.h> 
+
+#ifndef BOOL
+#define BOOL
+ #ifndef __BOOL
+ #define __BOOL
+  #ifndef __BOOL__
+  #define __BOOL__
+       typedef enum{false=0,true=1} bool;
+  #endif
+ #endif
+#endif
+
+
+typedef struct cast5_ctx_st{
+       uint32_t        mask[16];
+       uint8_t         rotl[8];        /* 4 bit from every rotation key is stored here */
+       uint8_t         roth[2];        /* 1 bit from every rotation key is stored here */
+       bool            shortkey;
+} cast5_ctx_t;
+
+void cast5_init(cast5_ctx_t* s, uint8_t* key, uint8_t keylength);
+void cast5_enc(cast5_ctx_t *s, void* block);
+void cast5_dec(cast5_ctx_t *s, void* block);
+
+
+
+#endif
+
diff --git a/config.h b/config.h
new file mode 100644 (file)
index 0000000..58e9b04
--- /dev/null
+++ b/config.h
@@ -0,0 +1,27 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+#include <avr/io.h>
+
+#define F_CPU 16000000         // Oszillator-Frequenz in Hz
+
+#define DEBUG uart
+
+//c uart.[ch] defines
+#define UART_INTERRUPT 1
+#define UART_BAUD_RATE 2400
+#define UART_RXBUFSIZE 16
+#define UART_TXBUFSIZE 16
+#define UART_LINE_BUFFER_SIZE 40
+#undef UART_LEDS
+/*
+#define UART_HWFLOWCONTROL
+#define UART_RTS_PORT PORTA
+#define UART_RTS_DDR DDRA
+#define UART_CTS_PIN PINA
+#define UART_CTS_DDR DDRA
+#define UART_RTS_BIT 0
+#define UART_CTS_BIT 1
+*/
+
+#endif
+
diff --git a/debug.c b/debug.c
new file mode 100644 (file)
index 0000000..1507e94
--- /dev/null
+++ b/debug.c
@@ -0,0 +1,46 @@
+/***************************
+*
+*
+*
+****************************/
+#include "config.h"
+
+#if DEBUG == uart
+ #include "uart.h"
+#else
+  #error "Your DEBUG methode is not suported!"
+#endif
+
+#ifdef DEBUG
+ void debug_init(void){
+ #if DBUG==uart
+  uart_init();
+ #else
+  #error "Your DEBUG methode is not suported!"
+ #endif
+ }
+ void debug_char(char c){
+       static char initialised = 0;
+       if (!initialised){
+               uart_init();
+               initialised=1;
+       }       
+       uart_putc(c);
+ }
+ void debug_str(char* s){
+       while (*s)
+               debug_char(*s++);
+ }
+
+
+ void debug_byte(char b){
+       char table[] = "0123456789ABCDEF";
+       debug_char(table[(b>>4) & 0xf]);
+       debug_char(table[b&0xf]);
+ }
+
+#endif //DEBUG
+
diff --git a/debug.h b/debug.h
new file mode 100644 (file)
index 0000000..c75dad6
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,22 @@
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+#ifdef DEBUG
+       #define DEBUG_INIT() debug_init()
+       #define DEBUG_C(_c) debug_char(_c)
+       #define DEBUG_S(_s) debug_str(_s)
+       #define DEBUG_B(_b) debug_byte(_b)
+#else
+       #define DEBUG_INIT()
+       #define DEBUG_C(_c) 
+       #define DEBUG_S(_s) 
+       #define DEBUG_B(_b) 
+#endif
+
+
+void debug_init(void);
+void debug_char(char);
+void debug_str(char*);
+void debug_byte(char);
+
+#endif /*DEBUG_H_*/
diff --git a/hmac-sha256.c b/hmac-sha256.c
new file mode 100644 (file)
index 0000000..3483f12
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * 
+ * implementation of HMAC as described in RFC2104
+ * Author:     Daniel Otte
+ * 
+ * License:    GPL
+ **/
+
+/* 
+ * hmac = hash ( k^opad , hash( k^ipad  , msg))
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sha256.h"
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+typedef sha256_ctx_t hmac_sha256_ctx_t;
+
+void hmac_sha256_init(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
+       uint8_t buffer[SHA256_BLOCK_BITS/8];
+       uint8_t i;
+       
+       if (kl > SHA256_BLOCK_BITS){
+               sha256((void*)buffer, key, kl);
+       } else {
+               memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
+       }
+       
+       for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
+               buffer[i] ^= IPAD;
+       }
+       
+       sha256_init(s);
+       sha256_nextBlock(s, buffer);
+#if defined SECURE_WIPE_BUFFER
+       memset(buffer, 0, SHA256_BLOCK_BITS/8);
+#endif
+}
+
+void hmac_sha256_final(hmac_sha256_ctx_t *s, void* key, uint16_t kl){
+       uint8_t buffer[SHA256_BLOCK_BITS/8];
+       uint8_t i;
+       sha256_ctx_t a;
+       
+       if (kl > SHA256_BLOCK_BITS){
+               sha256((void*)buffer, key, kl);
+       } else {
+               memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
+       }
+       
+       for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
+               buffer[i] ^= OPAD;
+       }
+       
+       sha256_init(&a);
+       sha256_nextBlock(&a, buffer); /* hash key ^ opad */
+       sha256_ctx2hash((void*)buffer, s);  /* copy hash(key ^ ipad, msg) to buffer */
+       sha256_lastBlock(s, buffer, SHA256_HASH_BITS);
+#if defined SECURE_WIPE_BUFFER
+       memset(buffer, 0, SHA256_BLOCK_BITS/8);
+       memset(a.h, 0, 8*4);
+#endif 
+}
+
+/*
+void hmac_sha256_nextBlock()
+void hmac_sha256_lastBlock()
+*/
+
+/*
+ * keylength in bits!
+ * message length in bits!
+ */
+void hmac_sha256(void* dest, void* key, uint16_t kl, void* msg, uint64_t ml){ /* a one-shot*/
+       sha256_ctx_t s;
+       uint8_t i;
+       uint8_t buffer[SHA256_BLOCK_BITS/8];
+       
+       /* if key is larger than a block we have to hash it*/
+       if (kl > SHA256_BLOCK_BITS){
+               sha256((void*)buffer, key, kl);
+       } else {
+               memcpy(buffer, key, kl/8 + (kl & 0x7)?1:0);
+       }
+       
+       for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
+               buffer[i] ^= IPAD;
+       }
+       sha256_init(&s);
+       sha256_nextBlock(&s, buffer);
+       while (ml >= SHA256_BLOCK_BITS){
+               sha256_nextBlock(&s, msg);
+               msg += SHA256_BLOCK_BITS/8;
+               ml -=  SHA256_BLOCK_BITS;
+       }
+       sha256_lastBlock(&s, msg, ml);
+       /* since buffer still contains key xor ipad we can do ... */
+       for (i=0; i<SHA256_BLOCK_BITS/8; ++i){
+               buffer[i] ^= IPAD ^ OPAD;
+       }
+       sha265_ctx2hash(dest, &s); /* save inner hash temporary to dest */
+       sha256_init(&s);
+       sha256_nextBlock(&s, buffer);
+       sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
+       sha265_ctx2hash(dest, &s);
+}
diff --git a/main-cast5-test.c b/main-cast5-test.c
new file mode 100644 (file)
index 0000000..2da7c1d
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * cast5 test-suit
+ * 
+*/
+
+#include "config.h"
+#include "serial-tools.h"
+#include "uart.h"
+#include "debug.h"
+
+#include "cast5.h"
+
+#include <stdint.h>
+#include <string.h>
+
+
+/*****************************************************************************
+ *  additional validation-functions                                                                                     *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *  self tests                                                                                                                          *
+ *****************************************************************************/
+
+void cast5_ctx_dump(cast5_ctx_t *s){
+       uint8_t i;
+       uart_putstr("\r\n==== cast5_ctx_dump ====\r\n shortkey: ");
+       uart_putstr(s->shortkey?"yes":"no");
+       for(i=0;i<16;++i){
+               uint8_t r;
+               uart_putstr("\r\n Km"); uart_hexdump(&i, 1); uart_putc(':');
+               uart_hexdump(&(s->mask[i]), 4);
+               uart_putstr("\r\n Kr"); uart_hexdump(&i, 1); uart_putc(':');
+               r = (s->rotl[i/2]);
+               if (i&0x01) r >>= 4;
+               r &= 0xf;
+               r += (s->roth[i>>3]&(1<<(i&0x7)))?0x10:0x00;
+               uart_hexdump(&r, 1);
+       }
+}
+
+
+void test_encrypt(uint8_t *block, uint8_t *key, uint8_t keylength, bool print){
+       cast5_ctx_t s;
+       if (print){
+               uart_putstr("\r\nCAST5:\r\n key:\t");
+               uart_hexdump(key, keylength/8);
+               uart_putstr("\r\n plaintext:\t");
+               uart_hexdump(block, 8);
+       }
+       cast5_init(&s, key, keylength);
+//     cast5_ctx_dump(&s);
+       cast5_enc(&s, block);
+       if (print){
+               uart_putstr("\r\n ciphertext:\t");
+               uart_hexdump(block, 8);
+       }
+} 
+
+void test_decrypt(uint8_t *block, uint8_t *key, uint8_t keylength, bool print){
+       cast5_ctx_t s;
+       if (print){
+               uart_putstr("\r\nCAST5:\r\n key:\t");
+               uart_hexdump(key, keylength/8);
+               uart_putstr("\r\n ciphertext:\t");
+               uart_hexdump(block, 8);
+       }
+       cast5_init(&s, key, keylength);
+//     cast5_ctx_dump(&s);
+       cast5_dec(&s, block);
+       if (print){
+               uart_putstr("\r\n plaintext:\t");
+               uart_hexdump(block, 8);
+       }
+} 
+
+void testrun_cast5(void){
+       uint8_t block[8];
+       uint8_t key[16];
+       uint8_t *tda = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+                       *tka = "\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A";
+       memcpy(block, tda, 8);
+       memcpy(key, tka, 16);
+       test_encrypt(block, key, 128, true);
+       test_decrypt(block, key, 128, true);
+       memcpy(block, tda, 8);
+       memcpy(key, tka, 16);
+       test_encrypt(block, key, 80, true);
+       test_decrypt(block, key, 80, true);
+       memcpy(block, tda, 8);
+       memcpy(key, tka, 16);
+       test_encrypt(block, key, 40, true);
+       test_decrypt(block, key, 40, true);
+       
+/**** long test *****/
+       uart_putstr("\r\nmaintance-test");
+       uint8_t a[16]= {0x01, 0x23, 0x45, 0x67, 0x12,
+                                   0x34, 0x56, 0x78, 0x23, 0x45, 
+                                   0x67, 0x89, 0x34, 0x56, 0x78, 
+                                   0x9A}, 
+                       b[16]= {0x01, 0x23, 0x45, 0x67, 0x12,
+                                   0x34, 0x56, 0x78, 0x23, 0x45, 
+                                   0x67, 0x89, 0x34, 0x56, 0x78, 
+                                   0x9A};
+       uint32_t i;
+       for(i=0;i<1000000; ++i){
+               test_encrypt(&(a[0]), &(b[0]), 128, false);
+               test_encrypt(&(a[8]), &(b[0]), 128, false);
+               test_encrypt(&(b[0]), &(a[0]), 128, false);
+               test_encrypt(&(b[8]), &(a[0]), 128, false);
+               if ((i&0x000000ff) == 0){
+                       uart_putstr("\r\n");
+                       uart_hexdump(&i, 4);
+               }
+       }
+       uart_putstr("\r\na = "); uart_hexdump(a, 16);
+       uart_putstr("\r\nb = "); uart_hexdump(b, 16);
+
+}
+
+
+
+/*****************************************************************************
+ *  main                                                                                                                                        *
+ *****************************************************************************/
+
+int main (void){
+       char str[20];
+
+       
+       DEBUG_INIT();
+       uart_putstr("\r\n");
+
+       uart_putstr("\r\n\r\nCrypto-VS\r\nloaded and running\r\n");
+restart:
+       while(1){ 
+               if (!getnextwordn(str,20))  {DEBUG_S("DBG: W1\r\n"); goto error;}
+               if (strcmp(str, "test")) {DEBUG_S("DBG: 1b\r\n"); goto error;}
+                       testrun_cast5();
+               goto restart;           
+               continue;
+       error:
+               uart_putstr("ERROR\r\n");
+       } /* while (1) */
+}
+
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..532e846
--- /dev/null
+++ b/main.c
@@ -0,0 +1,296 @@
+/*
+ * crypto-test
+ * 
+*/
+
+/* implemented:
+ *  
+ * xtea (C+ASM)
+ * SHA256 (C+ASM)
+ * ARCFOUR (C+ASM)
+ * HMAC-SHA256 (C)
+ * PRNG (C)
+ * 
+ */
+
+/* to implement:
+ *  -aes
+ *     -seal (broken?) 
+ *  -serpent
+ *  -cast
+ *  -des (???)
+ *     -twofish
+ *     -blowfish
+ *     -skipjack (???)
+ *     -idea (???)
+ *  -kasumi---
+ *  -camellia
+ * modes: cbc, ecb, ...
+ *  need Hashes, asymetrics, signatures, ...
+ */
+
+#include "config.h"
+#include "serial-tools.h"
+#include "uart.h"
+#include "debug.h"
+
+#include "sha256-asm.h"
+#include "xtea.h"
+#include "arcfour.h"
+#include "prng.h"
+#include "cast5.h"
+
+#include <stdint.h>
+#include <string.h>
+
+
+/*****************************************************************************
+ *  additional validation-functions                                                                                     *
+*****************************************************************************/
+
+void shavs_rnd(sha256_hash_t seed){
+       uint8_t md[4][SHA256_HASH_BITS/8], buffer[3*SHA256_HASH_BITS/8];
+       uint8_t j;
+       uint16_t i;
+       
+       for(j=0; j< 100; ++j){
+               memcpy(md[0], seed, SHA256_HASH_BITS/8);
+               memcpy(md[1], seed, SHA256_HASH_BITS/8);
+               memcpy(md[2], seed, SHA256_HASH_BITS/8);
+               for(i=3; i<1003; ++i){
+                       memcpy(buffer+0*(SHA256_HASH_BITS/8), md[(i-3)%4], SHA256_HASH_BITS/8);
+                       memcpy(buffer+1*(SHA256_HASH_BITS/8), md[(i-2)%4], SHA256_HASH_BITS/8);
+                       memcpy(buffer+2*(SHA256_HASH_BITS/8), md[(i-1)%4], SHA256_HASH_BITS/8);
+                       sha256(((void*)md[i%4]), buffer, 3*SHA256_HASH_BITS);
+                       uart_putc('.');
+               }
+               /* OUTPUT */
+               --i;
+               uart_putstr("\r\nMD = ");
+               uart_hexdump(md[i%4], SHA256_HASH_BITS/8);
+               uart_putstr("\r\n");
+               memcpy(seed, (md[i%4]), SHA256_HASH_BITS/8);
+       }
+}
+
+/*****************************************************************************
+ *  self tests                                                                                                                          *
+*****************************************************************************/
+void testrun_sha256(void){
+       uint8_t block[SHA256_BLOCK_BITS/8];
+       
+       uart_putstr("\r\nsha256(\"\", 0)= ");
+       sha256((void*)block, (void*)"\x00", 0);
+       uart_hexdump(block, SHA256_HASH_BITS/8);
+       
+       uart_putstr("\r\nsha256(\"abc\", 24)= ");
+       sha256((void*)block, (void*)"abc", 24);
+       uart_hexdump(block, SHA256_HASH_BITS/8);
+       
+       uart_putstr("\r\nsha256(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\", 24)= ");
+       sha256((void*)block, (void*) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 448);
+       uart_hexdump(block, SHA256_HASH_BITS/8);
+       
+       uart_putstr("\r\nsha256(1,000,000 x 'a')= ");
+       {
+               uint16_t i;
+               sha256_ctx_t s;
+               sha256_init(&s);
+               memset(block,'a',SHA256_BLOCK_BITS/8);
+               for(i=0; i<(1000000/(SHA256_BLOCK_BITS/8)); ++i){ /* 15625 times*/
+                       sha256_nextBlock(&s, block);
+               } 
+               sha256_lastBlock(&s, block, 0);
+               sha256_ctx2hash((void*)block, &s);
+       }
+       uart_hexdump(block, SHA256_HASH_BITS/8);
+}
+
+void testrun_xtea(void){
+       uint8_t block[8], block2[8];
+       uint8_t key [16];
+       
+       memcpy (block, "abcdefgh", 8);
+       memset (key, 0, 16);
+       memset (block2, 0, 8);
+       uart_putstr("\r\nxtea_enc(\"abcdefgh\", 0)= ");
+       xtea_enc((void*)block2, (void*)block, (void*)key);
+       uart_hexdump(block2, 8);
+       uart_putstr("\r\nxtea_dec(form above)= ");
+       xtea_dec((void*)block, (void*)block2, (void*)key);
+       uart_hexdump(block, 8);
+
+       memcpy (key, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16);
+       uart_putstr("\r\nxtea_enc(\"abcdefgh\", 000102030405060708090a0b0c0d0e0f)= ");
+       xtea_enc((void*)block, (void*)block, (void*)key);
+       uart_hexdump(block, 8);
+       uart_putstr("\r\nxtea_dec(form above)= ");
+       xtea_dec((void*)block, (void*)block, (void*)key);
+       uart_hexdump(block, 8); 
+}
+
+void testrun_arcfour(void){
+       arcfour_ctx_t s;
+       char *b;
+       /* using wikipedia test-vectors:
+        *      RC4( "Key", "Plaintext" ) == "bbf316e8 d940af0a d3"
+        *      RC4( "Wiki", "pedia" ) == "1021bf0420"
+        *      RC4( "Secret", "Attack at dawn" ) == "45a01f64 5fc35b38 3552544b 9bf5"
+        **/
+       uart_putstr("\r\narcfour(\"Plaintext\", \"Key\")=");
+       arcfour_init(&s, "Key", 3);
+       b="Plaintext";
+       while (*b)
+               *b++ ^= arcfour_gen(&s);
+       uart_hexdump(b-9, 9);
+       
+       uart_putstr("\r\narcfour(\"pedia\", \"Wiki\")=");
+       arcfour_init(&s, "Wiki", 4);
+       b="pedia";
+       while (*b)
+               *b++ ^= arcfour_gen(&s);
+       uart_hexdump(b-5, 5);
+       
+       uart_putstr("\r\narcfour(\"Attack at dawn\", \"Secret\")=");
+       arcfour_init(&s, "Secret", 6);
+       b="Attack at dawn";
+       while (*b)
+               *b++ ^= arcfour_gen(&s);
+       uart_hexdump(b-14, 14);
+       
+       uart_putstr("\r\narcfour(00.00.00.00.00.00.00.00, 01.23.45.67.89.AB.CD.EF)=");
+       arcfour_init(&s, "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8);
+       int i=0;
+       uint8_t a[8];
+       memset(a, 0 , 8);
+       while (i < 8)
+               a[i++] ^= arcfour_gen(&s);
+       uart_hexdump(a, 8);     
+}
+
+void testrun_prng(void){
+       uint8_t i,block[32];
+       uart_putstr("\r\naddEntropy(32, 0x00000000)");
+       addEntropy(32,"\x00\x00\x00\x00");
+       for(i=0;i<12;++i){
+               getRandomBlock((void*)block);
+               uart_putstr("\r\n");
+               uart_hexdump(block, 32);
+       }
+}
+
+void testrun_cast5(void){
+       cast5_ctx_t s;
+       uint8_t i;
+       uart_putstr("\r\nCAST5:\r\nkey: 01 23 45 67 34 56 78 23 45 67 89 34 56 78 9A");
+       cast5_init(&s, "\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A", 128);
+       uint8_t block[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+       uart_putstr("\r\nplaintext: ");
+       uart_hexdump(block, 8);
+       cast5_enc(&s, block);
+       uart_putstr("\r\nciphertext: ");
+       uart_hexdump(block, 8);
+       for(i=0; i<16; ++i){
+               uart_putstr("\r\nK"); uart_putc('0'+(i+1)/10); uart_putc('0'+(i+1)%10); uart_putstr(": ");
+               uart_hexdump(&(s.mask[i]),4);
+       }
+}
+
+/*****************************************************************************
+ *  main                                                                                                                                        *
+ *****************************************************************************/
+
+int main (void){
+       uint64_t length=0;
+       sha256_ctx_t s;
+       char str[20];
+       int i;
+       uint8_t block[SHA256_BLOCK_BITS/8];
+       
+       DEBUG_INIT();
+       
+       sha256_init(&s);
+       uart_putstr("\r\n");
+
+       uart_putstr("\r\n\r\nCrypto-VS\r\nloaded and running\r\n");
+restart:
+       while(1){ 
+               if (!getnextwordn(str,20))  {DEBUG_S("DBG: W1\r\n"); goto error;}
+               if (strcmp(str, "REQ")) {DEBUG_S("DBG: 1b\r\n"); goto error;}
+               if (!getnextwordn(str,20))  {DEBUG_S("DBG: W2\r\n"); goto error;}
+               if (strcmp(str, "SHA256")) {
+                       if (strcmp(str, "test")){DEBUG_S("DBG: 1d\r\n"); goto error;};
+                       /* use some fixed test-vectors and all Algos */
+                                       uart_putstr("\r\n intergrated selftests:\r\n");
+                               testrun_xtea();
+                                       uart_putstr("\r\n");
+                               testrun_prng();
+                                       uart_putstr("\r\n");
+                               testrun_cast5();
+                                       uart_putstr("\r\n");
+                               testrun_arcfour();
+                                       uart_putstr("\r\n");
+                               testrun_sha256();
+                       goto restart;
+               }
+               if (!getnextwordn(str,20)) {DEBUG_S("DBG: W4\r\n"); goto error;}
+               if (strcmp(str, "Len=")) {
+       /* 1d9370cdccba99b23670e2e0d6514001006f50d3c7a453201d2776f03c5e58fd */
+       /*      f41ece26 13e45739 15696b5a dcd51ca3
+               28be3bf5 66a9ca99 c9ceb027 9c1cb0a7
+        */
+                       if(strcmp(str, "rnd")){DEBUG_S("DBG: 2b\r\n"); goto error;}
+                       sha256_hash_t seed = {0x1d, 0x93, 0x70, 0xcd, 0xcc, 0xba, 0x99, 0xb2, 0x36, 0x70,
+                                                                 0xe2, 0xe0, 0xd6, 0x51, 0x40, 0x01, 0x00, 0x6f, 0x50, 0xd3,
+                                                         0xc7, 0xa4, 0x53, 0x20, 0x1d, 0x27, 0x76, 0xf0, 0x3c, 0x5e,
+                                                                 0x58, 0xfd  }; /*
+                               { 0xf4, 0x1e, 0xce, 0x26,  0x13, 0xe4, 0x57, 0x39,  0x15, 0x69, 0x6b, 0x5a,  0xdc, 0xd5, 0x1c, 0xa3, 
+                               0x28, 0xbe, 0x3b, 0xf5,  0x66, 0xa9, 0xca, 0x99,  0xc9, 0xce, 0xb0, 0x27,  0x9c, 0x1c, 0xb0, 0xa7 };
+                       //      */
+                       shavs_rnd(seed);
+                       goto restart;
+                       
+                       }
+               if (!getnextwordn(str,20)) {DEBUG_S("DBG: W5\r\n"); goto error;}
+               {       
+                       length=0;
+                       i=0;
+                       while (str[i]){ /* we should check for error here */
+                               length *= 10;
+                               length += str[i++] - '0';
+                       }
+               };
+//             DEBUG_S("\r\nDBG: Length="); DEBUG_B(length&0xff); DEBUG_S("\r\n");
+//             DEBUG_S("A");
+               sha256_init(&s);
+//             DEBUG_S("B");
+               if (!getnextwordn(str,20)) {DEBUG_S("DBG: W6\r\n"); goto error;}
+//             DEBUG_S("b2");
+               if (strcmp(str, "Msg=")) {DEBUG_S("DBG: 4b\r\n"); goto error;}  
+//             DEBUG_S("b3");
+               {
+                       memset(block, 0, SHA256_BLOCK_BITS/8);
+//                     DEBUG_S("b3.0");
+                       while (length>=SHA256_BLOCK_BITS){
+                               readhex2buffer(block, SHA256_BLOCK_BITS/8);
+//                     DEBUG_S("b3.1");
+                               sha256_nextBlock(&s, block); 
+//                     DEBUG_S("b3.2");
+                               length -= SHA256_BLOCK_BITS;
+                       }
+//             DEBUG_S("C");   
+                       readhex2buffer(block, (length/8) + ((length&0x7)?1:0) + ((length)?0:1));
+//             DEBUG_S("D");   
+                       sha256_lastBlock(&s, block, length);
+//             DEBUG_S("E");   
+                       sha256_ctx2hash((void*)block, &s);
+                       uart_putstr("\n\rMD= ");
+                       uart_hexdump(block, SHA256_HASH_BITS/8);
+                       uart_putstr("\n\r\n\r");
+               }               
+               continue;
+       error:
+               uart_putstr("ERROR\r\n");
+       } /* while (1) */
+}
+
diff --git a/md5.c b/md5.c
new file mode 100644 (file)
index 0000000..d26c806
--- /dev/null
+++ b/md5.c
@@ -0,0 +1,15 @@
+/* 
+ * File:       md5.h
+ * Author:     Daniel Otte
+ * Date:       31.07.2006
+ * License: GPL
+ * Description: Implementation of the MD5 hash algorithm as described in RFC 1321
+ * 
+ */
+
+ #include "md5.h"
+ #include <stdint.h>
\ No newline at end of file
diff --git a/md5.h b/md5.h
new file mode 100644 (file)
index 0000000..bd91f23
--- /dev/null
+++ b/md5.h
@@ -0,0 +1,14 @@
+/* 
+ * File:       md5.h
+ * Author:     Daniel Otte
+ * Date:       31.07.2006
+ * License: GPL
+ * Description: Implementation of the MD5 hash algorithm as described in RFC 1321
+ * 
+ */
+
+
+#ifndef MD5_H_
+#define MD5_H_
+
+#endif /*MD5_H_*/
diff --git a/prng.c b/prng.c
new file mode 100644 (file)
index 0000000..640c2ac
--- /dev/null
+++ b/prng.c
@@ -0,0 +1,95 @@
+/**
+ * File:               prng.c
+ * Author:             Daniel Otte
+ * Date:               17.05.2006
+ * License:            GPL
+ * Description:        This file contains an implementaition of a pseudo-random-number generator.
+ * Extension 1:
+ *     rndCore is expanded to 512 bits for more security.
+ **/
+
+
+/*
+ * 
+ *                      ####################################################################################
+ *                      #                                                                                                                                                     #
+ *                                         #             +---------------------------+                                                                                    #
+ *                                         #             |                                           |                                                                                    #
+ *                                         #             V                                           |                                                                                    #
+ *                      #      (concat)                                  |                                                                                        #
+ *  +---------------+   #    o---------o             (xor)+---------+      o---------o       o---------o   #    +--------------+
+ *  | entropy Block | -----> | sha-256 | --(offset)-<     | rndCore | ---> | sha-256 | --+-> | sha-256 | -----> | random Block |
+ *  +---------------+   #    o---------o             (xor)+---------+      o---------o   |   o---------o   #    +--------------+
+ *                                             #                                                     (xor)     (xor)                                    |                                 #
+ *                                             #                                                           ^     ^                                              |                                 #
+ *                                             #                                                            \   /                                               |                                 #
+ *                                             #                                                           (offset)---------------------+                                 #
+ *                                             #                                                                                                                                                      #
+ *                                             ####################################################################################
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sha256.h"
+
+
+
+
+uint32_t rndCore[16]; /* secret */
+
+/*
+ * idea is: hash the message and add it via xor to rndCore
+ *
+ * length in bits 
+ * 
+ * we simply first "hash" rndCore, then entropy.
+ */
+void addEntropy(unsigned length, void* data){
+       sha256_ctx_t s;
+       static uint8_t offset=0; /* selects if higher or lower half gets updated */
+       sha256_init(&s);
+       sha256_nextBlock(&s, rndCore);
+       while (length>=512){
+               sha256_nextBlock(&s, data);
+               data += 512/8;
+               length -= 512;  
+       }
+       sha256_lastBlock(&s, data, length);
+       uint8_t i;
+       for (i=0; i<8; ++i){
+               rndCore[i+offset] ^= s.h[i];
+       }
+       offset ^= 8; /* hehe */
+}
+void getRandomBlock(uint32_t *b){
+       sha256_ctx_t s;
+       uint8_t offset=8;
+       
+       sha256_init(&s);
+       sha256_lastBlock(&s, rndCore, 512); /* remeber the byte order! */
+       uint8_t i;
+       for (i=0; i<8; ++i){
+               rndCore[i+offset] ^= s.h[i];
+       }
+       offset ^= 8; /* hehe */
+       memcpy(b, s.h, 32); /* back up first hash in b */
+       sha256_init(&s);
+       sha256_lastBlock(&s, b, 256);
+       memcpy(b, s.h, 32);
+}
+/* this does some simple buffering */
+uint8_t getRandomByte(void){
+       static uint8_t block[32];
+       static uint8_t i=32;
+       
+       if (i==32){
+               getRandomBlock((void*)block);
+               i=0;
+       }       
+       return block[i++];
+}
diff --git a/prng.h b/prng.h
new file mode 100644 (file)
index 0000000..5266368
--- /dev/null
+++ b/prng.h
@@ -0,0 +1,22 @@
+/**
+ * File:               prng.h
+ * Author:             Daniel Otte
+ * Date:               23.07.2006
+ * License:            GPL
+ * Description:        This file contains the declarations for the pseudo-random-number generator.
+ **/
+
+#ifndef PRNG_H_
+#define PRNG_H_
+
+#include <stdint.h>
+/*
+ * length in bits 
+ */
+void addEntropy(unsigned length, void* data); 
+void getRandomBlock(uint32_t* b);
+/* this does some simple buffering */
+uint8_t getRandomByte(void);
+
+#endif /*PRNG_H_*/
diff --git a/serial-tools.c b/serial-tools.c
new file mode 100644 (file)
index 0000000..b423299
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * 
+ * Author:     Daniel Otte
+ * Date:               16.05.2006
+ * 
+ * This tools should help to parse some input. 
+ * 
+ */
+
+#include "config.h"
+#include "uart.h"
+#include <string.h>
+#include <stdint.h>
+
+int getnextwordn(char *s, int n){ /* words are seperated by spaces */
+       char c = ' ';
+       while ((c=uart_getc()) == ' ')
+               ;
+       *s++ = c;
+       while (n && (*s++=uart_getc())!=' ')
+               ;
+       *(s-1) = '\0';
+       return n;
+}
+
+
+void readhex2buffer(void* buffer, int n){
+       char c;
+       uint8_t i;
+       
+//     DEBUG_S("\r\nDBG: n="); DEBUG_B(n&0xff); DEBUG_S("\r\n");
+       for(i=0; i<n; ++i){
+               c = uart_getc();
+               if ('0'<= c && '9'>=c){
+                       ((uint8_t*)buffer)[i] = c - '0';
+               } else {
+                       c &= ~('A' ^ 'a'); /* make all uppercase */ 
+                       if ('A'<= c && 'F'>=c){
+                               ((uint8_t*)buffer)[i] = c - 'A' + 10;
+                       } else {
+                               /* oh shit, wrong char */
+                       }
+               }
+               
+               ((uint8_t*)buffer)[i] <<= 4;
+               
+               c = uart_getc();
+               if ('0'<= c && '9'>=c){
+                       ((uint8_t*)buffer)[i] |= c - '0';
+               } else {
+                       c &= ~('A' ^ 'a'); /* make all uppercase */ 
+                       if ('A'<= c && 'F'>=c){
+                               ((uint8_t*)buffer)[i] |= c - 'A' + 10;
+                       } else {
+                               /* oh shit, wrong char */
+                       }
+               }
+       } /* for i=0 .. n */
+}
+
+void uart_putptr(void* p){
+       uart_hexdump((void*) &p,2);
+}
+
diff --git a/serial-tools.h b/serial-tools.h
new file mode 100644 (file)
index 0000000..4ed5f60
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef SERIALTOOLS_H_
+#define SERIALTOOLS_H_
+
+
+int getnextwordn(char *s, int n); /* words are seperated by spaces */
+void readhex2buffer(void* buffer, int n);
+void uart_putptr(void* p);
+
+#endif /*SERIALTOOLS_H_*/
diff --git a/sha256-asm.S b/sha256-asm.S
new file mode 100644 (file)
index 0000000..0769e7c
--- /dev/null
@@ -0,0 +1,1025 @@
+/*\r
+ * Author:     Daniel Otte\r
+ *\r
+ * License: GPL\r
+*/\r
+; sha-256 implementation in assembler  \r
+SHA256_BLOCK_BITS = 512\r
+SHA256_HASH_BITS = 256\r
+\r
+.macro precall\r
+       /* push r18 - r27, r30 - r31*/\r
+       push r0\r
+       push r1\r
+       push r18\r
+       push r19\r
+       push r20\r
+       push r21\r
+       push r22\r
+       push r23\r
+       push r24\r
+       push r25\r
+       push r26\r
+       push r27\r
+       push r30\r
+       push r31\r
+       clr r1\r
+.endm\r
+\r
+.macro postcall\r
+       pop r31\r
+       pop r30\r
+       pop r27\r
+       pop r26\r
+       pop r25\r
+       pop r24\r
+       pop r23\r
+       pop r22\r
+       pop r21\r
+       pop r20\r
+       pop r19\r
+       pop r18\r
+       pop r1\r
+       pop r0\r
+.endm\r
+\r
+\r
+.macro hexdump length\r
+       push r27\r
+       push r26\r
+       ldi r25, '\r'\r
+       mov r24, r25\r
+       call uart_putc\r
+       ldi r25, '\n'\r
+       mov r24, r25\r
+       call uart_putc\r
+       pop r26\r
+       pop r27\r
+       movw r24, r26\r
+.if \length > 16\r
+       ldi r22, lo8(16)\r
+       ldi r23, hi8(16)\r
+       push r27\r
+       push r26\r
+       call uart_hexdump\r
+       pop r26\r
+       pop r27\r
+       adiw r26, 16\r
+       hexdump \length-16\r
+.else\r
+       ldi r22, lo8(\length)\r
+       ldi r23, hi8(\length)\r
+       call uart_hexdump\r
+.endif\r
+.endm\r
+\r
+/* X points to Block */\r
+.macro dbg_hexdump length\r
+       precall\r
+       hexdump \length\r
+       postcall\r
+.endm\r
+\r
+.section .text\r
+\r
+SPL = 0x3D\r
+SPH = 0x3E\r
+SREG = 0x3F\r
+\r
+\r
+;\r
+;sha256_ctx_t is:\r
+;\r
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]\r
+; hn is 32 bit large, length is 64 bit large\r
+\r
+;###########################################################   \r
+\r
+.global sha256_ctx2hash\r
+; === sha256_lastBlock ===\r
+; this function does padding & Co. for calculating SHA-256 hashes\r
+;  param1: the 16-bit destination pointer\r
+;      given in r25,r24 (r25 is most significant)\r
+;  param2: the 16-bit pointer to sha256_ctx structure\r
+;      given in r23,r22\r
+sha256_ctx2hash:\r
+       movw r26, r22\r
+       movw r30, r24\r
+       ldi r21, 8\r
+       sbiw r26, 4\r
+1:     \r
+       ldi r20, 4\r
+       adiw r26, 8\r
+2:     \r
+               ld r0, -X\r
+               st Z+, r0       \r
+       dec r20\r
+       brne 2b\r
+       \r
+       dec r21\r
+       brne 1b\r
+       \r
+       ret\r
+\r
+;###########################################################   \r
+\r
+.global sha256\r
+; === sha256 ===\r
+; this function calculates SHA-256 hashes from messages in RAM\r
+;  param1: the 16-bit hash destination pointer\r
+;      given in r25,r24 (r25 is most significant)\r
+;  param2: the 16-bit pointer to message\r
+;      given in r23,r22\r
+;  param3: 32-bit length value (length of message in bits)\r
+;   given in r21,r20,r19,r18\r
+sha256:\r
+sha256_prolog:\r
+       push r8\r
+       push r9\r
+       push r10\r
+       push r11\r
+       push r12\r
+       push r13\r
+       push r16\r
+       push r17\r
+       in r16, SPL\r
+       in r17, SPH\r
+       subi r16, 8*4+8 \r
+       sbci r17, 0     \r
+       in r0, SREG\r
+       cli\r
+       out SPL, r16\r
+       out SPH, r17\r
+       out SREG, r0\r
+       \r
+       push r25\r
+       push r24\r
+       inc r16\r
+       adc r17, r1\r
+       \r
+       movw r8, r18            /* backup of length*/\r
+       movw r10, r20\r
+       \r
+       movw r12, r22   /* backup pf msg-ptr */\r
+       \r
+       movw r24, r16\r
+       rcall sha256_init\r
+       /* if length >= 512 */\r
+1:\r
+       tst r11\r
+       brne 4f\r
+       tst r10\r
+       brne 4f\r
+       mov r19, r9\r
+       cpi r19, 0x02\r
+       brlo 4f\r
+       \r
+       movw r24, r16\r
+       movw r22, r12\r
+       rcall sha256_nextBlock\r
+       ldi r19, 0x64\r
+       add r22, r19\r
+       adc r23, r1\r
+       /* length -= 512 */\r
+       ldi r19, 0x02\r
+       sub r9, r19\r
+       sbc r10, r1\r
+       sbc r11, r1\r
+       rjmp 1b\r
+       \r
+4:\r
+       movw r24, r16\r
+       movw r22, r12\r
+       movw r20, r8\r
+       rcall sha256_lastBlock\r
+       \r
+       pop r24\r
+       pop r25\r
+       movw r22, r16\r
+       rcall sha256_ctx2hash   \r
+       \r
+sha256_epilog:\r
+       in r30, SPL\r
+       in r31, SPH\r
+       adiw r30, 8*4+8         \r
+       in r0, SREG\r
+       cli\r
+       out SPL, r30\r
+       out SPH, r31\r
+       out SREG, r0\r
+       pop r17\r
+       pop r16\r
+       pop r13\r
+       pop r12\r
+       pop r11\r
+       pop r10\r
+       pop r9\r
+       pop r8\r
+       ret\r
+\r
+;###########################################################   \r
+\r
+\r
+; block MUST NOT be larger than 64 bytes\r
+\r
+.global sha256_lastBlock\r
+; === sha256_lastBlock ===\r
+; this function does padding & Co. for calculating SHA-256 hashes\r
+;  param1: the 16-bit pointer to sha256_ctx structure\r
+;      given in r25,r24 (r25 is most significant)\r
+;  param2: an 16-bit pointer to 64 byte block to hash\r
+;      given in r23,r22\r
+;  param3: an 16-bit integer specifing length of block in bits\r
+;      given in r21,r20\r
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)\r
+\r
+\r
+sha256_lastBlock:\r
+       tst r20\r
+       brne sha256_lastBlock_prolog\r
+       cpi r21, 0x02\r
+       brne sha256_lastBlock_prolog\r
+       push r25\r
+       push r24\r
+       push r23\r
+       push r22\r
+       rcall sha256_nextBlock\r
+       pop r22\r
+       pop r23\r
+       pop r24\r
+       pop r25\r
+       clr r21\r
+       clr r22\r
+sha256_lastBlock_prolog:\r
+       /* allocate space on stack */\r
+       in r30, SPL\r
+       in r31, SPH\r
+       in r1, SREG\r
+       subi r30, lo8(64)\r
+       sbci r31, hi8(64)\r
+       cli\r
+       out SPL, r30\r
+       out SPH, r31\r
+       out SREG,r1\r
+\r
+       adiw r30, 1 /* SP points to next free byte on stack */\r
+       mov r18, r20 /* r20 = LSB(length) */\r
+       lsr r18\r
+       lsr r18\r
+       lsr r18\r
+       bst r21, 0      /* may be we should explain this ... */\r
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */\r
+       \r
+       \r
+       movw r26, r22 /* X points to begin of msg */\r
+       tst r18\r
+       breq sha256_lastBlock_post_copy\r
+       mov r1, r18\r
+sha256_lastBlock_copy_loop:\r
+       ld r0, X+\r
+       st Z+, r0\r
+       dec r1\r
+       brne sha256_lastBlock_copy_loop\r
+sha256_lastBlock_post_copy:    \r
+sha256_lastBlock_insert_stuffing_bit:  \r
+       ldi r19, 0x80\r
+       mov r0,r19      \r
+       ldi r19, 0x07\r
+       and r19, r20 /* if we are in bitmode */\r
+       breq 2f /* no bitmode */\r
+1:     \r
+       lsr r0\r
+       dec r19\r
+       brne 1b\r
+       ld r19, X\r
+/* maybe we should do some ANDing here, just for safety */\r
+       or r0, r19\r
+2:     \r
+       st Z+, r0\r
+       inc r18\r
+\r
+/* checking stuff here */\r
+       cpi r18, 64-8+1\r
+       brsh 0f \r
+       rjmp sha256_lastBlock_insert_zeros\r
+0:\r
+       /* oh shit, we landed here */\r
+       /* first we have to fill it up with zeros */\r
+       ldi r19, 64\r
+       sub r19, r18\r
+       breq 2f\r
+1:     \r
+       st Z+, r1\r
+       dec r19\r
+       brne 1b \r
+2:     \r
+       sbiw r30, 63\r
+       sbiw r30,  1\r
+       movw r22, r30\r
+       \r
+       push r31\r
+       push r30\r
+       push r25\r
+       push r24\r
+       push r21\r
+       push r20\r
+       rcall sha256_nextBlock\r
+       pop r20\r
+       pop r21\r
+       pop r24\r
+       pop r25\r
+       pop r30\r
+       pop r31\r
+       \r
+       /* now we should subtract 512 from length */\r
+       movw r26, r24\r
+       adiw r26, 4*8+1 /* we can skip the lowest byte */\r
+       ld r19, X\r
+       subi r19, hi8(512)\r
+       st X+, r19\r
+       ldi r18, 6\r
+1:\r
+       ld r19, X\r
+       sbci r19, 0\r
+       st X+, r19\r
+       dec r18\r
+       brne 1b\r
+       \r
+;      clr r18 /* not neccessary ;-) */\r
+       /* reset Z pointer to begin of block */\r
+\r
+sha256_lastBlock_insert_zeros: \r
+       ldi r19, 64-8\r
+       sub r19, r18\r
+       breq sha256_lastBlock_insert_length\r
+       clr r1\r
+1:\r
+       st Z+, r1       /* r1 is still zero */\r
+       dec r19\r
+       brne 1b\r
+\r
+;      rjmp sha256_lastBlock_epilog\r
+sha256_lastBlock_insert_length:\r
+       movw r26, r24   /* X points to state */\r
+       adiw r26, 8*4   /* X points to (state.length) */\r
+       adiw r30, 8             /* Z points one after the last byte of block */\r
+       ld r0, X+\r
+       add r0, r20\r
+       st -Z, r0\r
+       ld r0, X+\r
+       adc r0, r21\r
+       st -Z, r0\r
+       ldi r19, 6\r
+1:\r
+       ld r0, X+\r
+       adc r0, r1\r
+       st -Z, r0\r
+       dec r19\r
+       brne 1b\r
+\r
+       sbiw r30, 64-8\r
+       movw r22, r30\r
+       rcall sha256_nextBlock\r
+\r
+sha256_lastBlock_epilog:\r
+       in r30, SPL\r
+       in r31, SPH\r
+       in r1, SREG\r
+       adiw r30, 63 ; lo8(64)\r
+       adiw r30,  1  ; hi8(64)\r
+       cli\r
+       out SPL, r30\r
+       out SPH, r31\r
+       out SREG,r1\r
+       clr r1\r
+       clr r0\r
+       ret\r
+\r
+/**/\r
+;###########################################################   \r
+\r
+.global sha256_nextBlock\r
+; === sha256_nextBlock ===\r
+; this is the core function for calculating SHA-256 hashes\r
+;  param1: the 16-bit pointer to sha256_ctx structure\r
+;      given in r25,r24 (r25 is most significant)\r
+;  param2: an 16-bit pointer to 64 byte block to hash\r
+;      given in r23,r22\r
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)\r
+\r
+Bck1 = 12\r
+Bck2 = 13\r
+Bck3 = 14\r
+Bck4 = 15\r
+Func1 = 22\r
+Func2 = 23\r
+Func3 = 24\r
+Func4 = 25\r
+Accu1 = 16\r
+Accu2 = 17\r
+Accu3 = 18\r
+Accu4 = 19\r
+XAccu1 = 8\r
+XAccu2 = 9\r
+XAccu3 = 10\r
+XAccu4 = 11\r
+T1     = 4\r
+T2     = 5\r
+T3     = 6\r
+T4     = 7\r
+LoopC = 1\r
+/* byteorder: high number <--> high significance */\r
+sha256_nextBlock:\r
+ ; initial, let's make some space ready for local vars\r
+       push r4 /* replace push & pop by mem ops? */\r
+       push r5\r
+       push r6\r
+       push r7\r
+       push r8\r
+       push r9\r
+       push r10\r
+       push r11\r
+       push r12\r
+       push r13\r
+       push r14\r
+       push r15\r
+       push r16\r
+       push r17\r
+       push r28\r
+       push r29\r
+       in r20, SPL\r
+       in r21, SPH\r
+       movw r18, r20                   ;backup SP\r
+;      movw r26, r20                   ; X points to free space on stack \r
+       movw r30, r22                   ; Z points to message\r
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63\r
+       sbci r21, hi8(sha256_nextBlock_localSpace)\r
+       movw r26, r20                   ; X points to free space on stack \r
+       in r0, SREG\r
+       cli ; we want to be uninterrupted while updating SP\r
+       out SPL, r20\r
+       out SPH, r21\r
+       out SREG, r0\r
+       push r18\r
+       push r19\r
+       push r24\r
+       push r25 /* param1 will be needed later */\r
+ ; now we fill the w array with message (think about endianess)\r
+       adiw r26, 1 ; X++\r
+       ldi r20, 16\r
+sha256_nextBlock_wcpyloop:     \r
+       ld r23, Z+\r
+       ld r22, Z+\r
+       ld r19, Z+\r
+       ld r18, Z+\r
+       st X+, r18\r
+       st X+, r19\r
+       st X+, r22      \r
+       st X+, r23\r
+       dec r20\r
+       brne sha256_nextBlock_wcpyloop\r
+/*     for (i=16; i<64; ++i){\r
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   \r
+       } */\r
+       /* r25,r24,r23,r24 (r21,r20) are function values\r
+          r19,r18,r17,r16 are the accumulator\r
+          r15,r14,r13,rBck1 are backup1\r
+          r11,r10,r9 ,r8  are xor accu   \r
+          r1 is round counter                                                          */\r
+\r
+       ldi r20, 64-16\r
+       mov LoopC, r20\r
+sha256_nextBlock_wcalcloop:             \r
+       movw r30, r26 ; cp X to Z\r
+       sbiw r30, 63\r
+       sbiw r30, 1             ; substract 64 = 16*4\r
+       ld Accu1, Z+\r
+       ld Accu2, Z+\r
+       ld Accu3, Z+\r
+       ld Accu4, Z+ /* w[i] = w[i-16] */\r
+       ld Bck1, Z+\r
+       ld Bck2, Z+\r
+       ld Bck3, Z+\r
+       ld Bck4, Z+ /* backup = w[i-15] */\r
+       /* now sigma 0 */\r
+       mov Func1, Bck2\r
+       mov Func2, Bck3\r
+       mov Func3, Bck4\r
+       mov Func4, Bck1  /* prerotated by 8 */\r
+       ldi r20, 1\r
+       rcall bitrotl\r
+       movw XAccu1, Func1\r
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */\r
+       movw Func1, Bck3\r
+       movw Func3, Bck1 /* prerotated by 16 */\r
+       ldi r20, 2\r
+       rcall bitrotr\r
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4\r
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/\r
+sigma0_shr:\r
+       lsr Bck4\r
+       ror Bck3\r
+       ror Bck2\r
+       ror Bck1        \r
+       dec Func2\r
+       brne sigma0_shr\r
+       eor XAccu1, Bck1\r
+       eor XAccu2, Bck2\r
+       eor XAccu3, Bck3\r
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */\r
+       add Accu1, XAccu1\r
+       adc Accu2, XAccu2\r
+       adc Accu3, XAccu3\r
+       adc Accu4, XAccu4 /* finished with sigma0 */\r
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */\r
+       ldd Func2, Z+7*4+1\r
+       ldd Func3, Z+7*4+2\r
+       ldd Func4, Z+7*4+3\r
+       add Accu1, Func1\r
+       adc Accu2, Func2\r
+       adc Accu3, Func3\r
+       adc Accu4, Func4\r
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/\r
+       ldd Bck2, Z+12*4+1\r
+       ldd Bck3, Z+12*4+2\r
+       ldd Bck4, Z+12*4+3\r
+       /* now sigma 1 */\r
+       movw Func1, Bck3\r
+       movw Func3, Bck1 /* prerotated by 16 */\r
+       ldi r20, 1\r
+       rcall bitrotr\r
+       movw XAccu3, Func3\r
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */\r
+;      movw Func1, Bck3\r
+;      movw Func3, Bck1 /* prerotated by 16 */\r
+       ldi r20, 2\r
+       rcall bitrotr\r
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4\r
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/\r
+sigma1_shr:\r
+       lsr Bck4\r
+       ror Bck3\r
+       ror Bck2        \r
+       dec Func2\r
+       brne sigma1_shr\r
+       eor XAccu1, Bck2\r
+       eor XAccu2, Bck3\r
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */\r
+       add Accu1, XAccu1\r
+       adc Accu2, XAccu2\r
+       adc Accu3, XAccu3\r
+       adc Accu4, XAccu4 /* finished with sigma0 */\r
+       /* now let's store the shit */\r
+       st X+, Accu1\r
+       st X+, Accu2\r
+       st X+, Accu3\r
+       st X+, Accu4\r
+       dec LoopC\r
+       breq 3f  ; skip if zero\r
+       rjmp sha256_nextBlock_wcalcloop\r
+3:\r
+       /* we are finished with w array X points one byte post w */\r
+/* init a array */\r
+       pop r31\r
+       pop r30\r
+       push r30\r
+       push r31\r
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */\r
+init_a_array:  \r
+       ld r1, Z+\r
+       st X+, r1\r
+       dec r25\r
+       brne init_a_array\r
+       \r
+/* now the real fun begins */\r
+/* for (i=0; i<64; ++i){\r
+                       t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];\r
+                       t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);\r
+                       memmove(&(a[1]), &(a[0]), 7*4);         // a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; \r
+                       a[4] += t1;\r
+                       a[0] = t1 + t2;\r
+               } */\r
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */\r
+       sbiw r26, 8*4  /* X still points at a[7]+1*/\r
+       movw r28, r26\r
+       ldi r30, lo8(sha256_kv)\r
+       ldi r31, hi8(sha256_kv)         \r
+       dec r27  /* X - (64*4 == 256) */\r
+       ldi r25, 64\r
+       mov LoopC, r25\r
+sha256_main_loop:\r
+       /* now calculate t1 */\r
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/\r
+       ldd T1, Y+5*4\r
+       ldd T2, Y+5*4+1\r
+       ldd T3, Y+5*4+2\r
+       ldd T4, Y+5*4+3 /* y in T */\r
+       ldd Func1, Y+4*4\r
+       ldd Func2, Y+4*4+1\r
+       ldd Func3, Y+4*4+2\r
+       ldd Func4, Y+4*4+3  /* x in Func */\r
+       ldd Bck1, Y+6*4\r
+       ldd Bck2, Y+6*4+1\r
+       ldd Bck3, Y+6*4+2\r
+       ldd Bck4, Y+6*4+3 /* z in Bck */\r
+       and T1, Func1\r
+       and T2, Func2\r
+       and T3, Func3\r
+       and T4, Func4\r
+       com Func1\r
+       com Func2\r
+       com Func3\r
+       com Func4\r
+       and Bck1, Func1\r
+       and Bck2, Func2\r
+       and Bck3, Func3\r
+       and Bck4, Func4\r
+       eor T1, Bck1\r
+       eor T2, Bck2\r
+       eor T3, Bck3\r
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */\r
+       /* now SIGMA1(a[4]) */\r
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/\r
+       ldd Bck1, Y+4*4+1       \r
+       ldd Bck2, Y+4*4+2\r
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ \r
+       movw Func1, Bck1\r
+       movw Func3, Bck3\r
+       ldi r20, 2 \r
+       rcall bitrotl           /* rotr(x,6) */ \r
+       movw XAccu1, Func1\r
+       movw XAccu3, Func3\r
+       movw Func1, Bck1\r
+       movw Func3, Bck3\r
+       ldi r20, 3 \r
+       rcall bitrotr   /* rotr(x,11) */\r
+       eor XAccu1, Func1\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4\r
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/\r
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/\r
+       ldi r20, 1 \r
+       rcall bitrotr   /* rotr(x,11) */\r
+       eor XAccu1, Func1\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */\r
+       add T1, XAccu1\r
+       adc T2, XAccu2\r
+       adc T3, XAccu3\r
+       adc T4, XAccu4\r
+       /* now we've to add a[7], w[i] and k[i] */\r
+       ldd XAccu1, Y+4*7\r
+       ldd XAccu2, Y+4*7+1\r
+       ldd XAccu3, Y+4*7+2\r
+       ldd XAccu4, Y+4*7+3\r
+       add T1, XAccu1\r
+       adc T2, XAccu2\r
+       adc T3, XAccu3\r
+       adc T4, XAccu4 /* add a[7] */\r
+       ld XAccu1, X+\r
+       ld XAccu2, X+\r
+       ld XAccu3, X+\r
+       ld XAccu4, X+\r
+       add T1, XAccu1\r
+       adc T2, XAccu2\r
+       adc T3, XAccu3\r
+       adc T4, XAccu4 /* add w[i] */\r
+       lpm XAccu1, Z+\r
+       lpm XAccu2, Z+\r
+       lpm XAccu3, Z+\r
+       lpm XAccu4, Z+\r
+       add T1, XAccu1\r
+       adc T2, XAccu2\r
+       adc T3, XAccu3\r
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */\r
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/\r
+               /* starting with MAJ(x,y,z) */\r
+       ldd Func1, Y+4*0+0\r
+       ldd Func2, Y+4*0+1\r
+       ldd Func3, Y+4*0+2\r
+       ldd Func4, Y+4*0+3 /* load x=a[0] */\r
+       ldd XAccu1, Y+4*1+0\r
+       ldd XAccu2, Y+4*1+1\r
+       ldd XAccu3, Y+4*1+2\r
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */\r
+       and XAccu1, Func1\r
+       and XAccu2, Func2\r
+       and XAccu3, Func3\r
+       and XAccu4, Func4       /* XAccu == (x & y) */\r
+       ldd Bck1, Y+4*2+0\r
+       ldd Bck2, Y+4*2+1\r
+       ldd Bck3, Y+4*2+2\r
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */\r
+       and Func1, Bck1\r
+       and Func2, Bck2\r
+       and Func3, Bck3\r
+       and Func4, Bck4\r
+       eor XAccu1, Func1\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */\r
+       ldd Func1, Y+4*1+0\r
+       ldd Func2, Y+4*1+1\r
+       ldd Func3, Y+4*1+2\r
+       ldd Func4, Y+4*1+3 /* load y=a[1] */\r
+       and Func1, Bck1\r
+       and Func2, Bck2\r
+       and Func3, Bck3\r
+       and Func4, Bck4\r
+       eor XAccu1, Func1\r
+       eor XAccu2, Func2\r
+       eor XAccu3, Func3\r
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */\r
+       /* SIGMA0(a[0]) */\r
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */\r
+       ldd Bck2, Y+4*0+1\r
+       ldd Bck3, Y+4*0+2\r
+       ldd Bck4, Y+4*0+3\r
+       movw Func1, Bck1\r
+       movw Func3, Bck3\r
+       ldi r20, 2\r
+       rcall bitrotr\r
+       movw Accu1, Func1\r
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */\r
+       movw Func1, Bck3 \r
+       movw Func3, Bck1 /* prerotate by 16 bits */\r
+       ldi r20, 3\r
+       rcall bitrotl\r
+       eor Accu1, Func1\r
+       eor Accu2, Func2\r
+       eor Accu3, Func3\r
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */\r
+       mov Func1, Bck4\r
+       mov Func2, Bck1\r
+       mov Func3, Bck2\r
+       mov Func4, Bck3  /* prerotate by 24 bits */\r
+       ldi r20, 2\r
+       rcall bitrotl\r
+       eor Accu1, Func1\r
+       eor Accu2, Func2\r
+       eor Accu3, Func3\r
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */\r
+       add Accu1, XAccu1 /* add previous result (MAJ)*/\r
+       adc Accu2, XAccu2\r
+       adc Accu3, XAccu3\r
+       adc Accu4, XAccu4\r
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/\r
+       /* a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; */\r
+\r
+       ldi r21, 7*4\r
+       adiw r28, 7*4\r
+a_shift_loop:\r
+       ld  r25, -Y /* warning: this is PREdecrement */\r
+       std Y+4, r25\r
+       dec r21\r
+       brne a_shift_loop\r
+\r
+       ldd Bck1, Y+4*4+0\r
+       ldd Bck2, Y+4*4+1\r
+       ldd Bck3, Y+4*4+2\r
+       ldd Bck4, Y+4*4+3\r
+       add Bck1, T1\r
+       adc Bck2, T2\r
+       adc Bck3, T3\r
+       adc Bck4, T4\r
+       std Y+4*4+0, Bck1\r
+       std Y+4*4+1, Bck2\r
+       std Y+4*4+2, Bck3\r
+       std Y+4*4+3, Bck4\r
+       add Accu1, T1\r
+       adc Accu2, T2\r
+       adc Accu3, T3\r
+       adc Accu4, T4\r
+       std Y+4*0+0, Accu1\r
+       std Y+4*0+1, Accu2\r
+       std Y+4*0+2, Accu3\r
+       std Y+4*0+3, Accu4 /* a array updated */\r
+       \r
+       \r
+       dec LoopC\r
+       breq update_state\r
+       rjmp sha256_main_loop ;brne sha256_main_loop\r
+update_state:  \r
+       /* update state */\r
+       /* pointers to state should still exist on the stack ;-) */\r
+       pop r31\r
+       pop r30\r
+       ldi r21, 8\r
+update_state_loop:\r
+       ldd Accu1, Z+0\r
+       ldd Accu2, Z+1\r
+       ldd Accu3, Z+2\r
+       ldd Accu4, Z+3 \r
+       ld Func1, Y+\r
+       ld Func2, Y+\r
+       ld Func3, Y+\r
+       ld Func4, Y+\r
+       add Accu1, Func1\r
+       adc Accu2, Func2\r
+       adc Accu3, Func3\r
+       adc Accu4, Func4\r
+       st Z+, Accu1\r
+       st Z+, Accu2\r
+       st Z+, Accu3\r
+       st Z+, Accu4\r
+       dec r21\r
+       brne update_state_loop\r
+       /* now we just have to update the length */\r
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ \r
+       ldi r21, 2\r
+       ldi r22, 6\r
+       ld r20, Z\r
+       add r20, r21\r
+       st Z+, r20      \r
+       clr r21\r
+sha256_nexBlock_fix_length:    \r
+       brcc sha256_nextBlock_epilog\r
+       ld r20, Z\r
+       adc r20, r21\r
+       st Z+, r20\r
+       dec r22\r
+       brne sha256_nexBlock_fix_length\r
+       \r
+; EPILOG\r
+sha256_nextBlock_epilog:\r
+/* now we should clean up the stack */\r
+       \r
+       pop r21\r
+       pop r20\r
+       in r0, SREG\r
+       cli ; we want to be uninterrupted while updating SP\r
+       out SPL, r20\r
+       out SPH, r21\r
+       out SREG, r0\r
+       \r
+       clr r1\r
+       pop r29\r
+       pop r28\r
+       pop r17\r
+       pop r16\r
+       pop r15\r
+       pop r14\r
+       pop r13\r
+       pop r12\r
+       pop r11\r
+       pop r10\r
+       pop r9\r
+       pop r8\r
+       pop r7\r
+       pop r6\r
+       pop r5\r
+       pop r4 \r
+       ret\r
+\r
+sha256_kv: ; round-key-vector stored in ProgMem \r
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c\r
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b\r
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9\r
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429\r
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272\r
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a\r
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e\r
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671\r
+\r
+       \r
+;###########################################################   \r
+\r
+.global sha256_init \r
+;uint32_t sha256_init_vector[]={\r
+;      0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,\r
+;      0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };\r
+;\r
+;void sha256_init(sha256_ctx_t *state){\r
+;      state->length=0;\r
+;      memcpy(state->h, sha256_init_vector, 8*4);\r
+;}\r
+; param1: (Func3,r24) 16-bit pointer to sha256_ctx_t struct in ram\r
+; modifys: Z(r30,r31), Func1, r22\r
+sha256_init:\r
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1\r
+       ldi r30, lo8((sha256_init_vector))\r
+       ldi r31, hi8((sha256_init_vector))\r
+       ldi r22, 32\r
+sha256_init_vloop:     \r
+       lpm r23, Z+ \r
+       st X+, r23\r
+       dec r22\r
+       brne sha256_init_vloop\r
+       ldi r22, 8\r
+       clr r1 ;this should not be needed\r
+sha256_init_lloop:\r
+       st X+, r1\r
+       dec r22\r
+       brne sha256_init_lloop\r
+       ret\r
+       \r
+sha256_init_vector:\r
+.word 0xE667, 0x6A09\r
+.word 0xAE85, 0xBB67 \r
+.word 0xF372, 0x3C6E \r
+.word 0xF53A, 0xA54F \r
+.word 0x527F, 0x510E \r
+.word 0x688C, 0x9B05 \r
+.word 0xD9AB, 0x1F83 \r
+.word 0xCD19, 0x5BE0\r
+\r
+;###########################################################   \r
+\r
+.global rotl32\r
+; === ROTL32 ===\r
+; function that rotates a 32 bit word to the left\r
+;  param1: the 32-bit word to rotate\r
+;      given in r25,r24,r23,r22 (r25 is most significant)\r
+;  param2: an 8-bit value telling how often to rotate\r
+;      given in r20\r
+; modifys: r21, r22\r
+rotl32:\r
+       cpi r20, 8\r
+       brlo bitrotl\r
+       mov r21, r25\r
+       mov r25, r24\r
+       mov r24, r23\r
+       mov r23, r22\r
+       mov r22, r21\r
+       subi r20, 8\r
+       rjmp rotr32\r
+bitrotl:\r
+       clr r21\r
+       clc\r
+bitrotl_loop:  \r
+       tst r20\r
+       breq fixrotl\r
+       rol r22\r
+       rol r23\r
+       rol r24\r
+       rol r25\r
+       rol r21\r
+       dec r20\r
+       rjmp bitrotl_loop\r
+fixrotl:\r
+       or r22, r21\r
+       ret\r
+       \r
+\r
+;###########################################################   \r
+\r
+.global rotr32\r
+; === ROTR32 ===\r
+; function that rotates a 32 bit word to the right\r
+;  param1: the 32-bit word to rotate\r
+;      given in r25,r24,r23,22 (r25 is most significant)\r
+;  param2: an 8-bit value telling how often to rotate\r
+;      given in r20\r
+; modifys: r21, r22\r
+rotr32:\r
+       cpi r20, 8\r
+       brlo bitrotr\r
+       mov r21, r22\r
+       mov r22, r23\r
+       mov r23, r24\r
+       mov r24, r25\r
+       mov r25, r21\r
+       subi r20, 8\r
+       rjmp rotr32\r
+bitrotr:\r
+       clr r21\r
+       clc\r
+bitrotr_loop:  \r
+       tst r20\r
+       breq fixrotr\r
+       ror r25\r
+       ror r24\r
+       ror r23\r
+       ror r22\r
+       ror r21\r
+       dec r20\r
+       rjmp bitrotr_loop\r
+fixrotr:\r
+       or r25, r21\r
+       ret\r
+       \r
+       \r
+;###########################################################   \r
+       \r
+.global change_endian32\r
+; === change_endian32 ===\r
+; function that changes the endianess of a 32-bit word\r
+;  param1: the 32-bit word\r
+;      given in r25,r24,r23,22 (r25 is most significant)\r
+;  modifys: r21, r22\r
+change_endian32:\r
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)\r
+       mov r22, r25\r
+       mov r23, r24\r
+       mov r24, r21\r
+       mov r25, r20 \r
+       ret\r
+\r
diff --git a/sha256-asm.h b/sha256-asm.h
new file mode 100644 (file)
index 0000000..65e4c22
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * File:               sha256-asm.h
+ * Author:     Daniel Otte 
+ * Date:               16.05.2006
+ * License:    GPL
+ * 
+ */
+
+#ifndef SHA256ASM_H_
+#define SHA256ASM_H_
+
+
+#define SHA256_HASH_BITS  256
+#define SHA256_BLOCK_BITS 512
+
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+typedef uint8_t sha256_hash_t[SHA256_HASH_BITS/8];
+
+void sha256_ctx2hash(sha256_hash_t *dest, sha256_ctx_t *state);
+void sha256(sha256_hash_t *dest, void* msg, uint32_t length);
+void sha256_init(sha256_ctx_t *state);
+void sha256_nextBlock(sha256_ctx_t *state, void* block);
+void sha256_lastBlock(sha256_ctx_t *state, void* block, uint16_t length);
+uint32_t rotr32(uint32_t, uint8_t);
+uint32_t change_endian32(uint32_t x);
+
+#endif /*SHA256ASM_H_*/
diff --git a/sha256.c b/sha256.c
new file mode 100644 (file)
index 0000000..f90dba8
--- /dev/null
+++ b/sha256.c
@@ -0,0 +1,183 @@
+/**
+ * File:               sha256.c
+ * Author:     Daniel Otte 
+ * Date:               16.05.2006
+ * License:    GPL
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h> /* for memcpy, memmove, memset */
+#include "sha256.h"
+
+#define LITTLE_ENDIAN
+
+#if defined LITTLE_ENDIAN
+#elif defined BIG_ENDIAN
+#else
+       #error specify endianess!!!
+#endif
+
+
+uint32_t sha256_init_vector[]={
+       0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+    0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
+
+void sha256_init(sha256_ctx_t *state){
+       state->length=0;
+       memcpy(state->h, sha256_init_vector, 8*4);
+}
+
+/*
+ * rotate x right by n positions
+ */
+
+uint32_t rotr32( uint32_t x, uint8_t n){
+       return ((x>>n) | (x<<(32-n)));
+}
+
+// #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
+
+uint32_t change_endian32(uint32_t x){
+       return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
+}
+
+
+/* sha256 functions as macros for speed and size, cause they are called only once */
+
+#define CH(x,y,z)  (((x)&(y)) ^ ((~(x))&(z)))
+#define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
+
+#define SIGMA0(x) (rotr32((x),2) ^ rotr32((x),13) ^ rotr32((x),22))
+#define SIGMA1(x) (rotr32((x),6) ^ rotr32((x),11) ^ rotr32((x),25))
+#define SIGMA_a(x) (rotr32((x),7)  ^ rotr32((x),18) ^ ((x)>>3))
+#define SIGMA_b(x) (rotr32((x),17) ^ rotr32((x),19) ^ ((x)>>10))
+
+
+uint32_t k[]={
+       0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+       0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+       0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+       0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+       0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+       0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+       0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+       0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+
+/**
+ * block must be, 512, Bit = 64, Byte, long !!!
+ */
+void sha256_nextBlock (sha256_ctx_t *state, void* block){
+       uint32_t w[64]; /* this is 256, byte, large, */
+       uint8_t  i;
+       uint32_t a[8],t1,t2;
+
+       /* init w */
+#if defined LITTLE_ENDIAN
+               for (i=0; i<16; ++i){
+                       w[i]= change_endian32(((uint32_t*)block)[i]);
+               }
+#elif defined BIG_ENDIAN
+               memcpy((void*)w, block, 64);
+#endif
+               for (i=16; i<64; ++i){
+                       w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+               }
+
+       /* init working variables */    
+               memcpy((void*)a,(void*)(state->h), 8*4);
+
+       /* do the, fun stuff, */
+               for (i=0; i<64; ++i){
+                       t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];
+                       t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);
+                       memmove(&(a[1]), &(a[0]), 7*4);         /* a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; */
+                       a[4] += t1;
+                       a[0] = t1 + t2;
+               }
+
+       /* update, the, state, */
+               for (i=0; i<8; ++i){
+                       state->h[i] += a[i];
+               }       
+               state->length += 512;
+} 
+
+/*
+ * length is the length of only THIS block in BITS not in bytes!
+ *  bits are big endian, meaning high bits come first.
+ *     if you have a message with bits at the end, the byte must be padded with zeros 
+ * */
+void sha256_lastBlock(sha256_ctx_t *state, void* block, uint16_t length){
+       uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
+       state->length += length;
+       memcpy (&(lb[0]), block, length/8);
+       
+       /* set the final one bit */
+       if (length & 0x3){ // if we have single bits at the end
+               lb[length/8] = ((uint8_t*)(block))[length/8];
+       } else {
+               lb[length/8] = 0;
+       }
+       lb[length/8] |= 0x80>>(length & 0x3);
+       length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
+       /* pad with zeros */
+       if (length>64-8){ /* not enouth space for 64bit length value */
+               memset((void*)(&(lb[length])), 0, 64-length);
+               sha256_nextBlock(state, lb);
+               state->length -= 512;
+               length = 0;     
+       }
+       memset((void*)(&(lb[length])), 0, 56-length);
+       /* store the 64bit length value */
+#if defined LITTLE_ENDIAN
+               /* this is now rolled up */
+       uint8_t i;      
+       for (i=1; i<=8; ++i){
+               lb[55+i] = (uint8_t)(state->length>>(64- 8*i));
+       }
+#elif defined BIG_ENDIAN
+       *((uint64_t)&(lb[56])) = state->length;
+#endif
+       sha256_nextBlock(state, lb);
+}
+
+
+/*
+ * length in bits!
+ */
+
+void sha256(sha256_hash_t *dest, void* msg, uint32_t length){ /* length could be choosen longer but this is for ?C */
+       sha256_ctx_t s;
+       sha256_init(&s);
+       while(length >= SHA256_BLOCK_BITS){
+               sha256_nextBlock(&s, msg);
+               msg += SHA256_BLOCK_BITS/8;
+               length -= SHA256_BLOCK_BITS;
+       }
+       sha256_lastBlock(&s, msg, length);
+       sha256_ctx2hash(dest,&s);
+}
+
+
+
+
+#ifdef sha256_ctx2hash_in_C
+void sha256_ctx2hash(sha256_hash_t *dest, sha256_ctx_t *state){
+#if defined LITTLE_ENDIAN
+       uint8_t i;
+       for(i=0; i<8; ++i){
+               ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
+       }
+#elif BIG_ENDIAN
+       if (dest != state->h)
+               memcpy(dest, state->h, SHA256_HASH_BITS/8);
+#else
+# error unsupported endian type!
+#endif
+}
+#endif
+
+
diff --git a/sha256.h b/sha256.h
new file mode 100644 (file)
index 0000000..80970ff
--- /dev/null
+++ b/sha256.h
@@ -0,0 +1,37 @@
+/**
+ * File:               sha256.h
+ * Author:     Daniel Otte 
+ * Date:               16.05.2006
+ * License:    GPL
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+
+#define SHA256_HASH_BITS  256
+#define SHA256_BLOCK_BITS 512
+
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+typedef uint8_t sha256_hash_t[SHA256_HASH_BITS/8];
+
+void sha256_init(sha256_ctx_t *state);
+void sha256_nextBlock (sha256_ctx_t *state, void* block);
+void sha256_lastBlock(sha256_ctx_t *state, void* block, uint16_t length);
+
+void sha256_ctx2hash(sha256_hash_t *dest, sha256_ctx_t *state);
+void sha256(sha256_hash_t *dest, void* msg, uint32_t length);
+uint32_t change_endian32(uint32_t x);
+
+
+#endif /*SHA256_H_*/
diff --git a/uart.c b/uart.c
new file mode 100644 (file)
index 0000000..c0365e7
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,181 @@
+/* USART-Init beim ATmegaXX */
+
+#include "config.h"
+
+#include <avr/io.h>
+//#include <avr/signal.h>
+#include <avr/interrupt.h>
+#include <stdlib.h>
+
+#include "uart.h"
+
+#ifdef ATMEGA128
+#define UCSRB UCSR0B
+#define UCSRC UCSR0C
+#define UDR UDR0
+#define UBRRH UBRR0H
+#define UBRRL UBRR0L
+#define URSEL UMSEL
+#endif
+
+
+#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
+
+
+#ifdef UART_INTERRUPT
+volatile static char rxbuf[UART_RXBUFSIZE];
+volatile static char txbuf[UART_TXBUFSIZE];
+volatile static char *volatile rxhead, *volatile rxtail;
+volatile static char *volatile txhead, *volatile txtail;
+
+
+SIGNAL(SIG_UART_DATA) {
+#ifdef UART_LEDS       
+       PORTC ^= 0x01;
+#endif
+       
+       if ( txhead == txtail ) {
+               UCSRB &= ~(1 << UDRIE);         /* disable data register empty IRQ */
+       } else {
+               UDR = *txtail;                  /* schreibt das Zeichen x auf die Schnittstelle */
+               if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
+       }
+}
+
+SIGNAL(SIG_UART_RECV) {
+       int diff; 
+
+#ifdef UART_LEDS
+       PORTC ^= 0x02;
+#endif
+       
+       /* buffer full? */
+       diff = rxhead - rxtail;
+       if ( diff < 0 ) diff += UART_RXBUFSIZE;
+       if (diff < UART_RXBUFSIZE -1) {
+               // buffer NOT full
+               *rxhead = UDR;
+               if (++rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
+       } else {
+               UDR;                            //reads the buffer to clear the interrupt condition
+       }
+}
+
+#endif // UART_INTERRUPT
+
+
+void uart_init(void) {
+       PORTD |= 0x01;                          //Pullup an RXD an
+
+       UCSRB |= (1<<TXEN);                     //UART TX einschalten
+       UCSRC |= (1<<URSEL)|(3<<UCSZ0);         //Asynchron 8N1
+
+       UCSRB |= ( 1 << RXEN );                 //Uart RX einschalten
+
+       UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
+       UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
+
+#ifdef UART_INTERRUPT
+       // init buffers
+       rxhead = rxtail = rxbuf;
+       txhead = txtail = txbuf;
+
+       // activate rx IRQ
+       UCSRB |= (1 << RXCIE);
+#endif // UART_INTERRUPT
+}
+
+#ifdef UART_INTERRUPT
+void uart_putc(char c) {
+       volatile int diff;
+
+       /* buffer full? */
+       do {
+               diff = txhead - txtail;
+               if ( diff < 0 ) diff += UART_TXBUFSIZE;
+       } while ( diff >= UART_TXBUFSIZE -1 );
+
+       cli();
+       *txhead = c;
+       if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
+
+       UCSRB |= (1 << UDRIE);          /* enable data register empty IRQ */
+       sei();
+}
+#else  // WITHOUT INTERRUPT
+void uart_putc(char c) {
+       while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich                   */
+       UDR = c;                      /* schreibt das Zeichen x auf die Schnittstelle */
+}
+#endif // UART_INTERRUPT
+
+
+void uart_putstr(char *str) {
+       while(*str) {
+               uart_putc(*str++);
+       }
+}
+
+void uart_putstr_P(PGM_P str) {
+       char tmp;
+       while((tmp = pgm_read_byte(str))) {
+               uart_putc(tmp);
+               str++;
+       }
+}
+
+void uart_hexdump(void* buf, int len)
+{
+       unsigned char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+       
+       while(len--){
+               uart_putc(table[((*((char*)buf))>>4)&0xf]);
+               uart_putc(table[(*((char*)buf))&0xf]);
+               uart_putc(' ');
+               ++buf;
+       }
+}
+
+
+#ifdef UART_INTERRUPT
+char uart_getc(void)
+{
+       char val;
+
+       while(rxhead==rxtail) ;
+
+       val = *rxtail;
+       if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
+
+       return val;
+}
+#else  // WITHOUT INTERRUPT
+char uart_getc(void)
+{
+       while (!(UCSRA & (1<<RXC)));    // warten bis Zeichen verfuegbar
+       return UDR;                     // Zeichen aus UDR zurueckgeben
+}
+#endif // UART_INTERRUPT
+
+// returns 1 on success
+#ifdef UART_INTERRUPT
+char uart_getc_nb(char *c)
+{
+       if (rxhead==rxtail) return 0;
+
+       *c = *rxtail;
+       if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
+
+       return 1;
+}
+#else  // WITHOUT INTERRUPT
+char uart_getc_nb(char *c)
+{
+       if (UCSRA & (1<<RXC)) {         // Zeichen verfuegbar
+               *c = UDR;
+               return 1;
+       }
+
+       return 0;
+}
+#endif // UART_INTERRUPT
diff --git a/uart.h b/uart.h
new file mode 100644 (file)
index 0000000..e8e3b20
--- /dev/null
+++ b/uart.h
@@ -0,0 +1,37 @@
+#ifndef UART_H
+#define UART_H
+
+/**
+ * UART Library
+ *
+ * #define F_CPU 16000000         // Oszillator-Frequenz in Hz
+ * #define UART_INTERRUPT 1
+ * #define UART_BAUD_RATE 19200
+ * #define UART_RXBUFSIZE 16
+ * #define UART_TXBUFSIZE 16
+ * #define UART_LINE_BUFFER_SIZE 40
+ * #define UART_LEDS             // LED1 and LED2 toggle on tx and rx interrupt
+ *
+ */
+
+
+#include "config.h"
+#include <inttypes.h>
+#include <avr/pgmspace.h>
+
+void uart_init(void);
+
+void uart_putc(char c);
+void uart_putstr(char * str);
+void uart_putstr_P(PGM_P str);
+void uart_hexdump(void* buf, int len);
+
+char uart_getc(void);
+char uart_getc_nb(char *c);            // returns 1 on success
+
+//get one Cariage return terminated line
+//echo charakters back on Uart
+//returns buffer with zero terminated line on success, 0 pointer otherwise
+char * uart_getline_nb(void);
+
+#endif
diff --git a/xtea-asm.S b/xtea-asm.S
new file mode 100644 (file)
index 0000000..35063f2
--- /dev/null
@@ -0,0 +1,567 @@
+/* xtea-asm.S 
+ * Author:     Daniel Otte
+ * Date:               06.06.2006
+ * License: GPL
+ *  Implementation of XTEA for AVR
+ *  include xtea.h in your C-Project to use this functions.
+*/
+
+V01 = 2
+V02 = 3
+V03 = 4
+V04 = 5
+V11 = 6
+V12 = 7
+V13 = 8
+V14 = 9
+Accu1 = 14
+Accu2 = 15
+Accu3 = 16
+Accu4 = 17
+Sum1 = 18
+Sum2 = 19
+Sum3 = 20
+Sum4 = 21
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+C = 28 /* der kleine Zaehler fuer zwischendurch */
+
+.global xtea_enc
+; == xtea_enc ==
+; xtea encrytion function
+; param1: 16-bit pointer to destination for encrypted block 
+;  given in r25,r24
+; param2: 16-bit pointer to the block (64-bit) which is to encrypt 
+;  given in r23,r22
+; param3: 16-bit pointer to the key (128-bit) 
+;  given in r21,r20
+;
+xtea_enc:
+ /* prolog */
+       push r2
+       push r3
+       push r4
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       
+ /* load the block */
+       movw r26, r22 /* X points to block */
+       movw r30, r20 /* Z points to key   */
+       ld V01, X+
+       ld V02, X+
+       ld V03, X+
+       ld V04, X+
+       ld V11, X+
+       ld V12, X+
+       ld V13, X+
+       ld V14, X+
+;      push r25
+;      push r24
+       movw r26, r24 /* X points to destination */
+       ldi Func1, 32
+       mov r0, Func1 /* r1 is cycle-counter */
+       clr Sum1
+       clr Sum2
+       movw Sum3, Sum1
+       clt
+
+1:
+       movw Accu1, V11
+       movw Accu3, V13
+       ldi C, 4
+2:     lsl Accu1
+       rol Accu2
+       rol Accu3
+       rol Accu4
+       dec C
+       brne 2b                 /* Accu == V1 << 4 */
+
+       movw Func1, V11
+       movw Func3, V13
+       ldi C, 5
+3:     lsr Func4
+       ror Func3
+       ror Func2
+       ror Func1
+       dec C
+       brne 3b                 /* Func == V1 >> 5 */
+       
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4
+       add Accu1, V11
+       adc Accu2, V12
+       adc Accu3, V13
+       adc Accu4, V14  /* Accu == ( (V1<<4)^(V1>>5) ) + V1 */
+       
+       brtc 4f
+       mov C, Sum2
+       lsr C
+       andi C,(0x03 <<2)
+       clt
+       rjmp 5f
+4:     
+       mov C, Sum1     /* calc key offset */
+       andi C, 0x03
+       lsl C
+       lsl C
+       set
+       
+5:     
+       add r30, C
+       adc r31, r1
+       ld  Func1, Z
+       ldd Func2, Z+1
+       ldd Func3, Z+2
+       ldd Func4, Z+3 /* Func = key[sum & 3] */
+       sub r30, C
+       sbci r31, 0
+       add Func1, Sum1
+       adc Func2, Sum2
+       adc Func3, Sum3
+       adc Func4, Sum4 
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu = ((V1<<4 ^ V1>>5) + V1) ^ (sum + key[sum&3])  */
+       add Accu1, V01
+       adc Accu2, V02
+       adc Accu3, V03
+       adc Accu4, V04
+       
+       movw V01, V11
+       movw V03, V13
+       movw V11, Accu1
+       movw V13, Accu3
+       
+       /* sum += delta */ /* delta == 0x9E3779B9 */
+       brtc 6f
+       ldi C, 0xB9
+       add Sum1, C
+       ldi C, 0x79
+       adc Sum2, C
+       ldi C, 0x37
+       adc Sum3, C
+       ldi C, 0x9E
+       adc Sum4, C
+       rjmp 1b
+       
+6:     
+       dec r0
+       breq 7f
+       rjmp 1b 
+ 7:
+ /* write block back */
+ ;     pop r26
+ ;     pop r27
+       st X+, V01
+       st X+, V02
+       st X+, V03
+       st X+, V04
+       st X+, V11
+       st X+, V12
+       st X+, V13
+       st X+, V14
+ /* epilog */
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4
+       pop r3
+       pop r2
+       ret
+
+;####################################################################
+ /* #endif TWO_IN_ONE */       
+ /* #ifdef TWO_IN_ONE */
+ /* now we use the same base-structure for enc- and decryption
+       to indicate operation mode we use the highest bit of param3 (16 bit pointer to key),
+       this is ok, since even the larges atmel today has "only" 8k of ram,
+       but you shouldn't use this feature while using external ram. 
+ */
+.global xtea_enc
+       ori r21, 0x80
+       
+.global xtea_dec
+; == xtea_dec ==
+; xtea decrytion function
+; param1: 16-bit pointer to destination for decrypted block 
+;  given in r25,r24
+; param2: 16-bit pointer to the block (64-bit) which is to derypt 
+;  given in r23,r22
+; param3: 16-bit pointer to the key (128-bit) 
+;  given in r21,r20
+;
+/*
+void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k) {
+    uint32_t v0=v[0], v1=v[1], i;
+    uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
+        sum -= delta;
+        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
+    }
+    dest[0]=v0; dest[1]=v1;
+}
+*/
+
+xtea_dec:
+ /* prolog */
+       push r2
+       push r3
+       push r4
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28 
+ /* load the block */
+       movw r26, r22 /* Z points to block */
+       movw r30, r20 /* X points to key   */
+       ld V01, X+
+       ld V02, X+
+       ld V03, X+
+       ld V04, X+
+       ld V11, X+
+       ld V12, X+
+       ld V13, X+
+       ld V14, X+
+       movw r26, r24 /* Z points to destination */
+       ldi Sum1, 32
+       mov r0, Sum1 /* r1 is cycle-counter */
+       ldi Sum1, 0x20 /* sum = 0xC6EF3720 */
+       ldi Sum2, 0x37
+       ldi Sum3, 0xEF
+       ldi Sum4, 0xC6
+       clt
+
+1:
+       movw Accu1, V01
+       movw Accu3, V03
+       ldi C, 4
+2:     lsl Accu1
+       rol Accu2
+       rol Accu3
+       rol Accu4
+       dec C
+       brne 2b                 /* Accu == V0 << 4 */
+
+       movw Func1, V01
+       movw Func3, V03
+       ldi C, 5
+3:     lsr Func4
+       ror Func3
+       ror Func2
+       ror Func1
+       dec C
+       brne 3b                 /* Func == V0 >> 5 */
+       
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4
+       add Accu1, V01
+       adc Accu2, V02
+       adc Accu3, V03
+       adc Accu4, V04  /* Accu == ( (V0<<4)^(V0>>5) ) + V0 */
+       
+       brts 4f
+       mov C, Sum2
+       lsr C
+       andi C,(0x03 <<2)
+       set
+       rjmp 5f
+4:     
+       mov C, Sum1     /* calc key offset */
+       andi C, 0x03
+       lsl C
+       lsl C
+       clt
+       
+5:     
+       add r30, C
+       adc r31, r1
+       ld  Func1, Z
+       ldd Func2, Z+1
+       ldd Func3, Z+2
+       ldd Func4, Z+3 /* Func = key[sum & 3] */
+       sub r30, C
+       sbci r31, 0
+       add Func1, Sum1
+       adc Func2, Sum2
+       adc Func3, Sum3
+       adc Func4, Sum4 
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu = ((V0<<4 ^ V0>>5) + V0) ^ (sum + key[sum&3])  */
+       sub V11, Accu1
+       sbc V12, Accu2
+       sbc V13, Accu3
+       sbc V14, Accu4
+       
+       movw Accu1, V01
+       movw Accu3, V03
+       movw V01, V11
+       movw V03, V13
+       movw V11, Accu1
+       movw V13, Accu3
+       
+       /* sum += delta */ /* delta == 0x9E3779B9 */
+       brtc 6f
+       subi Sum1, 0xB9
+       sbci Sum2, 0x79
+       sbci Sum3, 0x37
+       sbci Sum4, 0x9E
+       rjmp 1b
+       
+6:     
+       dec r0
+       breq 7f
+       rjmp 1b 
+7:
+ /* write block back */
+       st X+, V01
+       st X+, V02
+       st X+, V03
+       st X+, V04
+       st X+, V11
+       st X+, V12
+       st X+, V13
+       st X+, V14
+ /* epilog */
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4
+       pop r3
+       pop r2
+       ret
+       
+ /* #endif */
+
+;####################################################################
+ #ifdef TWO_IN_ONE
+ /* now we use the same base-structure for enc- and decryption
+       to indicate operation mode we use the highest bit of param3 (16 bit pointer to key),
+       this is ok, since even the larges atmel today has "only" 8k of ram,
+       but you shouldn't use this feature while using external ram. 
+ */
+.global xtea_enc
+       ori r21, 0x80
+       
+.global xtea_dec
+; == xtea_dec ==
+; xtea decrytion function
+; param1: 16-bit pointer to destination for decrypted block 
+;  given in r25,r24
+; param2: 16-bit pointer to the block (64-bit) which is to derypt 
+;  given in r23,r22
+; param3: 16-bit pointer to the key (128-bit) 
+;  given in r21,r20
+;
+/*
+void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k) {
+    uint32_t v0=v[0], v1=v[1], i;
+    uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
+        sum -= delta;
+        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
+    }
+    dest[0]=v0; dest[1]=v1;
+}
+*/
+
+xtea_dec:
+ /* prolog */
+       push r2
+       push r3
+       push r4
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28 
+ /* set T-bit if we are going to encrypt, clear otherwise */
+       bst r21, 7
+       andi r21, 0x7f /* fix r21:r22 to a real addr */
+ /* load the block */
+       movw r26, r22 /* Z points to block */
+       movw r30, r20 /* X points to key   */
+       ld V01, X+
+       ld V02, X+
+       ld V03, X+
+       ld V04, X+
+       ld V11, X+
+       ld V12, X+
+       ld V13, X+
+       ld V14, X+
+       movw r26, r24 /* Z points to destination */
+       ldi Sum1, 32
+       mov r0, Sum1 /* r1 is cycle-counter */
+       ldi Sum1, 0x20 /* sum = 0xC6EF3720 */
+       ldi Sum2, 0x37
+       ldi Sum3, 0xEF
+       ldi Sum4, 0xC6
+       clt
+
+1:
+       movw Accu1, V01
+       movw Accu3, V03
+       ldi C, 4
+2:     lsl Accu1
+       rol Accu2
+       rol Accu3
+       rol Accu4
+       dec C
+       brne 2b                 /* Accu == V0 << 4 */
+
+       movw Func1, V01
+       movw Func3, V03
+       ldi C, 5
+3:     lsr Func4
+       ror Func3
+       ror Func2
+       ror Func1
+       dec C
+       brne 3b                 /* Func == V0 >> 5 */
+       
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4
+       add Accu1, V01
+       adc Accu2, V02
+       adc Accu3, V03
+       adc Accu4, V04  /* Accu == ( (V0<<4)^(V0>>5) ) + V0 */
+       
+       brts 4f
+       mov C, Sum2
+       lsr C
+       andi C,(0x03 <<2)
+       set
+       rjmp 5f
+4:     
+       mov C, Sum1     /* calc key offset */
+       andi C, 0x03
+       lsl C
+       lsl C
+       clt
+       
+5:     
+       add r30, C
+       adc r31, r1
+       ld  Func1, Z
+       ldd Func2, Z+1
+       ldd Func3, Z+2
+       ldd Func4, Z+3 /* Func = key[sum & 3] */
+       sub r30, C
+       sbci r31, 0
+       add Func1, Sum1
+       adc Func2, Sum2
+       adc Func3, Sum3
+       adc Func4, Sum4 
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu = ((V0<<4 ^ V0>>5) + V0) ^ (sum + key[sum&3])  */
+       sub V11, Accu1
+       sbc V12, Accu2
+       sbc V13, Accu3
+       sbc V14, Accu4
+       
+       movw Accu1, V01
+       movw Accu3, V03
+       movw V01, V11
+       movw V03, V13
+       movw V11, Accu1
+       movw V13, Accu3
+       
+       /* sum += delta */ /* delta == 0x9E3779B9 */
+       brtc 6f
+       subi Sum1, 0xB9
+       sbci Sum2, 0x79
+       sbci Sum3, 0x37
+       sbci Sum4, 0x9E
+       rjmp 1b
+       
+6:     
+       dec r0
+       breq 7f
+       rjmp 1b 
+7:
+ /* write block back */
+       st X+, V01
+       st X+, V02
+       st X+, V03
+       st X+, V04
+       st X+, V11
+       st X+, V12
+       st X+, V13
+       st X+, V14
+ /* epilog */
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4
+       pop r3
+       pop r2
+       ret
+       
+ #endif
+
diff --git a/xtea.c b/xtea.c
new file mode 100644 (file)
index 0000000..c9fe103
--- /dev/null
+++ b/xtea.c
@@ -0,0 +1,32 @@
+/* 
+ * XTEA implemantation 
+ *  copy'n'pasted from http://en.wikipedia.org/wiki/XTEA
+ *   and slightly modified
+ * */
+#include <stdint.h> 
+
+void xtea_enc(uint32_t* dest, uint32_t* v, uint32_t* k) {
+    uint32_t v0=v[0], v1=v[1], i;
+    uint32_t sum=0, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
+        sum += delta;
+        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
+    }
+    dest[0]=v0; dest[1]=v1;
+}
+
+void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k) {
+    uint32_t v0=v[0], v1=v[1], i;
+    uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
+        sum -= delta;
+        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
+    }
+    dest[0]=v0; dest[1]=v1;
+}
+
+
diff --git a/xtea.h b/xtea.h
new file mode 100644 (file)
index 0000000..a156abd
--- /dev/null
+++ b/xtea.h
@@ -0,0 +1,28 @@
+/*
+ * Author:     Daniel Otte
+ * Date:               06.06.2006
+ * License:    GPL
+ */
+
+#ifndef XTEA_H_
+#define XTEA_H_
+
+#include <stdint.h> 
+/*
+ * this fits for xtea.c and xtea-asm.S
+ * 
+ */
+
+
+
+/*
+ * dest: the destination where result of operation will be placed (64 bit)
+ * v:   the block to operate on (64 bit)
+ * k:   the key for en/decryption (128 bit)
+ */
+void xtea_enc(uint32_t* dest, uint32_t* v, uint32_t* k);
+void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k);
+
+
+#endif /*XTEA_H_*/