]> git.cryptolib.org Git - avr-crypto-lib.git/commitdiff
modified structure
authorbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Thu, 6 Aug 2009 20:11:02 +0000 (20:11 +0000)
committerbg <bg@b1d182e4-1ff8-0310-901f-bddb46175740>
Thu, 6 Aug 2009 20:11:02 +0000 (20:11 +0000)
206 files changed:
arcfour-asm.S [deleted file]
arcfour.c [deleted file]
arcfour.h [deleted file]
arcfour/arcfour-asm.S [new file with mode: 0644]
arcfour/arcfour.c [new file with mode: 0644]
arcfour/arcfour.h [new file with mode: 0644]
base64/base64_dec.c [new file with mode: 0644]
base64/base64_dec.h [new file with mode: 0644]
base64/base64_enc.c [new file with mode: 0644]
base64/base64_enc.h [new file with mode: 0644]
base64_dec.c [deleted file]
base64_dec.h [deleted file]
base64_enc.c [deleted file]
base64_enc.h [deleted file]
bmw/bmw_large.c [new file with mode: 0644]
bmw/bmw_large.h [new file with mode: 0644]
bmw/bmw_small.c [new file with mode: 0644]
bmw/bmw_small.h [new file with mode: 0644]
bmw_large.c [deleted file]
bmw_large.h [deleted file]
bmw_small.c [deleted file]
bmw_small.h [deleted file]
cast5-sbox.h [deleted file]
cast5.c [deleted file]
cast5.h [deleted file]
cast5/cast5-sbox.h [new file with mode: 0644]
cast5/cast5.c [new file with mode: 0644]
cast5/cast5.h [new file with mode: 0644]
cast6.c [deleted file]
cast6.h [deleted file]
cast6/cast6.c [new file with mode: 0644]
cast6/cast6.h [new file with mode: 0644]
cast6/cast6_sboxes.h [new file with mode: 0644]
cast6_sboxes.h [deleted file]
des.c [deleted file]
des.h [deleted file]
des/des.c [new file with mode: 0644]
des/des.h [new file with mode: 0644]
entropium.c [deleted file]
entropium.h [deleted file]
entropium/entropium.c [new file with mode: 0644]
entropium/entropium.h [new file with mode: 0644]
entropium/sha256-asm.S [new file with mode: 0644]
entropium/sha256.h [new file with mode: 0644]
grain.c [deleted file]
grain.h [deleted file]
grain/grain.c [new file with mode: 0644]
grain/grain.h [new file with mode: 0644]
hmac-md5.c [deleted file]
hmac-md5.h [deleted file]
hmac-md5/base64_dec.c [new file with mode: 0644]
hmac-md5/base64_dec.h [new file with mode: 0644]
hmac-md5/base64_enc.c [new file with mode: 0644]
hmac-md5/base64_enc.h [new file with mode: 0644]
hmac-md5/hmac-md5.c [new file with mode: 0644]
hmac-md5/hmac-md5.h [new file with mode: 0644]
hmac-md5/md5-asm.S [new file with mode: 0644]
hmac-md5/md5.h [new file with mode: 0644]
hmac-sha1.c [deleted file]
hmac-sha1.h [deleted file]
hmac-sha1/hmac-sha1.c [new file with mode: 0644]
hmac-sha1/hmac-sha1.h [new file with mode: 0644]
hmac-sha1/sha1-asm.S [new file with mode: 0644]
hmac-sha1/sha1.h [new file with mode: 0644]
hmac-sha256.c [deleted file]
hmac-sha256.h [deleted file]
hmac-sha256/hmac-sha256.c [new file with mode: 0644]
hmac-sha256/hmac-sha256.h [new file with mode: 0644]
hmac-sha256/sha256-asm.S [new file with mode: 0644]
hmac-sha256/sha256.h [new file with mode: 0644]
md5-asm.S [deleted file]
md5.c [deleted file]
md5.h [deleted file]
md5/md5-asm.S [new file with mode: 0644]
md5/md5.c [new file with mode: 0644]
md5/md5.h [new file with mode: 0644]
md5/md5_sbox.h [new file with mode: 0644]
md5_sbox.h [deleted file]
mickey128.c [deleted file]
mickey128.h [deleted file]
mickey128/mickey128.c [new file with mode: 0644]
mickey128/mickey128.h [new file with mode: 0644]
mkfiles/arcfour.mk
mkfiles/arcfour_c.mk
mkfiles/base64.mk
mkfiles/bmw_c.mk
mkfiles/cast5.mk
mkfiles/cast6.mk
mkfiles/des.mk
mkfiles/entropium.mk
mkfiles/grain.mk
mkfiles/hmac-md5.mk
mkfiles/hmac-sha1.mk
mkfiles/hmac-sha256.mk
mkfiles/md5.mk
mkfiles/md5_c.mk
mkfiles/mickey128.mk
mkfiles/present.mk
mkfiles/rc5.mk
mkfiles/rc6.mk
mkfiles/seed.mk
mkfiles/seed_C.mk
mkfiles/serpent-bitslice.mk
mkfiles/serpent_asm_bitslice.mk
mkfiles/serpent_asm_fast.mk
mkfiles/serpent_asm_small.mk
mkfiles/serpent_c.mk
mkfiles/sha1.mk
mkfiles/sha1_c.mk
mkfiles/sha256.mk
mkfiles/sha256_c.mk
mkfiles/shabea.mk
mkfiles/shacal1enc.mk
mkfiles/shacal2enc.mk
mkfiles/skipjack.mk
mkfiles/tdes.mk
mkfiles/trivium.mk
mkfiles/xtea.mk
mkfiles/xtea_c.mk
present.c [deleted file]
present.h [deleted file]
present/present.c [new file with mode: 0644]
present/present.h [new file with mode: 0644]
rc5.c [deleted file]
rc5.h [deleted file]
rc5/rc5.c [new file with mode: 0644]
rc5/rc5.h [new file with mode: 0644]
rc6.c [deleted file]
rc6.h [deleted file]
rc6/rc6.c [new file with mode: 0644]
rc6/rc6.h [new file with mode: 0644]
seed-asm.S [deleted file]
seed.h [deleted file]
seed/seed-asm.S [new file with mode: 0644]
seed/seed.h [new file with mode: 0644]
seed/seed_C.c [new file with mode: 0644]
seed/seed_sbox.h [new file with mode: 0644]
seed_C.c [deleted file]
seed_sbox.h [deleted file]
serpent-asm.S [deleted file]
serpent-sboxes-bitslice-asm.S [deleted file]
serpent-sboxes-bitslice.c [deleted file]
serpent-sboxes-fast.S [deleted file]
serpent-sboxes-small.S [deleted file]
serpent-sboxes.h [deleted file]
serpent-sboxes_c.c [deleted file]
serpent.c [deleted file]
serpent.h [deleted file]
serpent/memxor.S [new file with mode: 0644]
serpent/memxor.h [new file with mode: 0644]
serpent/serpent-asm.S [new file with mode: 0644]
serpent/serpent-sboxes-bitslice-asm.S [new file with mode: 0644]
serpent/serpent-sboxes-bitslice.c [new file with mode: 0644]
serpent/serpent-sboxes-fast.S [new file with mode: 0644]
serpent/serpent-sboxes-small.S [new file with mode: 0644]
serpent/serpent-sboxes.h [new file with mode: 0644]
serpent/serpent-sboxes_c.c [new file with mode: 0644]
serpent/serpent.c [new file with mode: 0644]
serpent/serpent.h [new file with mode: 0644]
sha1-asm.S [deleted file]
sha1.c [deleted file]
sha1.h [deleted file]
sha1/sha1-asm.S [new file with mode: 0644]
sha1/sha1.c [new file with mode: 0644]
sha1/sha1.h [new file with mode: 0644]
sha256-asm.S [deleted file]
sha256.c [deleted file]
sha256.h [deleted file]
sha256/sha256-asm.S [new file with mode: 0644]
sha256/sha256.c [new file with mode: 0644]
sha256/sha256.h [new file with mode: 0644]
shabea.c [deleted file]
shabea.h [deleted file]
shabea/memxor.S [new file with mode: 0644]
shabea/memxor.h [new file with mode: 0644]
shabea/sha256-asm.S [new file with mode: 0644]
shabea/sha256.h [new file with mode: 0644]
shabea/shabea.c [new file with mode: 0644]
shabea/shabea.h [new file with mode: 0644]
shacal1/sha1-asm.S [new file with mode: 0644]
shacal1/sha1.h [new file with mode: 0644]
shacal1/shacal1_enc.c [new file with mode: 0644]
shacal1/shacal1_enc.h [new file with mode: 0644]
shacal1_enc.c [deleted file]
shacal1_enc.h [deleted file]
shacal2/sha256-asm.S [new file with mode: 0644]
shacal2/sha256.h [new file with mode: 0644]
shacal2/shacal2_enc.c [new file with mode: 0644]
shacal2/shacal2_enc.h [new file with mode: 0644]
shacal2_enc.c [deleted file]
shacal2_enc.h [deleted file]
skipjack.c [deleted file]
skipjack.h [deleted file]
skipjack/skipjack.c [new file with mode: 0644]
skipjack/skipjack.h [new file with mode: 0644]
test_src/main-hmac-md5-test.c
trivium.c [deleted file]
trivium.h [deleted file]
trivium/trivium.c [new file with mode: 0644]
trivium/trivium.h [new file with mode: 0644]
xtea-asm.S [deleted file]
xtea.c [deleted file]
xtea.h [deleted file]
xtea/xtea-asm.S [new file with mode: 0644]
xtea/xtea.c [new file with mode: 0644]
xtea/xtea.h [new file with mode: 0644]

diff --git a/arcfour-asm.S b/arcfour-asm.S
deleted file mode 100644 (file)
index 1ef8218..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* arcfour-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* 
- * File:        arcfour-asm.S
- * Author:      Daniel Otte
- * Date:        2006-07-06
- * License:     GPLv3 or later
- * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
- * 
- */
-#include <avr/io.h>
-#include "avr-asm-macros.S"
- /* +---+---+---------------------+
- *  | i | j | ......<256>........ |
- *  +---+---+---------------------+
- */
-.global arcfour_init
-/*
- *== arcfour_init ==
- *  this function initialises the context
- * param1: 16-bit pointer to the key
- *     given in r24:r25
- * param2: 8-bit integer indicating keylength in byte
- *     given in r22
- * param3: 16-bit pointer to a ctx struct
- *     given in r20:r21
- */
-arcfour_init:
-       push_ r28, r29
-       movw r26, r20   /* X points to ctx */
-       movw r30, r24   /* Z points to key */
-       st X+, r1
-       st X+, r1       /* X points to S */
-       movw r20, r26   /* store pointer to S in r21:r20 */
-       
-1:             
-       st X+, r1 
-       inc r1
-       brne 1b
-       
-       movw r26, r20
-       add r22, r30         /* r18 is keyindex counter */
-       clr r0
-       clr r19
-2:
-       ld r23, X
-       ld r18, Z+
-       add r19, r18
-       add r19, r23
-       movw r28, r20   /* load pointer to S in Y */
-       add r28, r19
-       adc r29, r1
-       ld r18, Y
-       st Y,  r23
-       st X+, r18
-       cp r30, r22
-       brne 3f
-       movw r30, r24
-3:             
-       inc r0
-       brne 2b 
-       pop_ r29, r28
-       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
deleted file mode 100644 (file)
index e07193f..0000000
--- a/arcfour.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* arcfour.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * File:        arcfour.c
- * Author:      Daniel Otte
- * email:       daniel.otte@rub.de
- * Date:        2006-06-07
- * License:     GPLv3 or later
- * 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(const void *key, uint8_t length_B, arcfour_ctx_t *ctx){
-       uint8_t t;
-       uint16_t x,y=0;
-       for(x=0; x<= 255; ++x)
-               ctx->s[x]=x;
-
-       for(x=0; x<= 255; ++x){
-               y += ctx->s[x] + ((uint8_t*)key)[x % length_B];
-               y &= 0xff;
-               /* ctx->s[y] <--> ctx->s[x] */
-               t = ctx->s[y];
-               ctx->s[y] = ctx->s[x];
-               ctx->s[x] = t;
-       }
-       ctx->i = ctx->j = 0;
-}
-
-uint8_t arcfour_gen(arcfour_ctx_t *ctx){
-       uint8_t t;
-       ctx->i++;
-       ctx->j += ctx->s[ctx->i];
-       /* ctx->s[i] <--> ctx->s[j] */
-       t = ctx->s[ctx->j];
-       ctx->s[ctx->j] = ctx->s[ctx->i];
-       ctx->s[ctx->i] = t;
-       return ctx->s[(ctx->s[ctx->j] + ctx->s[ctx->i]) & 0xff];
-}
-
diff --git a/arcfour.h b/arcfour.h
deleted file mode 100644 (file)
index d332d7f..0000000
--- a/arcfour.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* arcfour.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * File:       arcfour.h
- * Author:     Daniel Otte
- * Date:       2006-06-07
- * License: GPLv3+
- * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
- */
-
-/**
- * \file       arcfour.h
- * \author     Daniel Otte
- * \date       2006-06-07
- * \license GPLv3+
- * \brief Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
- *
- * This header file defines the interface of the ARCFOUR cipher implementation.
- *
- * This implementation aims to be compatible with the ARCFOUR description
- * available at
- * http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt
- */
-
-
-#ifndef ARCFOUR_H_
-#define ARCFOUR_H_
-
-#include <stdint.h>
-
-/** \typedef arcfour_ctx_t
- * \brief type for arcfour context
- *
- * A variable of this type may contain a complete ARCFOUR context.
- * The context is used to store the state of the cipher and gets
- * created by the arcfour_init(arcfour_ctx_t *c, uint8_t *key, uint8_t length_B)
- * function. The context is of the fixed size of 258 bytes
- */
-
-/** \struct arcfour_ctx_st
- * \brief base for ::arcfour_ctx_t
- *
- * The struct holds the two indices and the S-Box
- */
-typedef struct arcfour_ctx_st {
-       uint8_t i,j;
-       uint8_t s[256];
-} arcfour_ctx_t;
-
-
-/** \fn void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx)
- * \brief setup a context with a key
- *
- * This function sets up a ::arcfour_ctx_t context using
- * the supplied key of the given length.
- * \param ctx pointer to the context
- * \param key pointer to the key
- * \param length_B length of the key in bytes (between 1 and 255)
- */
-
-void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx);
-
-/** \fn uint8_t arcfour_gen(arcfour_ctx_t *ctx)
- * \brief generates a byte of keystream
- *
- * This function generates the next byte of keystream
- * from the supplied ::arcfour_ctx_t context which is updated accordingly
- *
- * \param ctx pointer to the context
- * \return byte of keystream
- */
-
-uint8_t arcfour_gen(arcfour_ctx_t *ctx);
-
-#endif
diff --git a/arcfour/arcfour-asm.S b/arcfour/arcfour-asm.S
new file mode 100644 (file)
index 0000000..1ef8218
--- /dev/null
@@ -0,0 +1,133 @@
+/* arcfour-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* 
+ * File:        arcfour-asm.S
+ * Author:      Daniel Otte
+ * Date:        2006-07-06
+ * License:     GPLv3 or later
+ * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ * 
+ */
+#include <avr/io.h>
+#include "avr-asm-macros.S"
+ /* +---+---+---------------------+
+ *  | i | j | ......<256>........ |
+ *  +---+---+---------------------+
+ */
+.global arcfour_init
+/*
+ *== arcfour_init ==
+ *  this function initialises the context
+ * param1: 16-bit pointer to the key
+ *     given in r24:r25
+ * param2: 8-bit integer indicating keylength in byte
+ *     given in r22
+ * param3: 16-bit pointer to a ctx struct
+ *     given in r20:r21
+ */
+arcfour_init:
+       push_ r28, r29
+       movw r26, r20   /* X points to ctx */
+       movw r30, r24   /* Z points to key */
+       st X+, r1
+       st X+, r1       /* X points to S */
+       movw r20, r26   /* store pointer to S in r21:r20 */
+       
+1:             
+       st X+, r1 
+       inc r1
+       brne 1b
+       
+       movw r26, r20
+       add r22, r30         /* r18 is keyindex counter */
+       clr r0
+       clr r19
+2:
+       ld r23, X
+       ld r18, Z+
+       add r19, r18
+       add r19, r23
+       movw r28, r20   /* load pointer to S in Y */
+       add r28, r19
+       adc r29, r1
+       ld r18, Y
+       st Y,  r23
+       st X+, r18
+       cp r30, r22
+       brne 3f
+       movw r30, r24
+3:             
+       inc r0
+       brne 2b 
+       pop_ r29, r28
+       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/arcfour.c b/arcfour/arcfour.c
new file mode 100644 (file)
index 0000000..e07193f
--- /dev/null
@@ -0,0 +1,63 @@
+/* arcfour.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * File:        arcfour.c
+ * Author:      Daniel Otte
+ * email:       daniel.otte@rub.de
+ * Date:        2006-06-07
+ * License:     GPLv3 or later
+ * 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(const void *key, uint8_t length_B, arcfour_ctx_t *ctx){
+       uint8_t t;
+       uint16_t x,y=0;
+       for(x=0; x<= 255; ++x)
+               ctx->s[x]=x;
+
+       for(x=0; x<= 255; ++x){
+               y += ctx->s[x] + ((uint8_t*)key)[x % length_B];
+               y &= 0xff;
+               /* ctx->s[y] <--> ctx->s[x] */
+               t = ctx->s[y];
+               ctx->s[y] = ctx->s[x];
+               ctx->s[x] = t;
+       }
+       ctx->i = ctx->j = 0;
+}
+
+uint8_t arcfour_gen(arcfour_ctx_t *ctx){
+       uint8_t t;
+       ctx->i++;
+       ctx->j += ctx->s[ctx->i];
+       /* ctx->s[i] <--> ctx->s[j] */
+       t = ctx->s[ctx->j];
+       ctx->s[ctx->j] = ctx->s[ctx->i];
+       ctx->s[ctx->i] = t;
+       return ctx->s[(ctx->s[ctx->j] + ctx->s[ctx->i]) & 0xff];
+}
+
diff --git a/arcfour/arcfour.h b/arcfour/arcfour.h
new file mode 100644 (file)
index 0000000..d332d7f
--- /dev/null
@@ -0,0 +1,91 @@
+/* arcfour.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * File:       arcfour.h
+ * Author:     Daniel Otte
+ * Date:       2006-06-07
+ * License: GPLv3+
+ * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ */
+
+/**
+ * \file       arcfour.h
+ * \author     Daniel Otte
+ * \date       2006-06-07
+ * \license GPLv3+
+ * \brief Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm.
+ *
+ * This header file defines the interface of the ARCFOUR cipher implementation.
+ *
+ * This implementation aims to be compatible with the ARCFOUR description
+ * available at
+ * http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt
+ */
+
+
+#ifndef ARCFOUR_H_
+#define ARCFOUR_H_
+
+#include <stdint.h>
+
+/** \typedef arcfour_ctx_t
+ * \brief type for arcfour context
+ *
+ * A variable of this type may contain a complete ARCFOUR context.
+ * The context is used to store the state of the cipher and gets
+ * created by the arcfour_init(arcfour_ctx_t *c, uint8_t *key, uint8_t length_B)
+ * function. The context is of the fixed size of 258 bytes
+ */
+
+/** \struct arcfour_ctx_st
+ * \brief base for ::arcfour_ctx_t
+ *
+ * The struct holds the two indices and the S-Box
+ */
+typedef struct arcfour_ctx_st {
+       uint8_t i,j;
+       uint8_t s[256];
+} arcfour_ctx_t;
+
+
+/** \fn void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx)
+ * \brief setup a context with a key
+ *
+ * This function sets up a ::arcfour_ctx_t context using
+ * the supplied key of the given length.
+ * \param ctx pointer to the context
+ * \param key pointer to the key
+ * \param length_B length of the key in bytes (between 1 and 255)
+ */
+
+void arcfour_init(const void *key, uint8_t length_B, arcfour_ctx_t *ctx);
+
+/** \fn uint8_t arcfour_gen(arcfour_ctx_t *ctx)
+ * \brief generates a byte of keystream
+ *
+ * This function generates the next byte of keystream
+ * from the supplied ::arcfour_ctx_t context which is updated accordingly
+ *
+ * \param ctx pointer to the context
+ * \return byte of keystream
+ */
+
+uint8_t arcfour_gen(arcfour_ctx_t *ctx);
+
+#endif
diff --git a/base64/base64_dec.c b/base64/base64_dec.c
new file mode 100644 (file)
index 0000000..f057f54
--- /dev/null
@@ -0,0 +1,246 @@
+/* base64_dec.c */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * base64 decoder (RFC3548)
+ * Author: Daniel Otte
+ * License: GPLv3
+ * 
+ * 
+ */
+
+#include <stdint.h>
+#include "base64_dec.h"
+
+#include "test_src/cli.h"
+
+/*
+ #define USE_GCC_EXTENSION
+*/
+#if 1
+
+#ifdef USE_GCC_EXTENSION
+
+static
+int ascii2bit6(char a){
+       switch(a){
+               case 'A'...'Z':
+                       return a-'A';
+               case 'a'...'z':
+                       return a-'a'+26;
+               case '0'...'9':
+                       return a-'0'+52;
+               case '+':
+               case '-':
+                       return 62;
+               case '/':
+               case '_':
+                       return 63;
+               default:
+                       return -1;
+       }
+}
+
+#else
+
+static
+uint8_t ascii2bit6(char a){
+       int r;
+       switch(a>>4){
+               case 0x5:
+               case 0x4: 
+                       r=a-'A';
+                       if(r<0 || r>25){
+                               return -1;
+                       } else {
+                               return r;
+                       }
+               case 0x7:
+               case 0x6: 
+                       r=a-'a';
+                       if(r<0 || r>25){
+                               return -1;
+                       } else {
+                               return r+26;
+                       }
+                       break;
+               case 0x3:
+                       if(a>'9')
+                               return -1;
+                       return a-'0'+52;
+               default:
+                       break;  
+       }
+       switch (a){
+               case '+':
+               case '-':
+                       return 62;
+               case '/':
+               case '_':
+                       return 63;
+               default:
+                       return 0xff;
+       }
+}
+
+#endif
+
+#else
+
+static 
+uint8_t ascii2bit6(uint8_t a){
+       if(a>='A' && a<='Z'){
+               return a-'A';
+       } else {
+               if(a>='a' && a<= 'z'){
+                       return a-'a'+26;
+               } else {
+                       if(a>='0' && a<='9'){
+                               return a-'0'+52;
+                       } else {
+                               if(a=='+' || a=='-'){
+                                       return 62;
+                               } else {
+                                       if(a=='/' || a=='_'){
+                                               return 63;
+                                       } else {
+                                               return 0xff;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+#endif
+
+int base64_binlength(char* str, uint8_t strict){
+       int l=0;
+       uint8_t term=0;
+       for(;;){
+               if(*str=='\0')
+                       break;
+               if(*str=='\n' || *str=='\r'){
+                       str++;
+                       continue;
+               }
+               if(*str=='='){
+                       term++;
+                       str++;
+                       if(term==2){
+                               break;
+                       }
+                       continue;
+               }
+               if(term)
+                       return -1;
+               if(ascii2bit6(*str)==-1){
+                       if(strict)
+                               return -1;
+               } else {
+                       l++;
+               }
+               str++;
+       }
+       switch(term){
+               case 0:
+                       if(l%4!=0)
+                               return -1;
+                       return l/4*3;
+               case 1:
+                       if(l%4!=3)
+                               return -1;
+                       return (l+1)/4*3-1;
+               case 2:
+                       if(l%4!=2)
+                               return -1;
+                       return (l+2)/4*3-2;
+               default:
+                       return -1;
+       }
+}
+
+/*
+  |543210543210543210543210|
+  |765432107654321076543210|
+
+        .      .      .     .
+  |54321054|32105432|10543210|
+  |76543210|76543210|76543210|
+
+*/
+
+int base64dec(void* dest, char* b64str, uint8_t strict){
+       uint8_t buffer[4];
+       uint8_t idx=0;
+       uint8_t term=0;
+       for(;;){
+//             cli_putstr_P(PSTR("\r\n  DBG: got 0x"));
+//             cli_hexdump(b64str, 1);
+               buffer[idx]= ascii2bit6(*b64str);
+//             cli_putstr_P(PSTR(" --> 0x"));
+//             cli_hexdump(buffer+idx, 1);
+               
+               if(buffer[idx]==0xFF){
+                       if(*b64str=='='){
+                               term++;
+                               b64str++;
+                               if(term==2)
+                                       goto finalize; /* definitly the end */
+                       }else{
+                               if(*b64str == '\0'){
+                                       goto finalize; /* definitly the end */
+                               }else{
+                                       if(*b64str == '\r' || *b64str == '\n' || !(strict)){
+                                               b64str++; /* charcters that we simply ignore */
+                                       }else{
+                                               return -1;
+                                       }
+                               }
+                       }
+               }else{
+                       if(term)
+                               return -1; /* this happens if we get a '=' in the stream */
+                       idx++;
+                       b64str++;
+               }
+               if(idx==4){
+                       ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+                       ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;
+                       ((uint8_t*)dest)[2] = buffer[2]<<6 | buffer[3];
+                       dest = (uint8_t*)dest +3;
+                       idx=0;
+               }
+       }
+  finalize:    
+       /* the final touch */
+       if(idx==0)
+               return 0;
+       if(term==1){
+               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+               ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;                      
+               return 0;
+       }
+       if(term==2){
+               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+               return 0;
+       }
+       return -1;
+}
diff --git a/base64/base64_dec.h b/base64/base64_dec.h
new file mode 100644 (file)
index 0000000..39beff8
--- /dev/null
@@ -0,0 +1,29 @@
+/* base64_dec.h */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef BASE64_DEC_H_
+#define BASE64_DEC_H_
+
+#include <stdint.h>
+
+int base64_binlength(char* str, uint8_t strict);
+int base64dec(void* dest, char* b64str, uint8_t strict);
+
+#endif /*BASE64_DEC_H_*/
diff --git a/base64/base64_enc.c b/base64/base64_enc.c
new file mode 100644 (file)
index 0000000..400f25c
--- /dev/null
@@ -0,0 +1,117 @@
+/* base64_enc.c */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * base64 encoder (RFC3548)
+ * Author: Daniel Otte
+ * License: GPLv3
+ * 
+ * 
+ */
+
+#include <stdint.h>
+#include "base64_enc.h"
+
+#if 1
+#include <avr/pgmspace.h>
+
+char base64_alphabet[64] PROGMEM = {
+       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
+       'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
+       'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 
+       'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 
+       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
+       'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
+       'w', 'x', 'y', 'z', '0', '1', '2', '3', 
+       '4', '5', '6', '7', '8', '9', '+', '/' }; 
+
+static 
+char bit6toAscii(uint8_t a){
+       a &= (uint8_t)0x3F;
+       return pgm_read_byte(base64_alphabet+a);
+}
+
+#else
+
+static 
+char bit6toAscii(uint8_t a){
+       a &= (uint8_t)0x3F;
+       
+       if(a<=25){
+               return a+'A';
+       } else {
+               if(a<=51){
+                       return a-26+'a';
+               } else {
+                       if(a<=61){
+                               return a-52+'0';
+                       } else {
+                               if(a==62){
+                                       return '+';
+                               } else {
+                                       return '/'; /* a == 63 */
+                               }
+                       }
+               }
+       }
+}
+
+#endif
+
+void base64enc(char* dest, void* src, uint16_t length){
+       uint16_t i,j;
+       uint8_t a[4];
+       for(i=0; i<length/3; ++i){
+               a[0]= (((uint8_t*)src)[i*3+0])>>2;
+               a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
+               a[2]= (((((uint8_t*)src)[i*3+1])<<2) | ((((uint8_t*)src)[i*3+2])>>6)) & 0x3F;
+               a[3]= (((uint8_t*)src)[i*3+2]) & 0x3F;
+               for(j=0; j<4; ++j){
+                       *dest++=bit6toAscii(a[j]);
+               }
+       }
+       /* now we do the rest */
+       switch(length%3){
+               case 0: 
+                       break;
+               case 1:
+                       a[0]=(((uint8_t*)src)[i*3+0])>>2;
+                       a[1]=((((uint8_t*)src)[i*3+0])<<4)&0x3F;
+                       *dest++ = bit6toAscii(a[0]);
+                       *dest++ = bit6toAscii(a[1]);
+                       *dest++ = '=';
+                       *dest++ = '=';
+                       break;
+               case 2:         
+                       a[0]= (((uint8_t*)src)[i*3+0])>>2;
+                       a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
+                       a[2]= ((((uint8_t*)src)[i*3+1])<<2) & 0x3F;
+                       *dest++ = bit6toAscii(a[0]);
+                       *dest++ = bit6toAscii(a[1]);
+                       *dest++ = bit6toAscii(a[2]);
+                       *dest++ = '=';
+                       break;
+               default: /* this will not happen! */
+                       break;  
+       }
+/*  finalize: */
+       *dest='\0';
+}
+
diff --git a/base64/base64_enc.h b/base64/base64_enc.h
new file mode 100644 (file)
index 0000000..9065132
--- /dev/null
@@ -0,0 +1,28 @@
+/* base64_enc.h */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef BASE64_ENC_H_
+#define BASE64_ENC_H_
+
+#include <stdint.h>
+
+void base64enc(char* dest, void* src, uint16_t length);
+
+#endif /*BASE64_ENC_H_*/
diff --git a/base64_dec.c b/base64_dec.c
deleted file mode 100644 (file)
index f057f54..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/* base64_dec.c */
-/*
- *   This file is part of the AVR-Crypto-Lib.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/**
- * base64 decoder (RFC3548)
- * Author: Daniel Otte
- * License: GPLv3
- * 
- * 
- */
-
-#include <stdint.h>
-#include "base64_dec.h"
-
-#include "test_src/cli.h"
-
-/*
- #define USE_GCC_EXTENSION
-*/
-#if 1
-
-#ifdef USE_GCC_EXTENSION
-
-static
-int ascii2bit6(char a){
-       switch(a){
-               case 'A'...'Z':
-                       return a-'A';
-               case 'a'...'z':
-                       return a-'a'+26;
-               case '0'...'9':
-                       return a-'0'+52;
-               case '+':
-               case '-':
-                       return 62;
-               case '/':
-               case '_':
-                       return 63;
-               default:
-                       return -1;
-       }
-}
-
-#else
-
-static
-uint8_t ascii2bit6(char a){
-       int r;
-       switch(a>>4){
-               case 0x5:
-               case 0x4: 
-                       r=a-'A';
-                       if(r<0 || r>25){
-                               return -1;
-                       } else {
-                               return r;
-                       }
-               case 0x7:
-               case 0x6: 
-                       r=a-'a';
-                       if(r<0 || r>25){
-                               return -1;
-                       } else {
-                               return r+26;
-                       }
-                       break;
-               case 0x3:
-                       if(a>'9')
-                               return -1;
-                       return a-'0'+52;
-               default:
-                       break;  
-       }
-       switch (a){
-               case '+':
-               case '-':
-                       return 62;
-               case '/':
-               case '_':
-                       return 63;
-               default:
-                       return 0xff;
-       }
-}
-
-#endif
-
-#else
-
-static 
-uint8_t ascii2bit6(uint8_t a){
-       if(a>='A' && a<='Z'){
-               return a-'A';
-       } else {
-               if(a>='a' && a<= 'z'){
-                       return a-'a'+26;
-               } else {
-                       if(a>='0' && a<='9'){
-                               return a-'0'+52;
-                       } else {
-                               if(a=='+' || a=='-'){
-                                       return 62;
-                               } else {
-                                       if(a=='/' || a=='_'){
-                                               return 63;
-                                       } else {
-                                               return 0xff;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-#endif
-
-int base64_binlength(char* str, uint8_t strict){
-       int l=0;
-       uint8_t term=0;
-       for(;;){
-               if(*str=='\0')
-                       break;
-               if(*str=='\n' || *str=='\r'){
-                       str++;
-                       continue;
-               }
-               if(*str=='='){
-                       term++;
-                       str++;
-                       if(term==2){
-                               break;
-                       }
-                       continue;
-               }
-               if(term)
-                       return -1;
-               if(ascii2bit6(*str)==-1){
-                       if(strict)
-                               return -1;
-               } else {
-                       l++;
-               }
-               str++;
-       }
-       switch(term){
-               case 0:
-                       if(l%4!=0)
-                               return -1;
-                       return l/4*3;
-               case 1:
-                       if(l%4!=3)
-                               return -1;
-                       return (l+1)/4*3-1;
-               case 2:
-                       if(l%4!=2)
-                               return -1;
-                       return (l+2)/4*3-2;
-               default:
-                       return -1;
-       }
-}
-
-/*
-  |543210543210543210543210|
-  |765432107654321076543210|
-
-        .      .      .     .
-  |54321054|32105432|10543210|
-  |76543210|76543210|76543210|
-
-*/
-
-int base64dec(void* dest, char* b64str, uint8_t strict){
-       uint8_t buffer[4];
-       uint8_t idx=0;
-       uint8_t term=0;
-       for(;;){
-//             cli_putstr_P(PSTR("\r\n  DBG: got 0x"));
-//             cli_hexdump(b64str, 1);
-               buffer[idx]= ascii2bit6(*b64str);
-//             cli_putstr_P(PSTR(" --> 0x"));
-//             cli_hexdump(buffer+idx, 1);
-               
-               if(buffer[idx]==0xFF){
-                       if(*b64str=='='){
-                               term++;
-                               b64str++;
-                               if(term==2)
-                                       goto finalize; /* definitly the end */
-                       }else{
-                               if(*b64str == '\0'){
-                                       goto finalize; /* definitly the end */
-                               }else{
-                                       if(*b64str == '\r' || *b64str == '\n' || !(strict)){
-                                               b64str++; /* charcters that we simply ignore */
-                                       }else{
-                                               return -1;
-                                       }
-                               }
-                       }
-               }else{
-                       if(term)
-                               return -1; /* this happens if we get a '=' in the stream */
-                       idx++;
-                       b64str++;
-               }
-               if(idx==4){
-                       ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-                       ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;
-                       ((uint8_t*)dest)[2] = buffer[2]<<6 | buffer[3];
-                       dest = (uint8_t*)dest +3;
-                       idx=0;
-               }
-       }
-  finalize:    
-       /* the final touch */
-       if(idx==0)
-               return 0;
-       if(term==1){
-               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-               ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;                      
-               return 0;
-       }
-       if(term==2){
-               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-               return 0;
-       }
-       return -1;
-}
diff --git a/base64_dec.h b/base64_dec.h
deleted file mode 100644 (file)
index 39beff8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* base64_dec.h */
-/*
- *   This file is part of the AVR-Crypto-Lib.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef BASE64_DEC_H_
-#define BASE64_DEC_H_
-
-#include <stdint.h>
-
-int base64_binlength(char* str, uint8_t strict);
-int base64dec(void* dest, char* b64str, uint8_t strict);
-
-#endif /*BASE64_DEC_H_*/
diff --git a/base64_enc.c b/base64_enc.c
deleted file mode 100644 (file)
index 400f25c..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* base64_enc.c */
-/*
- *   This file is part of the AVR-Crypto-Lib.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/**
- * base64 encoder (RFC3548)
- * Author: Daniel Otte
- * License: GPLv3
- * 
- * 
- */
-
-#include <stdint.h>
-#include "base64_enc.h"
-
-#if 1
-#include <avr/pgmspace.h>
-
-char base64_alphabet[64] PROGMEM = {
-       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
-       'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
-       'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 
-       'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 
-       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
-       'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
-       'w', 'x', 'y', 'z', '0', '1', '2', '3', 
-       '4', '5', '6', '7', '8', '9', '+', '/' }; 
-
-static 
-char bit6toAscii(uint8_t a){
-       a &= (uint8_t)0x3F;
-       return pgm_read_byte(base64_alphabet+a);
-}
-
-#else
-
-static 
-char bit6toAscii(uint8_t a){
-       a &= (uint8_t)0x3F;
-       
-       if(a<=25){
-               return a+'A';
-       } else {
-               if(a<=51){
-                       return a-26+'a';
-               } else {
-                       if(a<=61){
-                               return a-52+'0';
-                       } else {
-                               if(a==62){
-                                       return '+';
-                               } else {
-                                       return '/'; /* a == 63 */
-                               }
-                       }
-               }
-       }
-}
-
-#endif
-
-void base64enc(char* dest, void* src, uint16_t length){
-       uint16_t i,j;
-       uint8_t a[4];
-       for(i=0; i<length/3; ++i){
-               a[0]= (((uint8_t*)src)[i*3+0])>>2;
-               a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
-               a[2]= (((((uint8_t*)src)[i*3+1])<<2) | ((((uint8_t*)src)[i*3+2])>>6)) & 0x3F;
-               a[3]= (((uint8_t*)src)[i*3+2]) & 0x3F;
-               for(j=0; j<4; ++j){
-                       *dest++=bit6toAscii(a[j]);
-               }
-       }
-       /* now we do the rest */
-       switch(length%3){
-               case 0: 
-                       break;
-               case 1:
-                       a[0]=(((uint8_t*)src)[i*3+0])>>2;
-                       a[1]=((((uint8_t*)src)[i*3+0])<<4)&0x3F;
-                       *dest++ = bit6toAscii(a[0]);
-                       *dest++ = bit6toAscii(a[1]);
-                       *dest++ = '=';
-                       *dest++ = '=';
-                       break;
-               case 2:         
-                       a[0]= (((uint8_t*)src)[i*3+0])>>2;
-                       a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
-                       a[2]= ((((uint8_t*)src)[i*3+1])<<2) & 0x3F;
-                       *dest++ = bit6toAscii(a[0]);
-                       *dest++ = bit6toAscii(a[1]);
-                       *dest++ = bit6toAscii(a[2]);
-                       *dest++ = '=';
-                       break;
-               default: /* this will not happen! */
-                       break;  
-       }
-/*  finalize: */
-       *dest='\0';
-}
-
diff --git a/base64_enc.h b/base64_enc.h
deleted file mode 100644 (file)
index 9065132..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* base64_enc.h */
-/*
- *   This file is part of the AVR-Crypto-Lib.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef BASE64_ENC_H_
-#define BASE64_ENC_H_
-
-#include <stdint.h>
-
-void base64enc(char* dest, void* src, uint16_t length);
-
-#endif /*BASE64_ENC_H_*/
diff --git a/bmw/bmw_large.c b/bmw/bmw_large.c
new file mode 100644 (file)
index 0000000..10e65f6
--- /dev/null
@@ -0,0 +1,468 @@
+/* bmw_large.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file    bmw_large.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "bmw_large.h"
+
+#define SHL64(a,n) ((a)<<(n))
+#define SHR64(a,n) ((a)>>(n))
+#define ROTL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
+#define ROTR64(a,n) (((a)>>(n))|((a)<<(64-(n))))
+
+#define BUG24 0
+#define F0_HACK 1
+#define DEBUG 0
+#if DEBUG
+ #include "cli.h"
+ void ctx_dump(const bmw_large_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr_P(PSTR("\r\n==== ctx dump ===="));
+       for(i=0; i<16;++i){
+               cli_putstr_P(PSTR("\r\n h["));
+               cli_hexdump(&i, 1);
+               cli_putstr_P(PSTR("] = "));
+               cli_hexdump_rev(&(ctx->h[i]), 8);
+       }
+       cli_putstr_P(PSTR("\r\n counter = "));
+       cli_hexdump(&(ctx->counter), 4);
+ }
+ void dump_x(const uint64_t* q, uint8_t elements, char x){
+       uint8_t i;
+       cli_putstr_P(PSTR("\r\n==== "));
+       cli_putc(x);
+       cli_putstr_P(PSTR(" dump ===="));
+       for(i=0; i<elements;++i){
+               cli_putstr_P(PSTR("\r\n "));
+               cli_putc(x);
+               cli_putstr_P(PSTR("["));
+               cli_hexdump(&i, 1);
+               cli_putstr_P(PSTR("] = "));
+               cli_hexdump_rev(&(q[i]), 8);
+       }
+ }
+#else
+ #define ctx_dump(x)
+ #define dump_x(a,b,c)
+#endif
+
+uint64_t bmw_large_s0(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ SHL64(x, 3)
+               ^ ROTL64(x, 4)
+               ^ ROTR64(x, 64-37);
+       return r;       
+}
+
+uint64_t bmw_large_s1(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ SHL64(x, 2)
+               ^ ROTL64(x,13)
+               ^ ROTR64(x,64-43);
+       return r;       
+}
+
+uint64_t bmw_large_s2(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ SHL64(x, 1)
+               ^ ROTL64(x, 19)
+               ^ ROTR64(x, 64-53);
+       return r;       
+}
+
+uint64_t bmw_large_s3(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ SHL64(x, 2)
+               ^ ROTL64(x, 28)
+               ^ ROTR64(x, 64-59);
+       return r;       
+}
+
+uint64_t bmw_large_s4(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 1)
+               ^ x;
+       return r;       
+}
+
+uint64_t bmw_large_s5(uint64_t x){
+       uint64_t r;
+       r =   SHR64(x, 2)
+               ^ x;
+       return r;       
+}
+
+uint64_t bmw_large_r1(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 5);
+       return r;       
+}
+
+uint64_t bmw_large_r2(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 11);
+       return r;       
+}
+
+uint64_t bmw_large_r3(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 27);
+       return r;       
+}
+
+uint64_t bmw_large_r4(uint64_t x){
+       uint64_t r;
+       r =   ROTL64(x, 32);
+       return r;       
+}
+
+uint64_t bmw_large_r5(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-37);
+       return r;       
+}
+
+uint64_t bmw_large_r6(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-43);
+       return r;       
+}
+
+uint64_t bmw_large_r7(uint64_t x){
+       uint64_t r;
+       r =   ROTR64(x, 64-53);
+       return r;       
+}
+/*
+#define K    0x0555555555555555LL
+#define MASK 0xFFFFFFFFFFFFFFFFLL
+static
+uint64_t k_lut[] PROGMEM = {
+       16LL*K, 17LL*K, 18LL*K, 19LL*K, 
+       20LL*K, 21LL*K, 22LL*K, 23LL*K,
+       24LL*K, 25LL*K, 26LL*K, 27LL*K,
+       28LL*K, 29LL*K, 30LL*K, 31LL*K };
+*/     
+/* the same as above but precomputed to avoid compiler warnings */
+static
+uint64_t k_lut[] PROGMEM = {
+       0x5555555555555550LL, 0x5aaaaaaaaaaaaaa5LL, 0x5ffffffffffffffaLL,
+       0x655555555555554fLL, 0x6aaaaaaaaaaaaaa4LL, 0x6ffffffffffffff9LL,
+       0x755555555555554eLL, 0x7aaaaaaaaaaaaaa3LL, 0x7ffffffffffffff8LL,
+       0x855555555555554dLL, 0x8aaaaaaaaaaaaaa2LL, 0x8ffffffffffffff7LL,
+       0x955555555555554cLL, 0x9aaaaaaaaaaaaaa1LL, 0x9ffffffffffffff6LL,
+       0xa55555555555554bLL };
+
+uint64_t bmw_large_expand1(uint8_t j, const uint64_t* q, const void* m){
+       uint64_t(*s[])(uint64_t) = {bmw_large_s1, bmw_large_s2, bmw_large_s3, bmw_large_s0};
+       union{
+               uint64_t v64;
+               uint32_t v32[2];
+       } r;
+       uint8_t i;
+       /* r = 0x0555555555555555LL*(j+16); */
+       r.v32[0] = pgm_read_dword(((uint8_t*)k_lut+8*j));
+       r.v32[1] = pgm_read_dword(((uint8_t*)k_lut+8*j+4));
+       for(i=0; i<16; ++i){
+               r.v64 += s[i%4](q[j+i]);
+       }
+       r.v64 += ((uint64_t*)m)[j];
+       r.v64 += ((uint64_t*)m)[j+3];
+       r.v64 -= ((uint64_t*)m)[j+10];
+       return r.v64;
+}
+
+uint64_t bmw_large_expand2(uint8_t j, const uint64_t* q, const void* m){
+       uint64_t(*rf[])(uint64_t) = {bmw_large_r1, bmw_large_r2, bmw_large_r3,
+                                    bmw_large_r4, bmw_large_r5, bmw_large_r6,
+                                                            bmw_large_r7};
+       union{
+               uint64_t v64;
+               uint32_t v32[2];
+       } r;
+       uint8_t i;
+       /* r = 0x0555555555555555LL*(j+16); */
+       r.v32[0] = pgm_read_dword(((uint8_t*)k_lut+8*j));
+       r.v32[1] = pgm_read_dword(((uint8_t*)k_lut+8*j+4));
+       for(i=0; i<14; i+=2){
+               r.v64 += q[j+i];
+       }
+       for(i=0; i<14; i+=2){
+               r.v64 += rf[i/2](q[j+i+1]);
+       }
+       r.v64 += bmw_large_s5(q[j+14]);
+       r.v64 += bmw_large_s4(q[j+15]);
+       r.v64 += ((uint64_t*)m)[j];
+       r.v64 += ((uint64_t*)m)[(j+3)%16];
+       r.v64 -= ((uint64_t*)m)[(j+10)%16];
+       return r.v64;
+}
+
+#if F0_HACK
+static
+uint8_t f0_lut[] PROGMEM ={
+        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
+        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
+        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
+        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
+        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
+        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
+        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0, 
+        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
+        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
+        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
+        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
+        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
+        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
+        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
+        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
+       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
+};
+
+void bmw_large_f0(uint64_t* q, uint64_t* h, const void* m){
+       uint8_t i,j=-1,v,sign,l=0;
+       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
+                                  bmw_large_s3, bmw_large_s4 };
+       for(i=0; i<16; ++i){
+               h[i] ^= ((uint64_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+//     memset(q, 0, 4*16);
+       for(i=0; i<5*16; ++i){
+               v = pgm_read_byte(f0_lut+i);
+               sign = v&1;
+               v >>=1;
+               if(i==l){
+                       j++;
+                       l+=5;
+                       q[j] = h[v];
+                       continue;
+               }
+               if(sign){
+                       q[j] -= h[v];
+               }else{
+                       q[j] += h[v];
+               }
+       }
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }       
+}
+
+#else
+void bmw_large_f0(uint64_t* q, uint64_t* h, const void* m){
+       uint8_t i;
+       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
+                                  bmw_large_s3, bmw_large_s4 };
+       for(i=0; i<16; ++i){
+               h[i] ^= ((uint64_t*)m)[i];
+       }
+       dump_x(t, 16, 'T');
+       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
+       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
+       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
+       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
+       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]); 
+       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
+       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
+       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
+       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
+       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
+       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]); 
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }       
+}
+#endif
+
+void bmw_large_f1(uint64_t* q, const void* m){
+       uint8_t i;
+       q[16] = bmw_large_expand1(0, q, m);
+       q[17] = bmw_large_expand1(1, q, m);
+       for(i=2; i<16; ++i){
+               q[16+i] = bmw_large_expand2(i, q, m);
+       }
+}
+
+void bmw_large_f2(uint64_t* h, const uint64_t* q, const void* m){
+       uint64_t xl=0, xh;
+       uint8_t i;
+       for(i=16;i<24;++i){
+               xl ^= q[i];
+       }
+       xh = xl;
+       for(i=24;i<32;++i){
+               xh ^= q[i];
+       }
+#if DEBUG      
+       cli_putstr_P(PSTR("\r\n XL = "));
+       cli_hexdump_rev(&xl, 4);
+       cli_putstr_P(PSTR("\r\n XH = "));
+       cli_hexdump_rev(&xh, 4);
+#endif
+       memcpy(h, m, 16*8);
+       h[0] ^= SHL64(xh, 5) ^ SHR64(q[16], 5);
+       h[1] ^= SHR64(xh, 7) ^ SHL64(q[17], 8);
+       h[2] ^= SHR64(xh, 5) ^ SHL64(q[18], 5);
+       h[3] ^= SHR64(xh, 1) ^ SHL64(q[19], 5);
+       h[4] ^= SHR64(xh, 3) ^ q[20];
+       h[5] ^= SHL64(xh, 6) ^ SHR64(q[21], 6);
+       h[6] ^= SHR64(xh, 4) ^ SHL64(q[22], 6);
+       h[7] ^= SHR64(xh,11) ^ SHL64(q[23], 2);
+       for(i=0; i<8; ++i){
+               h[i] += xl ^ q[24+i] ^ q[i];
+       }
+       for(i=0; i<8; ++i){
+               h[8+i] ^= xh ^ q[24+i];
+               h[8+i] += ROTL64(h[(4+i)%8],i+9);
+       }
+       h[ 8] += SHL64(xl, 8) ^ q[23] ^ q[ 8];
+       h[ 9] += SHR64(xl, 6) ^ q[16] ^ q[ 9];
+       h[10] += SHL64(xl, 6) ^ q[17] ^ q[10];
+       h[11] += SHL64(xl, 4) ^ q[18] ^ q[11];
+       h[12] += SHR64(xl, 3) ^ q[19] ^ q[12];
+       h[13] += SHR64(xl, 4) ^ q[20] ^ q[13];
+       h[14] += SHR64(xl, 7) ^ q[21] ^ q[14];
+       h[15] += SHR64(xl, 2) ^ q[22] ^ q[15];
+}
+
+void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block){
+       uint64_t q[32];
+       dump_x(block, 16, 'M');
+       bmw_large_f0(q, ctx->h, block);
+       dump_x(q, 16, 'Q');
+       bmw_large_f1(q, block);
+       dump_x(q, 32, 'Q');
+       bmw_large_f2(ctx->h, q, block);
+       ctx->counter += 1;
+       ctx_dump(ctx);
+}
+
+void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[128];
+       while(length_b >= BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(ctx, block);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               block = (uint8_t*)block + BMW_LARGE_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 128);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
+       if(length_b+1>128*8-64){
+               bmw_large_nextBlock(ctx, buffer);
+               memset(buffer, 0, 128-8);
+               ctx->counter -= 1;
+       }
+       *((uint64_t*)&(buffer[128-8])) = (uint64_t)(ctx->counter*1024LL)+(uint64_t)length_b;
+       bmw_large_nextBlock(ctx, buffer);
+}
+
+void bmw384_init(bmw384_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x0001020304050607LL;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
+       }
+#if BUG24      
+       ctx->h[6] = 0x3031323324353637LL;
+#endif
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw512_init(bmw512_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x8081828384858687LL;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block){
+       bmw_large_nextBlock(ctx, block);
+}
+
+void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block){
+       bmw_large_nextBlock(ctx, block);
+}
+
+void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_large_lastBlock(ctx, block, length_b);
+}
+
+void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_large_lastBlock(ctx, block, length_b);
+}
+
+void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[10]), 384/8);
+}
+
+void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[8]), 512/8);
+}
+
+void bmw384(void* dest, const void* msg, uint32_t length_b){
+       bmw_large_ctx_t ctx;
+       bmw384_init(&ctx);
+       while(length_b>=BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(&ctx, msg);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
+       }
+       bmw_large_lastBlock(&ctx, msg, length_b);
+       bmw384_ctx2hash(dest, &ctx);
+}
+
+void bmw512(void* dest, const void* msg, uint32_t length_b){
+       bmw_large_ctx_t ctx;
+       bmw512_init(&ctx);
+       while(length_b>=BMW_LARGE_BLOCKSIZE){
+               bmw_large_nextBlock(&ctx, msg);
+               length_b -= BMW_LARGE_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
+       }
+       bmw_large_lastBlock(&ctx, msg, length_b);
+       bmw512_ctx2hash(dest, &ctx);
+}
+
diff --git a/bmw/bmw_large.h b/bmw/bmw_large.h
new file mode 100644 (file)
index 0000000..fba01fb
--- /dev/null
@@ -0,0 +1,65 @@
+/* bmw_large.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file    bmw_large.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BMW_LARGE_H_
+#define BMW_LARGE_H_
+
+#include <stdint.h>
+
+#define BMW_LARGE_BLOCKSIZE   1024
+#define BMW_LARGE_BLOCKSIZE_B ((BMW_LARGE_BLOCKSIZE+7)/8)
+#define BMW384_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
+#define BMW384_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
+#define BMW512_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
+#define BMW512_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
+
+typedef struct {
+       uint64_t h[16];
+       uint32_t counter;
+} bmw_large_ctx_t;
+
+typedef bmw_large_ctx_t bmw384_ctx_t;
+typedef bmw_large_ctx_t bmw512_ctx_t;
+
+void bmw384_init(bmw384_ctx_t* ctx);
+void bmw512_init(bmw512_ctx_t* ctx);
+
+void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block);
+void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block);
+void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block);
+void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx);
+void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx);
+
+void bmw384(void* dest, const void* msg, uint32_t length_b);
+void bmw512(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BMW_LARGE_H_ */
diff --git a/bmw/bmw_small.c b/bmw/bmw_small.c
new file mode 100644 (file)
index 0000000..aefd592
--- /dev/null
@@ -0,0 +1,461 @@
+/* bmw_small.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file    bmw_small.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "bmw_small.h"
+
+
+#define SHL32(a,n) ((a)<<(n))
+#define SHR32(a,n) ((a)>>(n))
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
+
+#define BUG24   0
+#define F0_HACK 1
+
+#define DEBUG 0
+#if DEBUG
+ #include "cli.h"
+ void ctx_dump(const bmw_small_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr_P(PSTR("\r\n==== ctx dump ===="));
+       for(i=0; i<16;++i){
+               cli_putstr_P(PSTR("\r\n h["));
+               cli_hexdump(&i, 1);
+               cli_putstr_P(PSTR("] = "));
+               cli_hexdump_rev(&(ctx->h[i]), 4);
+       }
+       cli_putstr_P(PSTR("\r\n counter = "));
+       cli_hexdump(&(ctx->counter), 4);
+ }
+ void dump_x(const uint32_t* q, uint8_t elements, char x){
+       uint8_t i;
+       cli_putstr_P(PSTR("\r\n==== "));
+       cli_putc(x);
+       cli_putstr_P(PSTR(" dump ===="));
+       for(i=0; i<elements;++i){
+               cli_putstr_P(PSTR("\r\n "));
+               cli_putc(x);
+               cli_putstr_P(PSTR("["));
+               cli_hexdump(&i, 1);
+               cli_putstr_P(PSTR("] = "));
+               cli_hexdump_rev(&(q[i]), 4);
+       }
+ }
+#else
+ #define ctx_dump(x)
+ #define dump_x(a,b,c)
+#endif
+
+uint32_t bmw_small_s0(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ SHL32(x, 3)
+               ^ ROTL32(x, 4)
+               ^ ROTR32(x, 13);
+       return r;       
+}
+
+uint32_t bmw_small_s1(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ SHL32(x, 2)
+               ^ ROTL32(x, 8)
+               ^ ROTR32(x, 9);
+       return r;       
+}
+
+uint32_t bmw_small_s2(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ SHL32(x, 1)
+               ^ ROTL32(x, 12)
+               ^ ROTR32(x, 7);
+       return r;       
+}
+
+uint32_t bmw_small_s3(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ SHL32(x, 2)
+               ^ ROTL32(x, 15)
+               ^ ROTR32(x, 3);
+       return r;       
+}
+
+uint32_t bmw_small_s4(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 1)
+               ^ x;
+       return r;       
+}
+
+uint32_t bmw_small_s5(uint32_t x){
+       uint32_t r;
+       r =   SHR32(x, 2)
+               ^ x;
+       return r;       
+}
+
+uint32_t bmw_small_r1(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 3);
+       return r;       
+}
+
+uint32_t bmw_small_r2(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 7);
+       return r;       
+}
+
+uint32_t bmw_small_r3(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 13);
+       return r;       
+}
+
+uint32_t bmw_small_r4(uint32_t x){
+       uint32_t r;
+       r =   ROTL32(x, 16);
+       return r;       
+}
+
+uint32_t bmw_small_r5(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 13);
+       return r;       
+}
+
+uint32_t bmw_small_r6(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 9);
+       return r;       
+}
+
+uint32_t bmw_small_r7(uint32_t x){
+       uint32_t r;
+       r =   ROTR32(x, 5);
+       return r;       
+}
+/*
+#define K 0x05555555L
+static
+uint32_t k_lut[] PROGMEM = {
+       16L*K, 17L*K, 18L*K, 19L*K, 20L*K, 21L*K, 22L*K, 23L*K,
+       24L*K, 25L*K, 26L*K, 27L*K, 28L*K, 29L*K, 30L*K, 31L*K
+};
+*/
+/* same as above but precomputed to avoid compiler warnings */
+
+static
+uint32_t k_lut[] PROGMEM = {
+       0x55555550L, 0x5aaaaaa5L, 0x5ffffffaL, 
+       0x6555554fL, 0x6aaaaaa4L, 0x6ffffff9L, 
+       0x7555554eL, 0x7aaaaaa3L, 0x7ffffff8L, 
+       0x8555554dL, 0x8aaaaaa2L, 0x8ffffff7L,
+       0x9555554cL, 0x9aaaaaa1L, 0x9ffffff6L, 
+       0xa555554bL };
+
+
+uint32_t bmw_small_expand1(uint8_t j, const uint32_t* q, const void* m){
+       uint32_t(*s[])(uint32_t) = {bmw_small_s1, bmw_small_s2, bmw_small_s3, bmw_small_s0};
+       uint32_t r;
+       uint8_t i;
+       /* r = 0x05555555*(j+16); */
+       r = pgm_read_dword(k_lut+j);
+       for(i=0; i<16; ++i){
+               r += s[i%4](q[j+i]);
+       }
+       r += ((uint32_t*)m)[j];
+       r += ((uint32_t*)m)[j+3];
+       r -= ((uint32_t*)m)[j+10];
+       return r;
+}
+
+uint32_t bmw_small_expand2(uint8_t j, const uint32_t* q, const void* m){
+       uint32_t(*rf[])(uint32_t) = {bmw_small_r1, bmw_small_r2, bmw_small_r3,
+                                    bmw_small_r4, bmw_small_r5, bmw_small_r6,
+                                                            bmw_small_r7};
+       uint32_t r;
+       uint8_t i;
+       /* r = 0x05555555*(j+16); */
+       r = pgm_read_dword(k_lut+j);
+       for(i=0; i<14; i+=2){
+               r += q[j+i];
+       }
+       for(i=0; i<14; i+=2){
+               r += rf[i/2](q[j+i+1]);
+       }
+       r += bmw_small_s5(q[j+14]);
+       r += bmw_small_s4(q[j+15]);
+       r += ((uint32_t*)m)[j];
+       r += ((uint32_t*)m)[(j+3)%16];
+       r -= ((uint32_t*)m)[(j+10)%16];
+       return r;
+}
+#if F0_HACK
+static
+uint8_t f0_lut[] PROGMEM = {
+        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
+        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
+        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
+        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
+        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
+        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
+        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0, 
+        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
+        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
+        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
+        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
+        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
+        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
+        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
+        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
+       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
+};
+
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint8_t i,j=-1,v,sign,l=0;
+       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
+                                  bmw_small_s3, bmw_small_s4 };
+       for(i=0; i<16; ++i){
+               h[i] ^= ((uint32_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       // memset(q, 0, 4*16);
+       for(i=0; i<5*16; ++i){
+               v = pgm_read_byte(f0_lut+i);
+               sign = v&1;
+               v >>=1;
+               if(i==l){
+                       j++;
+                       l+=5;
+                       q[j] = h[v];
+                       continue;
+               }
+               if(sign){
+                       q[j] -= h[v];
+               }else{
+                       q[j] += h[v];
+               }
+       }
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }       
+}
+
+#else
+void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
+       uint8_t i;
+       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
+                                  bmw_small_s3, bmw_small_s4 };
+       for(i=0; i<16; ++i){
+               h[i] ^= ((uint32_t*)m)[i];
+       }
+       dump_x(h, 16, 'T');
+       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
+       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
+       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
+       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
+       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
+       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
+       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]); 
+       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
+       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
+       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
+       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
+       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
+       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
+       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
+       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
+       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]); 
+       dump_x(q, 16, 'W');
+       for(i=0; i<16; ++i){
+               q[i] = s[i%5](q[i]);
+       }       
+}
+#endif
+
+void bmw_small_f1(uint32_t* q, const void* m){
+       uint8_t i;
+       q[16] = bmw_small_expand1(0, q, m);
+       q[17] = bmw_small_expand1(1, q, m);
+       for(i=2; i<16; ++i){
+               q[16+i] = bmw_small_expand2(i, q, m);
+       }
+}
+
+void bmw_small_f2(uint32_t* h, const uint32_t* q, const void* m){
+       uint32_t xl=0, xh;
+       uint8_t i;
+       for(i=16;i<24;++i){
+               xl ^= q[i];
+       }
+       xh = xl;
+       for(i=24;i<32;++i){
+               xh ^= q[i];
+       }
+#if DEBUG      
+       cli_putstr_P(PSTR("\r\n XL = "));
+       cli_hexdump_rev(&xl, 4);
+       cli_putstr_P(PSTR("\r\n XH = "));
+       cli_hexdump_rev(&xh, 4);
+#endif
+       memcpy(h, m, 16*4);
+       h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5);
+       h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8);
+       h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5);
+       h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5);
+       h[4] ^= SHR32(xh, 3) ^ q[20];
+       h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6);
+       h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6);
+       h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2);
+       for(i=0; i<8; ++i){
+               h[i] += xl ^ q[24+i] ^ q[i];
+       }
+       for(i=0; i<8; ++i){
+               h[8+i] ^= xh ^ q[24+i];
+               h[8+i] += ROTL32(h[(4+i)%8],i+9);
+       }
+       h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8];
+       h[ 9] += SHR32(xl, 6) ^ q[16] ^ q[ 9];
+       h[10] += SHL32(xl, 6) ^ q[17] ^ q[10];
+       h[11] += SHL32(xl, 4) ^ q[18] ^ q[11];
+       h[12] += SHR32(xl, 3) ^ q[19] ^ q[12];
+       h[13] += SHR32(xl, 4) ^ q[20] ^ q[13];
+       h[14] += SHR32(xl, 7) ^ q[21] ^ q[14];
+       h[15] += SHR32(xl, 2) ^ q[22] ^ q[15];
+}
+
+void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){
+       uint32_t q[32];
+       dump_x(block, 16, 'M');
+       bmw_small_f0(q, ctx->h, block);
+       dump_x(q, 16, 'Q');
+       bmw_small_f1(q, block);
+       dump_x(q, 32, 'Q');
+       bmw_small_f2(ctx->h, q, block);
+       ctx->counter += 1;
+       ctx_dump(ctx);
+}
+
+void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b){
+       uint8_t buffer[64];
+       while(length_b >= BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(ctx, block);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
+       }
+       memset(buffer, 0, 64);
+       memcpy(buffer, block, (length_b+7)/8);
+       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
+       if(length_b+1>64*8-64){
+               bmw_small_nextBlock(ctx, buffer);
+               memset(buffer, 0, 64-8);
+               ctx->counter -= 1;
+       }
+       *((uint64_t*)&(buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
+       bmw_small_nextBlock(ctx, buffer);
+}
+
+void bmw224_init(bmw224_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x00010203;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+#if BUG24      
+       ctx->h[13] = 0x24353637;
+#endif
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw256_init(bmw256_ctx_t* ctx){
+       uint8_t i;
+       ctx->h[0] = 0x40414243;
+       for(i=1; i<16; ++i){
+               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
+       }
+       ctx->counter=0;
+       ctx_dump(ctx);
+}
+
+void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block){
+       bmw_small_nextBlock(ctx, block);
+}
+
+void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b){
+       bmw_small_lastBlock(ctx, block, length_b);
+}
+
+void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[9]), 224/8);
+}
+
+void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
+       memcpy(dest, &(ctx->h[8]), 256/8);
+}
+
+void bmw224(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw224_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw224_ctx2hash(dest, &ctx);
+}
+
+void bmw256(void* dest, const void* msg, uint32_t length_b){
+       bmw_small_ctx_t ctx;
+       bmw256_init(&ctx);
+       while(length_b>=BMW_SMALL_BLOCKSIZE){
+               bmw_small_nextBlock(&ctx, msg);
+               length_b -= BMW_SMALL_BLOCKSIZE;
+               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
+       }
+       bmw_small_lastBlock(&ctx, msg, length_b);
+       bmw256_ctx2hash(dest, &ctx);
+}
+
diff --git a/bmw/bmw_small.h b/bmw/bmw_small.h
new file mode 100644 (file)
index 0000000..f314712
--- /dev/null
@@ -0,0 +1,65 @@
+/* bmw_small.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file    bmw_small.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2009-04-27
+ * \license GPLv3 or later
+ * 
+ */
+#ifndef BMW_SMALL_H_
+#define BMW_SMALL_H_
+
+#include <stdint.h>
+
+#define BMW_SMALL_BLOCKSIZE   512
+#define BMW_SMALL_BLOCKSIZE_B ((BMW_SMALL_BLOCKSIZE+7)/8)
+#define BMW224_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
+#define BMW224_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
+#define BMW256_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
+#define BMW256_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
+
+typedef struct {
+       uint32_t h[16];
+       uint32_t counter;
+} bmw_small_ctx_t;
+
+typedef bmw_small_ctx_t bmw224_ctx_t;
+typedef bmw_small_ctx_t bmw256_ctx_t;
+
+void bmw224_init(bmw224_ctx_t* ctx);
+void bmw256_init(bmw256_ctx_t* ctx);
+
+void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block);
+void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block);
+void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block);
+void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx);
+void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx);
+
+void bmw224(void* dest, const void* msg, uint32_t length_b);
+void bmw256(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BMW_SMALL_H_ */
diff --git a/bmw_large.c b/bmw_large.c
deleted file mode 100644 (file)
index 10e65f6..0000000
+++ /dev/null
@@ -1,468 +0,0 @@
-/* bmw_large.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file    bmw_large.c
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \date    2009-04-27
- * \license GPLv3 or later
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "bmw_large.h"
-
-#define SHL64(a,n) ((a)<<(n))
-#define SHR64(a,n) ((a)>>(n))
-#define ROTL64(a,n) (((a)<<(n))|((a)>>(64-(n))))
-#define ROTR64(a,n) (((a)>>(n))|((a)<<(64-(n))))
-
-#define BUG24 0
-#define F0_HACK 1
-#define DEBUG 0
-#if DEBUG
- #include "cli.h"
- void ctx_dump(const bmw_large_ctx_t* ctx){
-       uint8_t i;
-       cli_putstr_P(PSTR("\r\n==== ctx dump ===="));
-       for(i=0; i<16;++i){
-               cli_putstr_P(PSTR("\r\n h["));
-               cli_hexdump(&i, 1);
-               cli_putstr_P(PSTR("] = "));
-               cli_hexdump_rev(&(ctx->h[i]), 8);
-       }
-       cli_putstr_P(PSTR("\r\n counter = "));
-       cli_hexdump(&(ctx->counter), 4);
- }
- void dump_x(const uint64_t* q, uint8_t elements, char x){
-       uint8_t i;
-       cli_putstr_P(PSTR("\r\n==== "));
-       cli_putc(x);
-       cli_putstr_P(PSTR(" dump ===="));
-       for(i=0; i<elements;++i){
-               cli_putstr_P(PSTR("\r\n "));
-               cli_putc(x);
-               cli_putstr_P(PSTR("["));
-               cli_hexdump(&i, 1);
-               cli_putstr_P(PSTR("] = "));
-               cli_hexdump_rev(&(q[i]), 8);
-       }
- }
-#else
- #define ctx_dump(x)
- #define dump_x(a,b,c)
-#endif
-
-uint64_t bmw_large_s0(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 1)
-               ^ SHL64(x, 3)
-               ^ ROTL64(x, 4)
-               ^ ROTR64(x, 64-37);
-       return r;       
-}
-
-uint64_t bmw_large_s1(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 1)
-               ^ SHL64(x, 2)
-               ^ ROTL64(x,13)
-               ^ ROTR64(x,64-43);
-       return r;       
-}
-
-uint64_t bmw_large_s2(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 2)
-               ^ SHL64(x, 1)
-               ^ ROTL64(x, 19)
-               ^ ROTR64(x, 64-53);
-       return r;       
-}
-
-uint64_t bmw_large_s3(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 2)
-               ^ SHL64(x, 2)
-               ^ ROTL64(x, 28)
-               ^ ROTR64(x, 64-59);
-       return r;       
-}
-
-uint64_t bmw_large_s4(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 1)
-               ^ x;
-       return r;       
-}
-
-uint64_t bmw_large_s5(uint64_t x){
-       uint64_t r;
-       r =   SHR64(x, 2)
-               ^ x;
-       return r;       
-}
-
-uint64_t bmw_large_r1(uint64_t x){
-       uint64_t r;
-       r =   ROTL64(x, 5);
-       return r;       
-}
-
-uint64_t bmw_large_r2(uint64_t x){
-       uint64_t r;
-       r =   ROTL64(x, 11);
-       return r;       
-}
-
-uint64_t bmw_large_r3(uint64_t x){
-       uint64_t r;
-       r =   ROTL64(x, 27);
-       return r;       
-}
-
-uint64_t bmw_large_r4(uint64_t x){
-       uint64_t r;
-       r =   ROTL64(x, 32);
-       return r;       
-}
-
-uint64_t bmw_large_r5(uint64_t x){
-       uint64_t r;
-       r =   ROTR64(x, 64-37);
-       return r;       
-}
-
-uint64_t bmw_large_r6(uint64_t x){
-       uint64_t r;
-       r =   ROTR64(x, 64-43);
-       return r;       
-}
-
-uint64_t bmw_large_r7(uint64_t x){
-       uint64_t r;
-       r =   ROTR64(x, 64-53);
-       return r;       
-}
-/*
-#define K    0x0555555555555555LL
-#define MASK 0xFFFFFFFFFFFFFFFFLL
-static
-uint64_t k_lut[] PROGMEM = {
-       16LL*K, 17LL*K, 18LL*K, 19LL*K, 
-       20LL*K, 21LL*K, 22LL*K, 23LL*K,
-       24LL*K, 25LL*K, 26LL*K, 27LL*K,
-       28LL*K, 29LL*K, 30LL*K, 31LL*K };
-*/     
-/* the same as above but precomputed to avoid compiler warnings */
-static
-uint64_t k_lut[] PROGMEM = {
-       0x5555555555555550LL, 0x5aaaaaaaaaaaaaa5LL, 0x5ffffffffffffffaLL,
-       0x655555555555554fLL, 0x6aaaaaaaaaaaaaa4LL, 0x6ffffffffffffff9LL,
-       0x755555555555554eLL, 0x7aaaaaaaaaaaaaa3LL, 0x7ffffffffffffff8LL,
-       0x855555555555554dLL, 0x8aaaaaaaaaaaaaa2LL, 0x8ffffffffffffff7LL,
-       0x955555555555554cLL, 0x9aaaaaaaaaaaaaa1LL, 0x9ffffffffffffff6LL,
-       0xa55555555555554bLL };
-
-uint64_t bmw_large_expand1(uint8_t j, const uint64_t* q, const void* m){
-       uint64_t(*s[])(uint64_t) = {bmw_large_s1, bmw_large_s2, bmw_large_s3, bmw_large_s0};
-       union{
-               uint64_t v64;
-               uint32_t v32[2];
-       } r;
-       uint8_t i;
-       /* r = 0x0555555555555555LL*(j+16); */
-       r.v32[0] = pgm_read_dword(((uint8_t*)k_lut+8*j));
-       r.v32[1] = pgm_read_dword(((uint8_t*)k_lut+8*j+4));
-       for(i=0; i<16; ++i){
-               r.v64 += s[i%4](q[j+i]);
-       }
-       r.v64 += ((uint64_t*)m)[j];
-       r.v64 += ((uint64_t*)m)[j+3];
-       r.v64 -= ((uint64_t*)m)[j+10];
-       return r.v64;
-}
-
-uint64_t bmw_large_expand2(uint8_t j, const uint64_t* q, const void* m){
-       uint64_t(*rf[])(uint64_t) = {bmw_large_r1, bmw_large_r2, bmw_large_r3,
-                                    bmw_large_r4, bmw_large_r5, bmw_large_r6,
-                                                            bmw_large_r7};
-       union{
-               uint64_t v64;
-               uint32_t v32[2];
-       } r;
-       uint8_t i;
-       /* r = 0x0555555555555555LL*(j+16); */
-       r.v32[0] = pgm_read_dword(((uint8_t*)k_lut+8*j));
-       r.v32[1] = pgm_read_dword(((uint8_t*)k_lut+8*j+4));
-       for(i=0; i<14; i+=2){
-               r.v64 += q[j+i];
-       }
-       for(i=0; i<14; i+=2){
-               r.v64 += rf[i/2](q[j+i+1]);
-       }
-       r.v64 += bmw_large_s5(q[j+14]);
-       r.v64 += bmw_large_s4(q[j+15]);
-       r.v64 += ((uint64_t*)m)[j];
-       r.v64 += ((uint64_t*)m)[(j+3)%16];
-       r.v64 -= ((uint64_t*)m)[(j+10)%16];
-       return r.v64;
-}
-
-#if F0_HACK
-static
-uint8_t f0_lut[] PROGMEM ={
-        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
-        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
-        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
-        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
-        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
-        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
-        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0, 
-        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
-        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
-        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
-        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
-        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
-        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
-        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
-        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
-       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
-};
-
-void bmw_large_f0(uint64_t* q, uint64_t* h, const void* m){
-       uint8_t i,j=-1,v,sign,l=0;
-       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
-                                  bmw_large_s3, bmw_large_s4 };
-       for(i=0; i<16; ++i){
-               h[i] ^= ((uint64_t*)m)[i];
-       }
-       dump_x(h, 16, 'T');
-//     memset(q, 0, 4*16);
-       for(i=0; i<5*16; ++i){
-               v = pgm_read_byte(f0_lut+i);
-               sign = v&1;
-               v >>=1;
-               if(i==l){
-                       j++;
-                       l+=5;
-                       q[j] = h[v];
-                       continue;
-               }
-               if(sign){
-                       q[j] -= h[v];
-               }else{
-                       q[j] += h[v];
-               }
-       }
-       dump_x(q, 16, 'W');
-       for(i=0; i<16; ++i){
-               q[i] = s[i%5](q[i]);
-       }       
-}
-
-#else
-void bmw_large_f0(uint64_t* q, uint64_t* h, const void* m){
-       uint8_t i;
-       uint64_t(*s[])(uint64_t)={ bmw_large_s0, bmw_large_s1, bmw_large_s2,
-                                  bmw_large_s3, bmw_large_s4 };
-       for(i=0; i<16; ++i){
-               h[i] ^= ((uint64_t*)m)[i];
-       }
-       dump_x(t, 16, 'T');
-       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
-       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
-       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
-       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
-       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
-       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
-       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]); 
-       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
-       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
-       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
-       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
-       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
-       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
-       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
-       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
-       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]); 
-       dump_x(q, 16, 'W');
-       for(i=0; i<16; ++i){
-               q[i] = s[i%5](q[i]);
-       }       
-}
-#endif
-
-void bmw_large_f1(uint64_t* q, const void* m){
-       uint8_t i;
-       q[16] = bmw_large_expand1(0, q, m);
-       q[17] = bmw_large_expand1(1, q, m);
-       for(i=2; i<16; ++i){
-               q[16+i] = bmw_large_expand2(i, q, m);
-       }
-}
-
-void bmw_large_f2(uint64_t* h, const uint64_t* q, const void* m){
-       uint64_t xl=0, xh;
-       uint8_t i;
-       for(i=16;i<24;++i){
-               xl ^= q[i];
-       }
-       xh = xl;
-       for(i=24;i<32;++i){
-               xh ^= q[i];
-       }
-#if DEBUG      
-       cli_putstr_P(PSTR("\r\n XL = "));
-       cli_hexdump_rev(&xl, 4);
-       cli_putstr_P(PSTR("\r\n XH = "));
-       cli_hexdump_rev(&xh, 4);
-#endif
-       memcpy(h, m, 16*8);
-       h[0] ^= SHL64(xh, 5) ^ SHR64(q[16], 5);
-       h[1] ^= SHR64(xh, 7) ^ SHL64(q[17], 8);
-       h[2] ^= SHR64(xh, 5) ^ SHL64(q[18], 5);
-       h[3] ^= SHR64(xh, 1) ^ SHL64(q[19], 5);
-       h[4] ^= SHR64(xh, 3) ^ q[20];
-       h[5] ^= SHL64(xh, 6) ^ SHR64(q[21], 6);
-       h[6] ^= SHR64(xh, 4) ^ SHL64(q[22], 6);
-       h[7] ^= SHR64(xh,11) ^ SHL64(q[23], 2);
-       for(i=0; i<8; ++i){
-               h[i] += xl ^ q[24+i] ^ q[i];
-       }
-       for(i=0; i<8; ++i){
-               h[8+i] ^= xh ^ q[24+i];
-               h[8+i] += ROTL64(h[(4+i)%8],i+9);
-       }
-       h[ 8] += SHL64(xl, 8) ^ q[23] ^ q[ 8];
-       h[ 9] += SHR64(xl, 6) ^ q[16] ^ q[ 9];
-       h[10] += SHL64(xl, 6) ^ q[17] ^ q[10];
-       h[11] += SHL64(xl, 4) ^ q[18] ^ q[11];
-       h[12] += SHR64(xl, 3) ^ q[19] ^ q[12];
-       h[13] += SHR64(xl, 4) ^ q[20] ^ q[13];
-       h[14] += SHR64(xl, 7) ^ q[21] ^ q[14];
-       h[15] += SHR64(xl, 2) ^ q[22] ^ q[15];
-}
-
-void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block){
-       uint64_t q[32];
-       dump_x(block, 16, 'M');
-       bmw_large_f0(q, ctx->h, block);
-       dump_x(q, 16, 'Q');
-       bmw_large_f1(q, block);
-       dump_x(q, 32, 'Q');
-       bmw_large_f2(ctx->h, q, block);
-       ctx->counter += 1;
-       ctx_dump(ctx);
-}
-
-void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b){
-       uint8_t buffer[128];
-       while(length_b >= BMW_LARGE_BLOCKSIZE){
-               bmw_large_nextBlock(ctx, block);
-               length_b -= BMW_LARGE_BLOCKSIZE;
-               block = (uint8_t*)block + BMW_LARGE_BLOCKSIZE_B;
-       }
-       memset(buffer, 0, 128);
-       memcpy(buffer, block, (length_b+7)/8);
-       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
-       if(length_b+1>128*8-64){
-               bmw_large_nextBlock(ctx, buffer);
-               memset(buffer, 0, 128-8);
-               ctx->counter -= 1;
-       }
-       *((uint64_t*)&(buffer[128-8])) = (uint64_t)(ctx->counter*1024LL)+(uint64_t)length_b;
-       bmw_large_nextBlock(ctx, buffer);
-}
-
-void bmw384_init(bmw384_ctx_t* ctx){
-       uint8_t i;
-       ctx->h[0] = 0x0001020304050607LL;
-       for(i=1; i<16; ++i){
-               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
-       }
-#if BUG24      
-       ctx->h[6] = 0x3031323324353637LL;
-#endif
-       ctx->counter=0;
-       ctx_dump(ctx);
-}
-
-void bmw512_init(bmw512_ctx_t* ctx){
-       uint8_t i;
-       ctx->h[0] = 0x8081828384858687LL;
-       for(i=1; i<16; ++i){
-               ctx->h[i] = ctx->h[i-1]+ 0x0808080808080808LL;
-       }
-       ctx->counter=0;
-       ctx_dump(ctx);
-}
-
-void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block){
-       bmw_large_nextBlock(ctx, block);
-}
-
-void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block){
-       bmw_large_nextBlock(ctx, block);
-}
-
-void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b){
-       bmw_large_lastBlock(ctx, block, length_b);
-}
-
-void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b){
-       bmw_large_lastBlock(ctx, block, length_b);
-}
-
-void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx){
-       memcpy(dest, &(ctx->h[10]), 384/8);
-}
-
-void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx){
-       memcpy(dest, &(ctx->h[8]), 512/8);
-}
-
-void bmw384(void* dest, const void* msg, uint32_t length_b){
-       bmw_large_ctx_t ctx;
-       bmw384_init(&ctx);
-       while(length_b>=BMW_LARGE_BLOCKSIZE){
-               bmw_large_nextBlock(&ctx, msg);
-               length_b -= BMW_LARGE_BLOCKSIZE;
-               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
-       }
-       bmw_large_lastBlock(&ctx, msg, length_b);
-       bmw384_ctx2hash(dest, &ctx);
-}
-
-void bmw512(void* dest, const void* msg, uint32_t length_b){
-       bmw_large_ctx_t ctx;
-       bmw512_init(&ctx);
-       while(length_b>=BMW_LARGE_BLOCKSIZE){
-               bmw_large_nextBlock(&ctx, msg);
-               length_b -= BMW_LARGE_BLOCKSIZE;
-               msg = (uint8_t*)msg + BMW_LARGE_BLOCKSIZE_B;
-       }
-       bmw_large_lastBlock(&ctx, msg, length_b);
-       bmw512_ctx2hash(dest, &ctx);
-}
-
diff --git a/bmw_large.h b/bmw_large.h
deleted file mode 100644 (file)
index fba01fb..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* bmw_large.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file    bmw_large.h
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \date    2009-04-27
- * \license GPLv3 or later
- * 
- */
-#ifndef BMW_LARGE_H_
-#define BMW_LARGE_H_
-
-#include <stdint.h>
-
-#define BMW_LARGE_BLOCKSIZE   1024
-#define BMW_LARGE_BLOCKSIZE_B ((BMW_LARGE_BLOCKSIZE+7)/8)
-#define BMW384_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
-#define BMW384_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
-#define BMW512_BLOCKSIZE      BMW_LARGE_BLOCKSIZE
-#define BMW512_BLOCKSIZE_B    BMW_LARGE_BLOCKSIZE_B
-
-typedef struct {
-       uint64_t h[16];
-       uint32_t counter;
-} bmw_large_ctx_t;
-
-typedef bmw_large_ctx_t bmw384_ctx_t;
-typedef bmw_large_ctx_t bmw512_ctx_t;
-
-void bmw384_init(bmw384_ctx_t* ctx);
-void bmw512_init(bmw512_ctx_t* ctx);
-
-void bmw_large_nextBlock(bmw_large_ctx_t* ctx, const void* block);
-void bmw_large_lastBlock(bmw_large_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw384_nextBlock(bmw384_ctx_t* ctx, const void* block);
-void bmw384_lastBlock(bmw384_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw512_nextBlock(bmw512_ctx_t* ctx, const void* block);
-void bmw512_lastBlock(bmw512_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw384_ctx2hash(void* dest, const bmw384_ctx_t* ctx);
-void bmw512_ctx2hash(void* dest, const bmw512_ctx_t* ctx);
-
-void bmw384(void* dest, const void* msg, uint32_t length_b);
-void bmw512(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* BMW_LARGE_H_ */
diff --git a/bmw_small.c b/bmw_small.c
deleted file mode 100644 (file)
index aefd592..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-/* bmw_small.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file    bmw_small.c
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \date    2009-04-27
- * \license GPLv3 or later
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "bmw_small.h"
-
-
-#define SHL32(a,n) ((a)<<(n))
-#define SHR32(a,n) ((a)>>(n))
-#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
-#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
-
-#define BUG24   0
-#define F0_HACK 1
-
-#define DEBUG 0
-#if DEBUG
- #include "cli.h"
- void ctx_dump(const bmw_small_ctx_t* ctx){
-       uint8_t i;
-       cli_putstr_P(PSTR("\r\n==== ctx dump ===="));
-       for(i=0; i<16;++i){
-               cli_putstr_P(PSTR("\r\n h["));
-               cli_hexdump(&i, 1);
-               cli_putstr_P(PSTR("] = "));
-               cli_hexdump_rev(&(ctx->h[i]), 4);
-       }
-       cli_putstr_P(PSTR("\r\n counter = "));
-       cli_hexdump(&(ctx->counter), 4);
- }
- void dump_x(const uint32_t* q, uint8_t elements, char x){
-       uint8_t i;
-       cli_putstr_P(PSTR("\r\n==== "));
-       cli_putc(x);
-       cli_putstr_P(PSTR(" dump ===="));
-       for(i=0; i<elements;++i){
-               cli_putstr_P(PSTR("\r\n "));
-               cli_putc(x);
-               cli_putstr_P(PSTR("["));
-               cli_hexdump(&i, 1);
-               cli_putstr_P(PSTR("] = "));
-               cli_hexdump_rev(&(q[i]), 4);
-       }
- }
-#else
- #define ctx_dump(x)
- #define dump_x(a,b,c)
-#endif
-
-uint32_t bmw_small_s0(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 1)
-               ^ SHL32(x, 3)
-               ^ ROTL32(x, 4)
-               ^ ROTR32(x, 13);
-       return r;       
-}
-
-uint32_t bmw_small_s1(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 1)
-               ^ SHL32(x, 2)
-               ^ ROTL32(x, 8)
-               ^ ROTR32(x, 9);
-       return r;       
-}
-
-uint32_t bmw_small_s2(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 2)
-               ^ SHL32(x, 1)
-               ^ ROTL32(x, 12)
-               ^ ROTR32(x, 7);
-       return r;       
-}
-
-uint32_t bmw_small_s3(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 2)
-               ^ SHL32(x, 2)
-               ^ ROTL32(x, 15)
-               ^ ROTR32(x, 3);
-       return r;       
-}
-
-uint32_t bmw_small_s4(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 1)
-               ^ x;
-       return r;       
-}
-
-uint32_t bmw_small_s5(uint32_t x){
-       uint32_t r;
-       r =   SHR32(x, 2)
-               ^ x;
-       return r;       
-}
-
-uint32_t bmw_small_r1(uint32_t x){
-       uint32_t r;
-       r =   ROTL32(x, 3);
-       return r;       
-}
-
-uint32_t bmw_small_r2(uint32_t x){
-       uint32_t r;
-       r =   ROTL32(x, 7);
-       return r;       
-}
-
-uint32_t bmw_small_r3(uint32_t x){
-       uint32_t r;
-       r =   ROTL32(x, 13);
-       return r;       
-}
-
-uint32_t bmw_small_r4(uint32_t x){
-       uint32_t r;
-       r =   ROTL32(x, 16);
-       return r;       
-}
-
-uint32_t bmw_small_r5(uint32_t x){
-       uint32_t r;
-       r =   ROTR32(x, 13);
-       return r;       
-}
-
-uint32_t bmw_small_r6(uint32_t x){
-       uint32_t r;
-       r =   ROTR32(x, 9);
-       return r;       
-}
-
-uint32_t bmw_small_r7(uint32_t x){
-       uint32_t r;
-       r =   ROTR32(x, 5);
-       return r;       
-}
-/*
-#define K 0x05555555L
-static
-uint32_t k_lut[] PROGMEM = {
-       16L*K, 17L*K, 18L*K, 19L*K, 20L*K, 21L*K, 22L*K, 23L*K,
-       24L*K, 25L*K, 26L*K, 27L*K, 28L*K, 29L*K, 30L*K, 31L*K
-};
-*/
-/* same as above but precomputed to avoid compiler warnings */
-
-static
-uint32_t k_lut[] PROGMEM = {
-       0x55555550L, 0x5aaaaaa5L, 0x5ffffffaL, 
-       0x6555554fL, 0x6aaaaaa4L, 0x6ffffff9L, 
-       0x7555554eL, 0x7aaaaaa3L, 0x7ffffff8L, 
-       0x8555554dL, 0x8aaaaaa2L, 0x8ffffff7L,
-       0x9555554cL, 0x9aaaaaa1L, 0x9ffffff6L, 
-       0xa555554bL };
-
-
-uint32_t bmw_small_expand1(uint8_t j, const uint32_t* q, const void* m){
-       uint32_t(*s[])(uint32_t) = {bmw_small_s1, bmw_small_s2, bmw_small_s3, bmw_small_s0};
-       uint32_t r;
-       uint8_t i;
-       /* r = 0x05555555*(j+16); */
-       r = pgm_read_dword(k_lut+j);
-       for(i=0; i<16; ++i){
-               r += s[i%4](q[j+i]);
-       }
-       r += ((uint32_t*)m)[j];
-       r += ((uint32_t*)m)[j+3];
-       r -= ((uint32_t*)m)[j+10];
-       return r;
-}
-
-uint32_t bmw_small_expand2(uint8_t j, const uint32_t* q, const void* m){
-       uint32_t(*rf[])(uint32_t) = {bmw_small_r1, bmw_small_r2, bmw_small_r3,
-                                    bmw_small_r4, bmw_small_r5, bmw_small_r6,
-                                                            bmw_small_r7};
-       uint32_t r;
-       uint8_t i;
-       /* r = 0x05555555*(j+16); */
-       r = pgm_read_dword(k_lut+j);
-       for(i=0; i<14; i+=2){
-               r += q[j+i];
-       }
-       for(i=0; i<14; i+=2){
-               r += rf[i/2](q[j+i+1]);
-       }
-       r += bmw_small_s5(q[j+14]);
-       r += bmw_small_s4(q[j+15]);
-       r += ((uint32_t*)m)[j];
-       r += ((uint32_t*)m)[(j+3)%16];
-       r -= ((uint32_t*)m)[(j+10)%16];
-       return r;
-}
-#if F0_HACK
-static
-uint8_t f0_lut[] PROGMEM = {
-        5<<1, ( 7<<1)+1, (10<<1)+0, (13<<1)+0, (14<<1)+0,
-        6<<1, ( 8<<1)+1, (11<<1)+0, (14<<1)+0, (15<<1)+1,
-        0<<1, ( 7<<1)+0, ( 9<<1)+0, (12<<1)+1, (15<<1)+0,
-        0<<1, ( 1<<1)+1, ( 8<<1)+0, (10<<1)+1, (13<<1)+0,
-        1<<1, ( 2<<1)+0, ( 9<<1)+0, (11<<1)+1, (14<<1)+1,
-        3<<1, ( 2<<1)+1, (10<<1)+0, (12<<1)+1, (15<<1)+0,
-        4<<1, ( 0<<1)+1, ( 3<<1)+1, (11<<1)+1, (13<<1)+0, 
-        1<<1, ( 4<<1)+1, ( 5<<1)+1, (12<<1)+1, (14<<1)+1,
-        2<<1, ( 5<<1)+1, ( 6<<1)+1, (13<<1)+0, (15<<1)+1,
-        0<<1, ( 3<<1)+1, ( 6<<1)+0, ( 7<<1)+1, (14<<1)+0,
-        8<<1, ( 1<<1)+1, ( 4<<1)+1, ( 7<<1)+1, (15<<1)+0,
-        8<<1, ( 0<<1)+1, ( 2<<1)+1, ( 5<<1)+1, ( 9<<1)+0,
-        1<<1, ( 3<<1)+0, ( 6<<1)+1, ( 9<<1)+1, (10<<1)+0,
-        2<<1, ( 4<<1)+0, ( 7<<1)+0, (10<<1)+0, (11<<1)+0,
-        3<<1, ( 5<<1)+1, ( 8<<1)+0, (11<<1)+1, (12<<1)+1,
-       12<<1, ( 4<<1)+1, ( 6<<1)+1, ( 9<<1)+1, (13<<1)+0
-};
-
-void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
-       uint8_t i,j=-1,v,sign,l=0;
-       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
-                                  bmw_small_s3, bmw_small_s4 };
-       for(i=0; i<16; ++i){
-               h[i] ^= ((uint32_t*)m)[i];
-       }
-       dump_x(h, 16, 'T');
-       // memset(q, 0, 4*16);
-       for(i=0; i<5*16; ++i){
-               v = pgm_read_byte(f0_lut+i);
-               sign = v&1;
-               v >>=1;
-               if(i==l){
-                       j++;
-                       l+=5;
-                       q[j] = h[v];
-                       continue;
-               }
-               if(sign){
-                       q[j] -= h[v];
-               }else{
-                       q[j] += h[v];
-               }
-       }
-       dump_x(q, 16, 'W');
-       for(i=0; i<16; ++i){
-               q[i] = s[i%5](q[i]);
-       }       
-}
-
-#else
-void bmw_small_f0(uint32_t* q, uint32_t* h, const void* m){
-       uint8_t i;
-       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
-                                  bmw_small_s3, bmw_small_s4 };
-       for(i=0; i<16; ++i){
-               h[i] ^= ((uint32_t*)m)[i];
-       }
-       dump_x(h, 16, 'T');
-       q[ 0] = (h[ 5] - h[ 7] + h[10] + h[13] + h[14]);
-       q[ 1] = (h[ 6] - h[ 8] + h[11] + h[14] - h[15]);
-       q[ 2] = (h[ 0] + h[ 7] + h[ 9] - h[12] + h[15]);
-       q[ 3] = (h[ 0] - h[ 1] + h[ 8] - h[10] + h[13]);
-       q[ 4] = (h[ 1] + h[ 2] + h[ 9] - h[11] - h[14]);
-       q[ 5] = (h[ 3] - h[ 2] + h[10] - h[12] + h[15]);
-       q[ 6] = (h[ 4] - h[ 0] - h[ 3] - h[11] + h[13]); 
-       q[ 7] = (h[ 1] - h[ 4] - h[ 5] - h[12] - h[14]);
-       q[ 8] = (h[ 2] - h[ 5] - h[ 6] + h[13] - h[15]);
-       q[ 9] = (h[ 0] - h[ 3] + h[ 6] - h[ 7] + h[14]);
-       q[10] = (h[ 8] - h[ 1] - h[ 4] - h[ 7] + h[15]);
-       q[11] = (h[ 8] - h[ 0] - h[ 2] - h[ 5] + h[ 9]);
-       q[12] = (h[ 1] + h[ 3] - h[ 6] - h[ 9] + h[10]);
-       q[13] = (h[ 2] + h[ 4] + h[ 7] + h[10] + h[11]);
-       q[14] = (h[ 3] - h[ 5] + h[ 8] - h[11] - h[12]);
-       q[15] = (h[12] - h[ 4] - h[ 6] - h[ 9] + h[13]); 
-       dump_x(q, 16, 'W');
-       for(i=0; i<16; ++i){
-               q[i] = s[i%5](q[i]);
-       }       
-}
-#endif
-
-void bmw_small_f1(uint32_t* q, const void* m){
-       uint8_t i;
-       q[16] = bmw_small_expand1(0, q, m);
-       q[17] = bmw_small_expand1(1, q, m);
-       for(i=2; i<16; ++i){
-               q[16+i] = bmw_small_expand2(i, q, m);
-       }
-}
-
-void bmw_small_f2(uint32_t* h, const uint32_t* q, const void* m){
-       uint32_t xl=0, xh;
-       uint8_t i;
-       for(i=16;i<24;++i){
-               xl ^= q[i];
-       }
-       xh = xl;
-       for(i=24;i<32;++i){
-               xh ^= q[i];
-       }
-#if DEBUG      
-       cli_putstr_P(PSTR("\r\n XL = "));
-       cli_hexdump_rev(&xl, 4);
-       cli_putstr_P(PSTR("\r\n XH = "));
-       cli_hexdump_rev(&xh, 4);
-#endif
-       memcpy(h, m, 16*4);
-       h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5);
-       h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8);
-       h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5);
-       h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5);
-       h[4] ^= SHR32(xh, 3) ^ q[20];
-       h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6);
-       h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6);
-       h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2);
-       for(i=0; i<8; ++i){
-               h[i] += xl ^ q[24+i] ^ q[i];
-       }
-       for(i=0; i<8; ++i){
-               h[8+i] ^= xh ^ q[24+i];
-               h[8+i] += ROTL32(h[(4+i)%8],i+9);
-       }
-       h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8];
-       h[ 9] += SHR32(xl, 6) ^ q[16] ^ q[ 9];
-       h[10] += SHL32(xl, 6) ^ q[17] ^ q[10];
-       h[11] += SHL32(xl, 4) ^ q[18] ^ q[11];
-       h[12] += SHR32(xl, 3) ^ q[19] ^ q[12];
-       h[13] += SHR32(xl, 4) ^ q[20] ^ q[13];
-       h[14] += SHR32(xl, 7) ^ q[21] ^ q[14];
-       h[15] += SHR32(xl, 2) ^ q[22] ^ q[15];
-}
-
-void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){
-       uint32_t q[32];
-       dump_x(block, 16, 'M');
-       bmw_small_f0(q, ctx->h, block);
-       dump_x(q, 16, 'Q');
-       bmw_small_f1(q, block);
-       dump_x(q, 32, 'Q');
-       bmw_small_f2(ctx->h, q, block);
-       ctx->counter += 1;
-       ctx_dump(ctx);
-}
-
-void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b){
-       uint8_t buffer[64];
-       while(length_b >= BMW_SMALL_BLOCKSIZE){
-               bmw_small_nextBlock(ctx, block);
-               length_b -= BMW_SMALL_BLOCKSIZE;
-               block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
-       }
-       memset(buffer, 0, 64);
-       memcpy(buffer, block, (length_b+7)/8);
-       buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
-       if(length_b+1>64*8-64){
-               bmw_small_nextBlock(ctx, buffer);
-               memset(buffer, 0, 64-8);
-               ctx->counter -= 1;
-       }
-       *((uint64_t*)&(buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
-       bmw_small_nextBlock(ctx, buffer);
-}
-
-void bmw224_init(bmw224_ctx_t* ctx){
-       uint8_t i;
-       ctx->h[0] = 0x00010203;
-       for(i=1; i<16; ++i){
-               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
-       }
-#if BUG24      
-       ctx->h[13] = 0x24353637;
-#endif
-       ctx->counter=0;
-       ctx_dump(ctx);
-}
-
-void bmw256_init(bmw256_ctx_t* ctx){
-       uint8_t i;
-       ctx->h[0] = 0x40414243;
-       for(i=1; i<16; ++i){
-               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
-       }
-       ctx->counter=0;
-       ctx_dump(ctx);
-}
-
-void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block){
-       bmw_small_nextBlock(ctx, block);
-}
-
-void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block){
-       bmw_small_nextBlock(ctx, block);
-}
-
-void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b){
-       bmw_small_lastBlock(ctx, block, length_b);
-}
-
-void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b){
-       bmw_small_lastBlock(ctx, block, length_b);
-}
-
-void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
-       memcpy(dest, &(ctx->h[9]), 224/8);
-}
-
-void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
-       memcpy(dest, &(ctx->h[8]), 256/8);
-}
-
-void bmw224(void* dest, const void* msg, uint32_t length_b){
-       bmw_small_ctx_t ctx;
-       bmw224_init(&ctx);
-       while(length_b>=BMW_SMALL_BLOCKSIZE){
-               bmw_small_nextBlock(&ctx, msg);
-               length_b -= BMW_SMALL_BLOCKSIZE;
-               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
-       }
-       bmw_small_lastBlock(&ctx, msg, length_b);
-       bmw224_ctx2hash(dest, &ctx);
-}
-
-void bmw256(void* dest, const void* msg, uint32_t length_b){
-       bmw_small_ctx_t ctx;
-       bmw256_init(&ctx);
-       while(length_b>=BMW_SMALL_BLOCKSIZE){
-               bmw_small_nextBlock(&ctx, msg);
-               length_b -= BMW_SMALL_BLOCKSIZE;
-               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
-       }
-       bmw_small_lastBlock(&ctx, msg, length_b);
-       bmw256_ctx2hash(dest, &ctx);
-}
-
diff --git a/bmw_small.h b/bmw_small.h
deleted file mode 100644 (file)
index f314712..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* bmw_small.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file    bmw_small.h
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \date    2009-04-27
- * \license GPLv3 or later
- * 
- */
-#ifndef BMW_SMALL_H_
-#define BMW_SMALL_H_
-
-#include <stdint.h>
-
-#define BMW_SMALL_BLOCKSIZE   512
-#define BMW_SMALL_BLOCKSIZE_B ((BMW_SMALL_BLOCKSIZE+7)/8)
-#define BMW224_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
-#define BMW224_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
-#define BMW256_BLOCKSIZE      BMW_SMALL_BLOCKSIZE
-#define BMW256_BLOCKSIZE_B    BMW_SMALL_BLOCKSIZE_B
-
-typedef struct {
-       uint32_t h[16];
-       uint32_t counter;
-} bmw_small_ctx_t;
-
-typedef bmw_small_ctx_t bmw224_ctx_t;
-typedef bmw_small_ctx_t bmw256_ctx_t;
-
-void bmw224_init(bmw224_ctx_t* ctx);
-void bmw256_init(bmw256_ctx_t* ctx);
-
-void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block);
-void bmw_small_lastBlock(bmw_small_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw224_nextBlock(bmw224_ctx_t* ctx, const void* block);
-void bmw224_lastBlock(bmw224_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw256_nextBlock(bmw256_ctx_t* ctx, const void* block);
-void bmw256_lastBlock(bmw256_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx);
-void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx);
-
-void bmw224(void* dest, const void* msg, uint32_t length_b);
-void bmw256(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* BMW_SMALL_H_ */
diff --git a/cast5-sbox.h b/cast5-sbox.h
deleted file mode 100644 (file)
index 4a8b6bf..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/* cast5-sbox.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * 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
deleted file mode 100644 (file)
index 6d7f42f..0000000
--- a/cast5.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/* cast5.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * \file       cast5.c
- * \author     Daniel Otte
- * \email       daniel.otte@rub.de
- * \date       2006-07-26
- * \par License:
- *  GPLv3 or later
- * \brief Implementation of the CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144
- * 
- */
- #include <stdint.h>
- #include <string.h>
- #include "cast5.h"
- #include "config.h"
- #include "debug.h"
- #undef DEBUG
- #ifdef DEBUG
-  #include "cli.h"
- #endif
-#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)])
-
-static 
-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]);
-}
-
-static
-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)]))
-
-static
-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
-               cli_putstr("\r\n\t h="); cli_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(const void* key, uint16_t keylength_b, cast5_ctx_t* s){
-        /* we migth return if the key is valid and if setup was successful */
-       uint32_t x[4], z[4];
-       #define BPX ((uint8_t*)&(x[0]))
-       #define BPZ ((uint8_t*)&(z[0]))
-       s->shortkey = (keylength_b<=80);
-       /* littel endian only! */
-       memset(&(x[0]), 0 ,16); /* set x to zero */
-       if(keylength_b > 128)
-               keylength_b=128;
-       memcpy(&(x[0]), key, (keylength_b+7)/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
-
-static
-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;
-       cli_putstr("\r\n f1("); cli_hexdump(&d, 4); cli_putc(',');
-               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
-               cli_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]] );
-       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
-       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
-       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
-       cli_putstr("\r\n\tID="); cli_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
-}
-
-static
-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;
-       cli_putstr("\r\n f2("); cli_hexdump(&d, 4); cli_putc(',');
-               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
-               cli_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]] );
-       
-       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
-       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
-       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
-       cli_putstr("\r\n\tID="); cli_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
-}
-
-static
-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;
-
-       cli_putstr("\r\n f3("); cli_hexdump(&d, 4); cli_putc(',');
-               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
-               cli_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]] );
-       
-       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
-       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
-       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
-       cli_putstr("\r\n\tID="); cli_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(void* block, const cast5_ctx_t *s){
-       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];
-//     cli_putstr("\r\n round[-1] = ");
-//     cli_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);
-//             cli_putstr("\r\n round["); DEBUG_B(i); cli_putstr("] = ");
-//             cli_hexdump(&r, 4);
-               l = x;
-       }
-       ((uint32_t*)block)[0]=r;
-       ((uint32_t*)block)[1]=l;
-}
-
-/******************************************************************************/
-
-void cast5_dec(void* block, const cast5_ctx_t *s){
-       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;
-}
-
-
-/******************************************************************************/
-
-
-
-
diff --git a/cast5.h b/cast5.h
deleted file mode 100644 (file)
index b014f7c..0000000
--- a/cast5.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* cast5.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** 
- * \file       cast5.h
- * \author     Daniel Otte
- * \date       2006-07-26
- * \license GPLv3 or later
- * \brief 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 cast5_ctx_t
- * \brief CAST-5 context
- * 
- * A variable of this type may hold a keyschedule for the CAST-5 cipher. 
- * This context is regulary generated by the 
- * cast5_init(uint8_t* key, uint8_t keylength_b, cast5_ctx_t* s) function.
- */
-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;
-
-
-/** \fn void cast5_init(const void* key, uint16_t keylength_b, cast5_ctx_t* s);
- * \brief generate keyschedule/contex for CAST-5
- * 
- * This function generates the keyschedule from the supplied key for the 
- * CAST-5 cipher and stores it in a supplied ::cast5_ctx_t context.
- * \param key pointer to the key
- * \param keylength_b length of the key in bits (maximum 128 bits)
- * \param s pointer to the context
- */
-void cast5_init(const void* key, uint16_t keylength_b, cast5_ctx_t* s);
-
-/** \fn void cast5_enc(void* block, const cast5_ctx_t* s);
- * \brief encrypt a block with the CAST-5 algorithm
- * 
- * This function encrypts a block of 64 bits (8 bytes) with the CAST-5 algorithm.
- * It uses a keyschedule as generated by the 
- * cast5_init(void* key, uint8_t keylength_b, cast5_ctx_t* s) function.
- * \param block pointer to the block which gets encrypted
- * \param s pointer to the keyschedule/context
- */
-void cast5_enc(void* block, const cast5_ctx_t* s);
-
-/** \fn void cast5_dec(void* block, const cast5_ctx_t* s);
- * \brief decrypt a block with the CAST-5 algorithm
- * 
- * This function decrypts a block of 64 bits (8 bytes) with the CAST-5 algorithm.
- * It uses a keyschedule as generated by the 
- * cast5_init(void* key, uint8_t keylength_b, cast5_ctx_t* s) function.
- * \param block pointer to the block which gets decrypted
- * \param s pointer to the keyschedule/context
- */
-void cast5_dec(void* block, const cast5_ctx_t* s);
-
-
-
-#endif
-
diff --git a/cast5/cast5-sbox.h b/cast5/cast5-sbox.h
new file mode 100644 (file)
index 0000000..4a8b6bf
--- /dev/null
@@ -0,0 +1,601 @@
+/* cast5-sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * 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/cast5.c b/cast5/cast5.c
new file mode 100644 (file)
index 0000000..6d7f42f
--- /dev/null
@@ -0,0 +1,343 @@
+/* cast5.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * \file       cast5.c
+ * \author     Daniel Otte
+ * \email       daniel.otte@rub.de
+ * \date       2006-07-26
+ * \par License:
+ *  GPLv3 or later
+ * \brief Implementation of the CAST5 (aka CAST-128) cipher algorithm as described in RFC 2144
+ * 
+ */
+ #include <stdint.h>
+ #include <string.h>
+ #include "cast5.h"
+ #include "config.h"
+ #include "debug.h"
+ #undef DEBUG
+ #ifdef DEBUG
+  #include "cli.h"
+ #endif
+#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)])
+
+static 
+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]);
+}
+
+static
+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)]))
+
+static
+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
+               cli_putstr("\r\n\t h="); cli_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(const void* key, uint16_t keylength_b, cast5_ctx_t* s){
+        /* we migth return if the key is valid and if setup was successful */
+       uint32_t x[4], z[4];
+       #define BPX ((uint8_t*)&(x[0]))
+       #define BPZ ((uint8_t*)&(z[0]))
+       s->shortkey = (keylength_b<=80);
+       /* littel endian only! */
+       memset(&(x[0]), 0 ,16); /* set x to zero */
+       if(keylength_b > 128)
+               keylength_b=128;
+       memcpy(&(x[0]), key, (keylength_b+7)/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
+
+static
+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;
+       cli_putstr("\r\n f1("); cli_hexdump(&d, 4); cli_putc(',');
+               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
+               cli_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]] );
+       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
+       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
+       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
+       cli_putstr("\r\n\tID="); cli_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
+}
+
+static
+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;
+       cli_putstr("\r\n f2("); cli_hexdump(&d, 4); cli_putc(',');
+               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
+               cli_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]] );
+       
+       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
+       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
+       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
+       cli_putstr("\r\n\tID="); cli_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
+}
+
+static
+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;
+
+       cli_putstr("\r\n f3("); cli_hexdump(&d, 4); cli_putc(',');
+               cli_hexdump(&m , 4); cli_putc(','); cli_hexdump(&r, 1);cli_putstr("): I=");
+               cli_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]] );
+       
+       cli_putstr("\r\n\tIA="); cli_hexdump(&ia, 4);
+       cli_putstr("\r\n\tIB="); cli_hexdump(&ib, 4);
+       cli_putstr("\r\n\tIC="); cli_hexdump(&ic, 4);
+       cli_putstr("\r\n\tID="); cli_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(void* block, const cast5_ctx_t *s){
+       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];
+//     cli_putstr("\r\n round[-1] = ");
+//     cli_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);
+//             cli_putstr("\r\n round["); DEBUG_B(i); cli_putstr("] = ");
+//             cli_hexdump(&r, 4);
+               l = x;
+       }
+       ((uint32_t*)block)[0]=r;
+       ((uint32_t*)block)[1]=l;
+}
+
+/******************************************************************************/
+
+void cast5_dec(void* block, const cast5_ctx_t *s){
+       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;
+}
+
+
+/******************************************************************************/
+
+
+
+
diff --git a/cast5/cast5.h b/cast5/cast5.h
new file mode 100644 (file)
index 0000000..b014f7c
--- /dev/null
@@ -0,0 +1,95 @@
+/* cast5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** 
+ * \file       cast5.h
+ * \author     Daniel Otte
+ * \date       2006-07-26
+ * \license GPLv3 or later
+ * \brief 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 cast5_ctx_t
+ * \brief CAST-5 context
+ * 
+ * A variable of this type may hold a keyschedule for the CAST-5 cipher. 
+ * This context is regulary generated by the 
+ * cast5_init(uint8_t* key, uint8_t keylength_b, cast5_ctx_t* s) function.
+ */
+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;
+
+
+/** \fn void cast5_init(const void* key, uint16_t keylength_b, cast5_ctx_t* s);
+ * \brief generate keyschedule/contex for CAST-5
+ * 
+ * This function generates the keyschedule from the supplied key for the 
+ * CAST-5 cipher and stores it in a supplied ::cast5_ctx_t context.
+ * \param key pointer to the key
+ * \param keylength_b length of the key in bits (maximum 128 bits)
+ * \param s pointer to the context
+ */
+void cast5_init(const void* key, uint16_t keylength_b, cast5_ctx_t* s);
+
+/** \fn void cast5_enc(void* block, const cast5_ctx_t* s);
+ * \brief encrypt a block with the CAST-5 algorithm
+ * 
+ * This function encrypts a block of 64 bits (8 bytes) with the CAST-5 algorithm.
+ * It uses a keyschedule as generated by the 
+ * cast5_init(void* key, uint8_t keylength_b, cast5_ctx_t* s) function.
+ * \param block pointer to the block which gets encrypted
+ * \param s pointer to the keyschedule/context
+ */
+void cast5_enc(void* block, const cast5_ctx_t* s);
+
+/** \fn void cast5_dec(void* block, const cast5_ctx_t* s);
+ * \brief decrypt a block with the CAST-5 algorithm
+ * 
+ * This function decrypts a block of 64 bits (8 bytes) with the CAST-5 algorithm.
+ * It uses a keyschedule as generated by the 
+ * cast5_init(void* key, uint8_t keylength_b, cast5_ctx_t* s) function.
+ * \param block pointer to the block which gets decrypted
+ * \param s pointer to the keyschedule/context
+ */
+void cast5_dec(void* block, const cast5_ctx_t* s);
+
+
+
+#endif
+
diff --git a/cast6.c b/cast6.c
deleted file mode 100644 (file)
index c4922fc..0000000
--- a/cast6.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* 
- * File:       cast6.c
- * Author:     Daniel Otte
- * Date:       09.09.2006
- * License: GPL
- * Description: Implementation of the CAST6 (aka CAST-256) cipher algorithm as described in RFC 2612
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "cast6.h"
-#include "cast6_sboxes.h"
-
-#define CHANGE_ENDIAN32(x) (((x)<<24 | (x)>>24 | ((x)&0xff00)<<8 | ((x)&0xff0000)>>8)&0xffffffff)
-
-
-static
-uint8_t kr(uint8_t i, const cast6_ctx_t* ctx){
-       uint8_t ret;
-       ret = ctx->krx[i/2];
-       if(i&1){
-               ret >>= 4;
-       }else{
-               ret &= 0x0f;
-       }
-       /* now get the high bit */
-       ret |= ((ctx->krx[24+i/8])&(1<<(i%8)))?0x10:0x00;
-       return ret;
-}
-
-static
-void set_kr(uint8_t value, uint8_t i, cast6_ctx_t* ctx){
-       value &= 0x1F;
-       
-       (ctx->krx[i/2]) &= 0xF0>>((i&1)*4); /* clear the location where v should go */
-       (ctx->krx[i/2]) |= (value&0x0f)<<((i&1)*4); 
-       
-       /* now set the high bit */
-       (ctx->krx[24+i/8]) &= ~(1<<(i%8)); /* clear the location where v should go */
-       (ctx->krx[24+i/8]) |= (value>>4)<<(i%8); 
-}
-
-#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
-#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
-
-#define S1(a) (pgm_read_dword(&(s1[(a)])))
-#define S2(a) (pgm_read_dword(&(s2[(a)])))
-#define S3(a) (pgm_read_dword(&(s3[(a)])))
-#define S4(a) (pgm_read_dword(&(s4[(a)])))
-
-#define A ((uint8_t)(v>>(8*3)))
-#define B ((uint8_t)(v>>(8*2)))
-#define C ((uint8_t)(v>>(8*1)))
-#define D ((uint8_t)(v>>(8*0)))
-
-
-static
-uint32_t f1(uint32_t v, uint8_t kri, uint32_t kmi){
-       uint32_t o;
-       kri &= 0x1F;
-       v  = ROTL32(kmi+v, kri);
-       o  = S1(A);
-       o ^= S2(B);
-       o -= S3(C);
-       o += S4(D);
-       return o;
-}
-
-static
-uint32_t f2(uint32_t v, uint8_t kri, uint32_t kmi){
-       uint32_t o;
-       kri &= 0x1F;
-       v  = ROTL32(kmi^v, kri);
-       o  = S1(A);
-       o -= S2(B);
-       o += S3(C);
-       o ^= S4(D);
-       return o;
-}
-
-static
-uint32_t f3(uint32_t v, uint8_t kri, uint32_t kmi){
-       uint32_t o;
-       kri &= 0x1F;
-       v  = ROTL32(kmi-v, kri);
-       o  = S1(A);
-       o += S2(B);
-       o ^= S3(C);
-       o -= S4(D);
-       return o;
-}
-
-#undef A
-#undef B
-#undef C
-#undef D
-
-#define A (((uint32_t*)buffer)[0])
-#define B (((uint32_t*)buffer)[1])
-#define C (((uint32_t*)buffer)[2])
-#define D (((uint32_t*)buffer)[3])
-
-static
-void q(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
-       C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
-       B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
-       A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
-       D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
-}
-
-static
-void qbar(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
-       D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
-       A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
-       B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
-       C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
-}
-
-void cast6_enc(void* buffer, const cast6_ctx_t* ctx){
-       uint8_t i;
-       for(i=0; i<32/4; ++i){
-               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
-       }
-       for(i=0; i<6; ++i){
-               q(buffer, i, ctx);
-       }
-       for(i=6; i<12; ++i){
-               qbar(buffer, i, ctx);
-       }
-       for(i=0; i<32/4; ++i){
-               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
-       }
-}
-
-void cast6_dec(void* buffer, const cast6_ctx_t* ctx){
-       uint8_t i;
-       for(i=0; i<32/4; ++i){
-               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
-       }
-       for(i=12; i>6; --i){
-               q(buffer, i-1, ctx);
-       }
-       for(i=6; i>0; --i){
-               qbar(buffer, i-1, ctx);
-       }
-       for(i=0; i<32/4; ++i){
-               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
-       }
-}
-
-
-#undef A
-#undef B
-#undef C
-#undef D
-
-#define A (((uint32_t*)buffer)[0])
-#define B (((uint32_t*)buffer)[1])
-#define C (((uint32_t*)buffer)[2])
-#define D (((uint32_t*)buffer)[3])
-#define E (((uint32_t*)buffer)[4])
-#define F (((uint32_t*)buffer)[5])
-#define G (((uint32_t*)buffer)[6])
-#define H (((uint32_t*)buffer)[7])
-
-/*
- * we might later make it optional to use this small thing
-static
-void w(void* buffer, uint8_t* tr, uint32_t* tm){
-       G ^= f1(H, (tr[0]&0x0f)+(tr[5]&0x01)?0x10:0x00, tm[0]);
-       F ^= f2(G, (tr[0]>>4)  +(tr[5]&0x02)?0x10:0x00, tm[1]);
-       E ^= f3(F, (tr[1]&0x0f)+(tr[5]&0x04)?0x10:0x00, tm[2]);
-       D ^= f1(E, (tr[1]>>4)  +(tr[5]&0x08)?0x10:0x00, tm[3]);
-       C ^= f2(D, (tr[2]&0x0f)+(tr[5]&0x10)?0x10:0x00, tm[4]);
-       B ^= f3(C, (tr[2]>>4)  +(tr[5]&0x20)?0x10:0x00, tm[5]);
-       A ^= f1(B, (tr[3]&0x0f)+(tr[5]&0x40)?0x10:0x00, tm[6]);
-       H ^= f2(A, (tr[3]>>4)  +(tr[5]&0x80)?0x10:0x00, tm[7]);
-}
-*/
-static
-void w(void* buffer, uint8_t* tr, uint32_t* tm){
-       G ^= f1(H, tr[0], tm[0]);
-       F ^= f2(G, tr[1], tm[1]);
-       E ^= f3(F, tr[2], tm[2]);
-       D ^= f1(E, tr[3], tm[3]);
-       C ^= f2(D, tr[4], tm[4]);
-       B ^= f3(C, tr[5], tm[5]);
-       A ^= f1(B, tr[6], tm[6]);
-       H ^= f2(A, tr[7], tm[7]);
-}
-
-/*
-void dump_ctx(const cast6_ctx_t* ctx){
-       uint8_t i,t;
-       cli_putstr_P(PSTR("\r\n DBG:"));
-       for(i=0; i<12; ++i){
-               cli_putstr_P(PSTR("\r\n DBG:"));
-               cli_putstr_P(PSTR(" rotk1="));
-               t=kr(i*4+0, ctx);
-               cli_hexdump(&t,1);
-               cli_putstr_P(PSTR("          rotk2="));
-               t=kr(i*4+1, ctx);
-               cli_hexdump(&t,1);
-               cli_putstr_P(PSTR("          rotk3="));
-               t=kr(i*4+2, ctx);
-               cli_hexdump(&t,1);
-               cli_putstr_P(PSTR("          rotk4="));
-               t=kr(i*4+3, ctx);
-               cli_hexdump(&t,1);
-               cli_putstr_P(PSTR("\r\n     "));
-               cli_putstr_P(PSTR(" mask1="));
-               cli_hexdump(&(ctx->km[i][0]),4);
-               cli_putstr_P(PSTR(" mask2="));
-               cli_hexdump(&(ctx->km[i][1]),4);
-               cli_putstr_P(PSTR(" mask3="));
-               cli_hexdump(&(ctx->km[i][2]),4);
-               cli_putstr_P(PSTR(" mask4="));
-               cli_hexdump(&(ctx->km[i][3]),4);
-               cli_putstr_P(PSTR("\r\n;-----"));
-       }
-}
-*/
-
-#define CR 19
-#define CM 0x5A827999
-#define MR 17 
-#define MM 0x6ED9EBA1
-
-void cast6_init(const void* key, uint16_t keysize_b, cast6_ctx_t* ctx){
-       uint8_t  buffer[32];
-       uint8_t  cr=CR, tr[8];
-       uint32_t cm=CM, tm[8];
-       uint8_t i,j;
-       
-       memset(buffer, 0, 32);
-       memcpy(buffer, key, (keysize_b+7)/8);
-       for(i=0; i<32/4; ++i){
-               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
-       }
-
-       for(i=0; i<24; ++i){
-               for(j=0; j<8; ++j){
-                       tm[j] = cm;
-                       cm += MM;
-                       tr[j] = cr&0x1F;
-                       cr += MR;
-               }
-               w(buffer, tr, tm);
-
-               if(i&1){
-                       j=i/2;
-                       ctx->km[j][0]=H;
-                       ctx->km[j][1]=F;
-                       ctx->km[j][2]=D;
-                       ctx->km[j][3]=B;
-                       set_kr((uint8_t)A,j*4+0,ctx);
-                       set_kr((uint8_t)C,j*4+1,ctx);
-                       set_kr((uint8_t)E,j*4+2,ctx);
-                       set_kr((uint8_t)G,j*4+3,ctx);
-               }
-       }
-}
-
-
-
diff --git a/cast6.h b/cast6.h
deleted file mode 100644 (file)
index dc3c7bb..0000000
--- a/cast6.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef CAST6_H_
-#define CAST6_H_
-
-#include <stdint.h>
-
-#define CAST6_ROUNDS 12
-
-/* size of this is 222 byte (HUGE) */
-typedef struct cast6_ctx_st{
-       uint32_t        km[12][4];
-       uint8_t         krx[4*12*5/8]; /* these are packed */
-} cast6_ctx_t;
-
-
-
-void cast6_enc(void* buffer, const cast6_ctx_t* ctx);
-void cast6_dec(void* buffer, const cast6_ctx_t* ctx);
-void cast6_init(const void* key, uint16_t keysize_b, cast6_ctx_t* ctx);
-
-
-#endif /*CAST6_H_*/
-
diff --git a/cast6/cast6.c b/cast6/cast6.c
new file mode 100644 (file)
index 0000000..c4922fc
--- /dev/null
@@ -0,0 +1,267 @@
+/* 
+ * File:       cast6.c
+ * Author:     Daniel Otte
+ * Date:       09.09.2006
+ * License: GPL
+ * Description: Implementation of the CAST6 (aka CAST-256) cipher algorithm as described in RFC 2612
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "cast6.h"
+#include "cast6_sboxes.h"
+
+#define CHANGE_ENDIAN32(x) (((x)<<24 | (x)>>24 | ((x)&0xff00)<<8 | ((x)&0xff0000)>>8)&0xffffffff)
+
+
+static
+uint8_t kr(uint8_t i, const cast6_ctx_t* ctx){
+       uint8_t ret;
+       ret = ctx->krx[i/2];
+       if(i&1){
+               ret >>= 4;
+       }else{
+               ret &= 0x0f;
+       }
+       /* now get the high bit */
+       ret |= ((ctx->krx[24+i/8])&(1<<(i%8)))?0x10:0x00;
+       return ret;
+}
+
+static
+void set_kr(uint8_t value, uint8_t i, cast6_ctx_t* ctx){
+       value &= 0x1F;
+       
+       (ctx->krx[i/2]) &= 0xF0>>((i&1)*4); /* clear the location where v should go */
+       (ctx->krx[i/2]) |= (value&0x0f)<<((i&1)*4); 
+       
+       /* now set the high bit */
+       (ctx->krx[24+i/8]) &= ~(1<<(i%8)); /* clear the location where v should go */
+       (ctx->krx[24+i/8]) |= (value>>4)<<(i%8); 
+}
+
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
+
+#define S1(a) (pgm_read_dword(&(s1[(a)])))
+#define S2(a) (pgm_read_dword(&(s2[(a)])))
+#define S3(a) (pgm_read_dword(&(s3[(a)])))
+#define S4(a) (pgm_read_dword(&(s4[(a)])))
+
+#define A ((uint8_t)(v>>(8*3)))
+#define B ((uint8_t)(v>>(8*2)))
+#define C ((uint8_t)(v>>(8*1)))
+#define D ((uint8_t)(v>>(8*0)))
+
+
+static
+uint32_t f1(uint32_t v, uint8_t kri, uint32_t kmi){
+       uint32_t o;
+       kri &= 0x1F;
+       v  = ROTL32(kmi+v, kri);
+       o  = S1(A);
+       o ^= S2(B);
+       o -= S3(C);
+       o += S4(D);
+       return o;
+}
+
+static
+uint32_t f2(uint32_t v, uint8_t kri, uint32_t kmi){
+       uint32_t o;
+       kri &= 0x1F;
+       v  = ROTL32(kmi^v, kri);
+       o  = S1(A);
+       o -= S2(B);
+       o += S3(C);
+       o ^= S4(D);
+       return o;
+}
+
+static
+uint32_t f3(uint32_t v, uint8_t kri, uint32_t kmi){
+       uint32_t o;
+       kri &= 0x1F;
+       v  = ROTL32(kmi-v, kri);
+       o  = S1(A);
+       o += S2(B);
+       o ^= S3(C);
+       o -= S4(D);
+       return o;
+}
+
+#undef A
+#undef B
+#undef C
+#undef D
+
+#define A (((uint32_t*)buffer)[0])
+#define B (((uint32_t*)buffer)[1])
+#define C (((uint32_t*)buffer)[2])
+#define D (((uint32_t*)buffer)[3])
+
+static
+void q(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
+       C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
+       B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
+       A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
+       D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
+}
+
+static
+void qbar(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
+       D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
+       A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
+       B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
+       C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
+}
+
+void cast6_enc(void* buffer, const cast6_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<32/4; ++i){
+               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
+       }
+       for(i=0; i<6; ++i){
+               q(buffer, i, ctx);
+       }
+       for(i=6; i<12; ++i){
+               qbar(buffer, i, ctx);
+       }
+       for(i=0; i<32/4; ++i){
+               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
+       }
+}
+
+void cast6_dec(void* buffer, const cast6_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<32/4; ++i){
+               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
+       }
+       for(i=12; i>6; --i){
+               q(buffer, i-1, ctx);
+       }
+       for(i=6; i>0; --i){
+               qbar(buffer, i-1, ctx);
+       }
+       for(i=0; i<32/4; ++i){
+               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
+       }
+}
+
+
+#undef A
+#undef B
+#undef C
+#undef D
+
+#define A (((uint32_t*)buffer)[0])
+#define B (((uint32_t*)buffer)[1])
+#define C (((uint32_t*)buffer)[2])
+#define D (((uint32_t*)buffer)[3])
+#define E (((uint32_t*)buffer)[4])
+#define F (((uint32_t*)buffer)[5])
+#define G (((uint32_t*)buffer)[6])
+#define H (((uint32_t*)buffer)[7])
+
+/*
+ * we might later make it optional to use this small thing
+static
+void w(void* buffer, uint8_t* tr, uint32_t* tm){
+       G ^= f1(H, (tr[0]&0x0f)+(tr[5]&0x01)?0x10:0x00, tm[0]);
+       F ^= f2(G, (tr[0]>>4)  +(tr[5]&0x02)?0x10:0x00, tm[1]);
+       E ^= f3(F, (tr[1]&0x0f)+(tr[5]&0x04)?0x10:0x00, tm[2]);
+       D ^= f1(E, (tr[1]>>4)  +(tr[5]&0x08)?0x10:0x00, tm[3]);
+       C ^= f2(D, (tr[2]&0x0f)+(tr[5]&0x10)?0x10:0x00, tm[4]);
+       B ^= f3(C, (tr[2]>>4)  +(tr[5]&0x20)?0x10:0x00, tm[5]);
+       A ^= f1(B, (tr[3]&0x0f)+(tr[5]&0x40)?0x10:0x00, tm[6]);
+       H ^= f2(A, (tr[3]>>4)  +(tr[5]&0x80)?0x10:0x00, tm[7]);
+}
+*/
+static
+void w(void* buffer, uint8_t* tr, uint32_t* tm){
+       G ^= f1(H, tr[0], tm[0]);
+       F ^= f2(G, tr[1], tm[1]);
+       E ^= f3(F, tr[2], tm[2]);
+       D ^= f1(E, tr[3], tm[3]);
+       C ^= f2(D, tr[4], tm[4]);
+       B ^= f3(C, tr[5], tm[5]);
+       A ^= f1(B, tr[6], tm[6]);
+       H ^= f2(A, tr[7], tm[7]);
+}
+
+/*
+void dump_ctx(const cast6_ctx_t* ctx){
+       uint8_t i,t;
+       cli_putstr_P(PSTR("\r\n DBG:"));
+       for(i=0; i<12; ++i){
+               cli_putstr_P(PSTR("\r\n DBG:"));
+               cli_putstr_P(PSTR(" rotk1="));
+               t=kr(i*4+0, ctx);
+               cli_hexdump(&t,1);
+               cli_putstr_P(PSTR("          rotk2="));
+               t=kr(i*4+1, ctx);
+               cli_hexdump(&t,1);
+               cli_putstr_P(PSTR("          rotk3="));
+               t=kr(i*4+2, ctx);
+               cli_hexdump(&t,1);
+               cli_putstr_P(PSTR("          rotk4="));
+               t=kr(i*4+3, ctx);
+               cli_hexdump(&t,1);
+               cli_putstr_P(PSTR("\r\n     "));
+               cli_putstr_P(PSTR(" mask1="));
+               cli_hexdump(&(ctx->km[i][0]),4);
+               cli_putstr_P(PSTR(" mask2="));
+               cli_hexdump(&(ctx->km[i][1]),4);
+               cli_putstr_P(PSTR(" mask3="));
+               cli_hexdump(&(ctx->km[i][2]),4);
+               cli_putstr_P(PSTR(" mask4="));
+               cli_hexdump(&(ctx->km[i][3]),4);
+               cli_putstr_P(PSTR("\r\n;-----"));
+       }
+}
+*/
+
+#define CR 19
+#define CM 0x5A827999
+#define MR 17 
+#define MM 0x6ED9EBA1
+
+void cast6_init(const void* key, uint16_t keysize_b, cast6_ctx_t* ctx){
+       uint8_t  buffer[32];
+       uint8_t  cr=CR, tr[8];
+       uint32_t cm=CM, tm[8];
+       uint8_t i,j;
+       
+       memset(buffer, 0, 32);
+       memcpy(buffer, key, (keysize_b+7)/8);
+       for(i=0; i<32/4; ++i){
+               ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
+       }
+
+       for(i=0; i<24; ++i){
+               for(j=0; j<8; ++j){
+                       tm[j] = cm;
+                       cm += MM;
+                       tr[j] = cr&0x1F;
+                       cr += MR;
+               }
+               w(buffer, tr, tm);
+
+               if(i&1){
+                       j=i/2;
+                       ctx->km[j][0]=H;
+                       ctx->km[j][1]=F;
+                       ctx->km[j][2]=D;
+                       ctx->km[j][3]=B;
+                       set_kr((uint8_t)A,j*4+0,ctx);
+                       set_kr((uint8_t)C,j*4+1,ctx);
+                       set_kr((uint8_t)E,j*4+2,ctx);
+                       set_kr((uint8_t)G,j*4+3,ctx);
+               }
+       }
+}
+
+
+
diff --git a/cast6/cast6.h b/cast6/cast6.h
new file mode 100644 (file)
index 0000000..dc3c7bb
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef CAST6_H_
+#define CAST6_H_
+
+#include <stdint.h>
+
+#define CAST6_ROUNDS 12
+
+/* size of this is 222 byte (HUGE) */
+typedef struct cast6_ctx_st{
+       uint32_t        km[12][4];
+       uint8_t         krx[4*12*5/8]; /* these are packed */
+} cast6_ctx_t;
+
+
+
+void cast6_enc(void* buffer, const cast6_ctx_t* ctx);
+void cast6_dec(void* buffer, const cast6_ctx_t* ctx);
+void cast6_init(const void* key, uint16_t keysize_b, cast6_ctx_t* ctx);
+
+
+#endif /*CAST6_H_*/
+
diff --git a/cast6/cast6_sboxes.h b/cast6/cast6_sboxes.h
new file mode 100644 (file)
index 0000000..88bd81e
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef CAST6_SBOXES_H_
+#define CAST6_SBOXES_H_
+
+
+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};
+
+
+
+
+#endif /*CAST6_SBOXES_H_*/
diff --git a/cast6_sboxes.h b/cast6_sboxes.h
deleted file mode 100644 (file)
index 88bd81e..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifndef CAST6_SBOXES_H_
-#define CAST6_SBOXES_H_
-
-
-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};
-
-
-
-
-#endif /*CAST6_SBOXES_H_*/
diff --git a/des.c b/des.c
deleted file mode 100644 (file)
index 2600a22..0000000
--- a/des.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* des.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file     des.c
- * \author   Daniel Otte
- * \email    daniel.otte@rub.de
- * \date     2007-06-16
- * \brief    DES and EDE-DES implementation
- * \license     GPLv3 or later
- * 
- */
-#include "config.h"
-#include "debug.h"
-#include "cli.h"
-#include <stdint.h>
-#include <string.h>
-#include <util/delay.h>
-#include <avr/pgmspace.h>
-
-prog_uint8_t sbox[256]  = {
-  /* S-box 1 */
-  0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
-  0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
-  0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
-  0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
-  /* S-box 2 */
-  0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
-  0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
-  0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
-  0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
-  /* S-box 3 */
-  0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
-  0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
-  0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
-  0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
-  /* S-box 4 */
-  0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
-  0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
-  0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
-  0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
-  /* S-box 5 */
-  0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
-  0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
-  0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
-  0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
-  /* S-box 6 */
-  0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
-  0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
-  0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
-  0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
-  /* S-box 7 */
-  0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
-  0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
-  0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
-  0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
-  /* S-box 8 */
-  0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
-  0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
-  0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
-  0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
-};
-
-prog_uint8_t e_permtab[] ={ 
-        4,  6,                                         /* 4 bytes in 6 bytes out*/
-       32,  1,  2,  3,  4,  5,
-        4,  5,  6,  7,  8,  9,
-        8,  9, 10, 11, 12, 13,
-       12, 13, 14, 15, 16, 17,
-       16, 17, 18, 19, 20, 21,
-       20, 21, 22, 23, 24, 25,
-       24, 25, 26, 27, 28, 29,
-       28, 29, 30, 31, 32,  1
-};
-
-prog_uint8_t p_permtab[] ={ 
-        4,  4,                                         /* 32 bit -> 32 bit */
-       16,  7, 20, 21,
-       29, 12, 28, 17,
-        1, 15, 23, 26,
-        5, 18, 31, 10,
-        2,  8, 24, 14,
-       32, 27,  3,  9,
-       19, 13, 30,  6,
-       22, 11,  4, 25
-};
-
-prog_uint8_t ip_permtab[] ={ 
-        8,  8,                                         /* 64 bit -> 64 bit */
-       58, 50, 42, 34, 26, 18, 10, 2,
-       60, 52, 44, 36, 28, 20, 12, 4,
-       62, 54, 46, 38, 30, 22, 14, 6,
-       64, 56, 48, 40, 32, 24, 16, 8,
-       57, 49, 41, 33, 25, 17,  9, 1,
-       59, 51, 43, 35, 27, 19, 11, 3,
-       61, 53, 45, 37, 29, 21, 13, 5,
-       63, 55, 47, 39, 31, 23, 15, 7
-};
-
-prog_uint8_t inv_ip_permtab[] ={ 
-        8, 8,                                          /* 64 bit -> 64 bit */
-       40, 8, 48, 16, 56, 24, 64, 32,
-       39, 7, 47, 15, 55, 23, 63, 31,
-       38, 6, 46, 14, 54, 22, 62, 30,
-       37, 5, 45, 13, 53, 21, 61, 29,
-       36, 4, 44, 12, 52, 20, 60, 28,
-       35, 3, 43, 11, 51, 19, 59, 27,
-       34, 2, 42, 10, 50, 18, 58, 26,
-       33, 1, 41,  9, 49, 17, 57, 25
-};
-
-prog_uint8_t pc1_permtab[] ={ 
-        8,  7,                                         /* 64 bit -> 56 bit*/
-       57, 49, 41, 33, 25, 17,  9,
-        1, 58, 50, 42, 34, 26, 18,
-       10,  2, 59, 51, 43, 35, 27,
-       19, 11,  3, 60, 52, 44, 36,
-       63, 55, 47, 39, 31, 23, 15,
-        7, 62, 54, 46, 38, 30, 22,
-       14,  6, 61, 53, 45, 37, 29,
-       21, 13,  5, 28, 20, 12,  4
-};
-
-prog_uint8_t pc2_permtab[] ={ 
-        7,      6,                                     /* 56 bit -> 48 bit */
-       14, 17, 11, 24,  1,  5,
-        3, 28, 15,  6, 21, 10,
-       23, 19, 12,  4, 26,  8,
-       16,  7, 27, 20, 13,  2,
-       41, 52, 31, 37, 47, 55,
-       30, 40, 51, 45, 33, 48,
-       44, 49, 39, 56, 34, 53,
-       46, 42, 50, 36, 29, 32
-};
-
-prog_uint8_t splitin6bitword_permtab[] = {
-        8,  8,                                         /* 64 bit -> 64 bit */
-       64, 64,  1,  6,  2,  3,  4,  5, 
-       64, 64,  7, 12,  8,  9, 10, 11, 
-       64, 64, 13, 18, 14, 15, 16, 17, 
-       64, 64, 19, 24, 20, 21, 22, 23, 
-       64, 64, 25, 30, 26, 27, 28, 29, 
-       64, 64, 31, 36, 32, 33, 34, 35, 
-       64, 64, 37, 42, 38, 39, 40, 41, 
-       64, 64, 43, 48, 44, 45, 46, 47 
-};
-
-prog_uint8_t shiftkey_permtab[] = {
-        7,  7,                                         /* 56 bit -> 56 bit */
-        2,  3,  4,  5,  6,  7,  8,  9,
-       10, 11, 12, 13, 14, 15, 16, 17,
-       18, 19, 20, 21, 22, 23, 24, 25, 
-       26, 27, 28,  1, 
-       30, 31, 32, 33, 34, 35, 36, 37, 
-       38, 39, 40, 41, 42, 43, 44, 45, 
-       46, 47, 48, 49, 50, 51, 52, 53, 
-       54, 55, 56, 29
-};
-
-prog_uint8_t shiftkeyinv_permtab[] = {
-        7,  7,
-       28,  1,  2,  3,  4,  5,  6,  7,
-        8,  9, 10, 11, 12, 13, 14, 15,
-       16, 17, 18, 19, 20, 21, 22, 23,
-       24, 25, 26, 27,
-       56, 29, 30, 31, 32, 33, 34, 35, 
-       36, 37, 38, 39, 40, 41, 42, 43, 
-       44, 45, 46, 47, 48, 49, 50, 51, 
-       52, 53, 54, 55
-};
-
-/*
-1 0
-1 0
-2 1
-2 1
-2 1
-2 1
-2 1
-2 1
-----
-1 0
-2 1
-2 1
-2 1
-2 1
-2 1
-2 1
-1 0
-*/
-#define ROTTABLE      0x7EFC 
-#define ROTTABLE_INV  0x3F7E
-/******************************************************************************/
-
-void permute(prog_uint8_t *ptable, const uint8_t *in, uint8_t *out){
-       uint8_t ib, ob; /* in-bytes and out-bytes */
-       uint8_t byte, bit; /* counter for bit and byte */
-       ib = pgm_read_byte(&(ptable[0]));
-       ob = pgm_read_byte(&(ptable[1]));
-       ptable = &(ptable[2]);
-       for(byte=0; byte<ob; ++byte){
-               uint8_t x,t=0;
-               for(bit=0; bit<8; ++bit){
-                       x=pgm_read_byte(&(ptable[byte*8+bit])) -1 ;
-                               t<<=1;
-                       if((in[x/8]) & (0x80>>(x%8)) ){
-                               t|=0x01;
-                       }
-               }
-               out[byte]=t;
-       }
-}
-
-/******************************************************************************/
-
-void changeendian32(uint32_t * a){
-       *a = (*a & 0x000000FF) << 24 |
-                (*a & 0x0000FF00) <<  8 |
-                (*a & 0x00FF0000) >>  8 |
-                (*a & 0xFF000000) >> 24;
-}
-
-/******************************************************************************/
-static inline
-void shiftkey(uint8_t *key){
-       uint8_t k[7];
-       memcpy(k, key, 7);
-       permute((prog_uint8_t*)shiftkey_permtab, k, key);       
-}
-
-/******************************************************************************/
-static inline
-void shiftkey_inv(uint8_t *key){
-       uint8_t k[7];
-       memcpy(k, key, 7);
-       permute((prog_uint8_t*)shiftkeyinv_permtab, k, key);
-       
-}
-
-/******************************************************************************/
-static inline
-uint64_t splitin6bitwords(uint64_t a){
-       uint64_t ret=0;
-       a &= 0x0000ffffffffffffLL;
-       permute((prog_uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);  
-       return ret;
-}
-
-/******************************************************************************/
-
-static inline
-uint8_t substitute(uint8_t a, prog_uint8_t * sbp){
-       uint8_t x;      
-       x = pgm_read_byte(&(sbp[a>>1]));
-       x = (a&1)?x&0x0F:x>>4;
-       return x;
-       
-}
-
-/******************************************************************************/
-
-uint32_t des_f(uint32_t r, uint8_t* kr){
-       uint8_t i;
-       uint32_t t=0,ret;
-       uint64_t data;
-       prog_uint8_t *sbp; /* sboxpointer */ 
-       permute((prog_uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
-       for(i=0; i<7; ++i)
-               ((uint8_t*)&data)[i] ^= kr[i];
-       
-       /* Sbox substitution */
-       data = splitin6bitwords(data);
-       sbp=(prog_uint8_t*)sbox;
-       for(i=0; i<8; ++i){
-               uint8_t x;
-               x = substitute(((uint8_t*)&data)[i], sbp);
-               t<<=4;
-               t |= x;
-               sbp += 32;
-       }
-       changeendian32(&t);
-               
-       permute((prog_uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
-
-       return ret;
-}
-
-/******************************************************************************/
-
-void des_enc(void* out, const void* in, const void* key){
-#define R *((uint32_t*)&(data[4]))
-#define L *((uint32_t*)&(data[0]))
-
-       uint8_t data[8],kr[6],k[7];
-       uint8_t i;
-       
-       permute((prog_uint8_t*)ip_permtab, (uint8_t*)in, data);
-       permute((prog_uint8_t*)pc1_permtab, (uint8_t*)key, k);
-       for(i=0; i<8; ++i){
-               shiftkey(k);
-               if(ROTTABLE&((1<<((i<<1)+0))) )
-                       shiftkey(k);
-               permute((prog_uint8_t*)pc2_permtab, k, kr);
-               L ^= des_f(R, kr);
-               
-               shiftkey(k);
-               if(ROTTABLE&((1<<((i<<1)+1))) )
-                       shiftkey(k);
-               permute((prog_uint8_t*)pc2_permtab, k, kr);
-               R ^= des_f(L, kr);
-
-       }
-       /* L <-> R*/
-       R ^= L;
-       L ^= R;
-       R ^= L;
-       
-       permute((prog_uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
-}
-
-/******************************************************************************/
-
-void des_dec(void* out, const void* in, const uint8_t* key){
-#define R *((uint32_t*)&(data[4]))
-#define L *((uint32_t*)&(data[0]))
-
-       uint8_t data[8],kr[6],k[7];
-       int8_t i;
-       
-       permute((prog_uint8_t*)ip_permtab, (uint8_t*)in, data);
-       permute((prog_uint8_t*)pc1_permtab, (uint8_t*)key, k);
-       for(i=7; i>=0; --i){
-               
-               permute((prog_uint8_t*)pc2_permtab, k, kr);
-               L ^= des_f(R, kr);
-               shiftkey_inv(k);
-               if(ROTTABLE&((1<<((i<<1)+1))) ){
-                       shiftkey_inv(k);
-               }
-
-               permute((prog_uint8_t*)pc2_permtab, k, kr);
-               R ^= des_f(L, kr);
-               shiftkey_inv(k);
-               if(ROTTABLE&((1<<((i<<1)+0))) ){
-                       shiftkey_inv(k);
-               }
-
-       }
-       /* L <-> R*/
-       R ^= L;
-       L ^= R;
-       R ^= L;
-       
-       permute((prog_uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
-}
-
-/******************************************************************************/
-
-void tdes_enc(void* out, void* in, const void* key){
-       des_enc(out,  in, (uint8_t*)key + 0);
-       des_dec(out, out, (uint8_t*)key + 8);
-       des_enc(out, out, (uint8_t*)key +16);
-}
-
-/******************************************************************************/
-
-void tdes_dec(void* out, void* in, const uint8_t* key){
-       des_dec(out,  in, (uint8_t*)key + 0);
-       des_enc(out, out, (uint8_t*)key + 8);
-       des_dec(out, out, (uint8_t*)key +16);
-}
-
-/******************************************************************************/
-
-
diff --git a/des.h b/des.h
deleted file mode 100644 (file)
index 082de13..0000000
--- a/des.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* des.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       des.h
- * \author     Daniel Otte 
- * \date       2007-06-16
- * \brief      des and tdes declarations
- * \license    GPLv3 or later
- * 
- */
-#ifndef DES_H_
-#define DES_H_
-
-/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA.
- * Also we only implement the three key mode  */
-
-/** \def tdea_enc
- * \brief defining an alias for void tdes_enc(void* out, const void* in, const void* key)
- */
-
-/** \def tdea_dec
- * \brief defining an alias for void tdes_dec(void* out, const void* in, const void* key)
- */
-
-#define tdea_enc tdes_enc
-#define tdea_dec tdes_dec
-
-/** \fn void des_enc(void* out, const void* in, const void* key)
- * \brief encrypt a block with DES
- * 
- * This function encrypts a block of 64 bits (8 bytes) with the DES algorithm.
- * Key expansion is done automatically. The key is 64 bits long, but note that
- * only 56 bits are used (the LSB of each byte is droped). The input and output
- * blocks may overlap.
- * 
- * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
- * \param in  pointer to the block (64 bit = 8 byte) where the plaintext is read from
- * \param key pointer to the key (64 bit = 8 byte)
- */
-void des_enc(void* out, const void* in, const void* key);
-
-/** \fn void des_dec(void* out, const void* in, const void* key)
- * \brief decrypt a block with DES
- * 
- * This function decrypts a block of 64 bits (8 bytes) with the DES algorithm.
- * Key expansion is done automatically. The key is 64 bits long, but note that
- * only 56 bits are used (the LSB of each byte is droped). The input and output
- * blocks may overlap.
- * 
- * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
- * \param in  pointer to the block (64 bit = 8 byte) where the ciphertext is read from
- * \param key pointer to the key (64 bit = 8 byte)
- */
-void des_dec(void* out, const void* in, const void* key);
-
-/** \fn void tdes_enc(void* out, const void* in, const void* key)
- * \brief encrypt a block with Tripple-DES
- * 
- * This function encrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
- * algorithm. Key expansion is done automatically. The key is 192 bits long, but
- * note that only 178 bits are used (the LSB of each byte is droped). The input
- * and output blocks may overlap.
- * 
- * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
- * \param in  pointer to the block (64 bit = 8 byte) where the plaintext is read from
- * \param key pointer to the key (192 bit = 24 byte)
- */
-void tdes_enc(void* out, const void* in, const void* key);
-
-/** \fn void tdes_dec(void* out, const void* in, const void* key)
- * \brief decrypt a block with Tripple-DES
- * 
- * This function decrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
- * algorithm. Key expansion is done automatically. The key is 192 bits long, but
- * note that only 178 bits are used (the LSB of each byte is droped). The input
- * and output blocks may overlap.
- * 
- * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
- * \param in  pointer to the block (64 bit = 8 byte) where the ciphertext is read from
- * \param key pointer to the key (192 bit = 24 byte)
- */
- void tdes_dec(void* out, const void* in, const void* key);
-
-#endif /*DES_H_*/
diff --git a/des/des.c b/des/des.c
new file mode 100644 (file)
index 0000000..2600a22
--- /dev/null
+++ b/des/des.c
@@ -0,0 +1,390 @@
+/* des.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file     des.c
+ * \author   Daniel Otte
+ * \email    daniel.otte@rub.de
+ * \date     2007-06-16
+ * \brief    DES and EDE-DES implementation
+ * \license     GPLv3 or later
+ * 
+ */
+#include "config.h"
+#include "debug.h"
+#include "cli.h"
+#include <stdint.h>
+#include <string.h>
+#include <util/delay.h>
+#include <avr/pgmspace.h>
+
+prog_uint8_t sbox[256]  = {
+  /* S-box 1 */
+  0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
+  0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
+  0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
+  0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
+  /* S-box 2 */
+  0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
+  0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
+  0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
+  0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
+  /* S-box 3 */
+  0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
+  0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
+  0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
+  0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
+  /* S-box 4 */
+  0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
+  0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
+  0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
+  0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
+  /* S-box 5 */
+  0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
+  0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
+  0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
+  0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
+  /* S-box 6 */
+  0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
+  0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
+  0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
+  0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
+  /* S-box 7 */
+  0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
+  0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
+  0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
+  0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
+  /* S-box 8 */
+  0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
+  0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
+  0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
+  0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
+};
+
+prog_uint8_t e_permtab[] ={ 
+        4,  6,                                         /* 4 bytes in 6 bytes out*/
+       32,  1,  2,  3,  4,  5,
+        4,  5,  6,  7,  8,  9,
+        8,  9, 10, 11, 12, 13,
+       12, 13, 14, 15, 16, 17,
+       16, 17, 18, 19, 20, 21,
+       20, 21, 22, 23, 24, 25,
+       24, 25, 26, 27, 28, 29,
+       28, 29, 30, 31, 32,  1
+};
+
+prog_uint8_t p_permtab[] ={ 
+        4,  4,                                         /* 32 bit -> 32 bit */
+       16,  7, 20, 21,
+       29, 12, 28, 17,
+        1, 15, 23, 26,
+        5, 18, 31, 10,
+        2,  8, 24, 14,
+       32, 27,  3,  9,
+       19, 13, 30,  6,
+       22, 11,  4, 25
+};
+
+prog_uint8_t ip_permtab[] ={ 
+        8,  8,                                         /* 64 bit -> 64 bit */
+       58, 50, 42, 34, 26, 18, 10, 2,
+       60, 52, 44, 36, 28, 20, 12, 4,
+       62, 54, 46, 38, 30, 22, 14, 6,
+       64, 56, 48, 40, 32, 24, 16, 8,
+       57, 49, 41, 33, 25, 17,  9, 1,
+       59, 51, 43, 35, 27, 19, 11, 3,
+       61, 53, 45, 37, 29, 21, 13, 5,
+       63, 55, 47, 39, 31, 23, 15, 7
+};
+
+prog_uint8_t inv_ip_permtab[] ={ 
+        8, 8,                                          /* 64 bit -> 64 bit */
+       40, 8, 48, 16, 56, 24, 64, 32,
+       39, 7, 47, 15, 55, 23, 63, 31,
+       38, 6, 46, 14, 54, 22, 62, 30,
+       37, 5, 45, 13, 53, 21, 61, 29,
+       36, 4, 44, 12, 52, 20, 60, 28,
+       35, 3, 43, 11, 51, 19, 59, 27,
+       34, 2, 42, 10, 50, 18, 58, 26,
+       33, 1, 41,  9, 49, 17, 57, 25
+};
+
+prog_uint8_t pc1_permtab[] ={ 
+        8,  7,                                         /* 64 bit -> 56 bit*/
+       57, 49, 41, 33, 25, 17,  9,
+        1, 58, 50, 42, 34, 26, 18,
+       10,  2, 59, 51, 43, 35, 27,
+       19, 11,  3, 60, 52, 44, 36,
+       63, 55, 47, 39, 31, 23, 15,
+        7, 62, 54, 46, 38, 30, 22,
+       14,  6, 61, 53, 45, 37, 29,
+       21, 13,  5, 28, 20, 12,  4
+};
+
+prog_uint8_t pc2_permtab[] ={ 
+        7,      6,                                     /* 56 bit -> 48 bit */
+       14, 17, 11, 24,  1,  5,
+        3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8,
+       16,  7, 27, 20, 13,  2,
+       41, 52, 31, 37, 47, 55,
+       30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53,
+       46, 42, 50, 36, 29, 32
+};
+
+prog_uint8_t splitin6bitword_permtab[] = {
+        8,  8,                                         /* 64 bit -> 64 bit */
+       64, 64,  1,  6,  2,  3,  4,  5, 
+       64, 64,  7, 12,  8,  9, 10, 11, 
+       64, 64, 13, 18, 14, 15, 16, 17, 
+       64, 64, 19, 24, 20, 21, 22, 23, 
+       64, 64, 25, 30, 26, 27, 28, 29, 
+       64, 64, 31, 36, 32, 33, 34, 35, 
+       64, 64, 37, 42, 38, 39, 40, 41, 
+       64, 64, 43, 48, 44, 45, 46, 47 
+};
+
+prog_uint8_t shiftkey_permtab[] = {
+        7,  7,                                         /* 56 bit -> 56 bit */
+        2,  3,  4,  5,  6,  7,  8,  9,
+       10, 11, 12, 13, 14, 15, 16, 17,
+       18, 19, 20, 21, 22, 23, 24, 25, 
+       26, 27, 28,  1, 
+       30, 31, 32, 33, 34, 35, 36, 37, 
+       38, 39, 40, 41, 42, 43, 44, 45, 
+       46, 47, 48, 49, 50, 51, 52, 53, 
+       54, 55, 56, 29
+};
+
+prog_uint8_t shiftkeyinv_permtab[] = {
+        7,  7,
+       28,  1,  2,  3,  4,  5,  6,  7,
+        8,  9, 10, 11, 12, 13, 14, 15,
+       16, 17, 18, 19, 20, 21, 22, 23,
+       24, 25, 26, 27,
+       56, 29, 30, 31, 32, 33, 34, 35, 
+       36, 37, 38, 39, 40, 41, 42, 43, 
+       44, 45, 46, 47, 48, 49, 50, 51, 
+       52, 53, 54, 55
+};
+
+/*
+1 0
+1 0
+2 1
+2 1
+2 1
+2 1
+2 1
+2 1
+----
+1 0
+2 1
+2 1
+2 1
+2 1
+2 1
+2 1
+1 0
+*/
+#define ROTTABLE      0x7EFC 
+#define ROTTABLE_INV  0x3F7E
+/******************************************************************************/
+
+void permute(prog_uint8_t *ptable, const uint8_t *in, uint8_t *out){
+       uint8_t ib, ob; /* in-bytes and out-bytes */
+       uint8_t byte, bit; /* counter for bit and byte */
+       ib = pgm_read_byte(&(ptable[0]));
+       ob = pgm_read_byte(&(ptable[1]));
+       ptable = &(ptable[2]);
+       for(byte=0; byte<ob; ++byte){
+               uint8_t x,t=0;
+               for(bit=0; bit<8; ++bit){
+                       x=pgm_read_byte(&(ptable[byte*8+bit])) -1 ;
+                               t<<=1;
+                       if((in[x/8]) & (0x80>>(x%8)) ){
+                               t|=0x01;
+                       }
+               }
+               out[byte]=t;
+       }
+}
+
+/******************************************************************************/
+
+void changeendian32(uint32_t * a){
+       *a = (*a & 0x000000FF) << 24 |
+                (*a & 0x0000FF00) <<  8 |
+                (*a & 0x00FF0000) >>  8 |
+                (*a & 0xFF000000) >> 24;
+}
+
+/******************************************************************************/
+static inline
+void shiftkey(uint8_t *key){
+       uint8_t k[7];
+       memcpy(k, key, 7);
+       permute((prog_uint8_t*)shiftkey_permtab, k, key);       
+}
+
+/******************************************************************************/
+static inline
+void shiftkey_inv(uint8_t *key){
+       uint8_t k[7];
+       memcpy(k, key, 7);
+       permute((prog_uint8_t*)shiftkeyinv_permtab, k, key);
+       
+}
+
+/******************************************************************************/
+static inline
+uint64_t splitin6bitwords(uint64_t a){
+       uint64_t ret=0;
+       a &= 0x0000ffffffffffffLL;
+       permute((prog_uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);  
+       return ret;
+}
+
+/******************************************************************************/
+
+static inline
+uint8_t substitute(uint8_t a, prog_uint8_t * sbp){
+       uint8_t x;      
+       x = pgm_read_byte(&(sbp[a>>1]));
+       x = (a&1)?x&0x0F:x>>4;
+       return x;
+       
+}
+
+/******************************************************************************/
+
+uint32_t des_f(uint32_t r, uint8_t* kr){
+       uint8_t i;
+       uint32_t t=0,ret;
+       uint64_t data;
+       prog_uint8_t *sbp; /* sboxpointer */ 
+       permute((prog_uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
+       for(i=0; i<7; ++i)
+               ((uint8_t*)&data)[i] ^= kr[i];
+       
+       /* Sbox substitution */
+       data = splitin6bitwords(data);
+       sbp=(prog_uint8_t*)sbox;
+       for(i=0; i<8; ++i){
+               uint8_t x;
+               x = substitute(((uint8_t*)&data)[i], sbp);
+               t<<=4;
+               t |= x;
+               sbp += 32;
+       }
+       changeendian32(&t);
+               
+       permute((prog_uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
+
+       return ret;
+}
+
+/******************************************************************************/
+
+void des_enc(void* out, const void* in, const void* key){
+#define R *((uint32_t*)&(data[4]))
+#define L *((uint32_t*)&(data[0]))
+
+       uint8_t data[8],kr[6],k[7];
+       uint8_t i;
+       
+       permute((prog_uint8_t*)ip_permtab, (uint8_t*)in, data);
+       permute((prog_uint8_t*)pc1_permtab, (uint8_t*)key, k);
+       for(i=0; i<8; ++i){
+               shiftkey(k);
+               if(ROTTABLE&((1<<((i<<1)+0))) )
+                       shiftkey(k);
+               permute((prog_uint8_t*)pc2_permtab, k, kr);
+               L ^= des_f(R, kr);
+               
+               shiftkey(k);
+               if(ROTTABLE&((1<<((i<<1)+1))) )
+                       shiftkey(k);
+               permute((prog_uint8_t*)pc2_permtab, k, kr);
+               R ^= des_f(L, kr);
+
+       }
+       /* L <-> R*/
+       R ^= L;
+       L ^= R;
+       R ^= L;
+       
+       permute((prog_uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
+}
+
+/******************************************************************************/
+
+void des_dec(void* out, const void* in, const uint8_t* key){
+#define R *((uint32_t*)&(data[4]))
+#define L *((uint32_t*)&(data[0]))
+
+       uint8_t data[8],kr[6],k[7];
+       int8_t i;
+       
+       permute((prog_uint8_t*)ip_permtab, (uint8_t*)in, data);
+       permute((prog_uint8_t*)pc1_permtab, (uint8_t*)key, k);
+       for(i=7; i>=0; --i){
+               
+               permute((prog_uint8_t*)pc2_permtab, k, kr);
+               L ^= des_f(R, kr);
+               shiftkey_inv(k);
+               if(ROTTABLE&((1<<((i<<1)+1))) ){
+                       shiftkey_inv(k);
+               }
+
+               permute((prog_uint8_t*)pc2_permtab, k, kr);
+               R ^= des_f(L, kr);
+               shiftkey_inv(k);
+               if(ROTTABLE&((1<<((i<<1)+0))) ){
+                       shiftkey_inv(k);
+               }
+
+       }
+       /* L <-> R*/
+       R ^= L;
+       L ^= R;
+       R ^= L;
+       
+       permute((prog_uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
+}
+
+/******************************************************************************/
+
+void tdes_enc(void* out, void* in, const void* key){
+       des_enc(out,  in, (uint8_t*)key + 0);
+       des_dec(out, out, (uint8_t*)key + 8);
+       des_enc(out, out, (uint8_t*)key +16);
+}
+
+/******************************************************************************/
+
+void tdes_dec(void* out, void* in, const uint8_t* key){
+       des_dec(out,  in, (uint8_t*)key + 0);
+       des_enc(out, out, (uint8_t*)key + 8);
+       des_dec(out, out, (uint8_t*)key +16);
+}
+
+/******************************************************************************/
+
+
diff --git a/des/des.h b/des/des.h
new file mode 100644 (file)
index 0000000..082de13
--- /dev/null
+++ b/des/des.h
@@ -0,0 +1,100 @@
+/* des.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       des.h
+ * \author     Daniel Otte 
+ * \date       2007-06-16
+ * \brief      des and tdes declarations
+ * \license    GPLv3 or later
+ * 
+ */
+#ifndef DES_H_
+#define DES_H_
+
+/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA.
+ * Also we only implement the three key mode  */
+
+/** \def tdea_enc
+ * \brief defining an alias for void tdes_enc(void* out, const void* in, const void* key)
+ */
+
+/** \def tdea_dec
+ * \brief defining an alias for void tdes_dec(void* out, const void* in, const void* key)
+ */
+
+#define tdea_enc tdes_enc
+#define tdea_dec tdes_dec
+
+/** \fn void des_enc(void* out, const void* in, const void* key)
+ * \brief encrypt a block with DES
+ * 
+ * This function encrypts a block of 64 bits (8 bytes) with the DES algorithm.
+ * Key expansion is done automatically. The key is 64 bits long, but note that
+ * only 56 bits are used (the LSB of each byte is droped). The input and output
+ * blocks may overlap.
+ * 
+ * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
+ * \param in  pointer to the block (64 bit = 8 byte) where the plaintext is read from
+ * \param key pointer to the key (64 bit = 8 byte)
+ */
+void des_enc(void* out, const void* in, const void* key);
+
+/** \fn void des_dec(void* out, const void* in, const void* key)
+ * \brief decrypt a block with DES
+ * 
+ * This function decrypts a block of 64 bits (8 bytes) with the DES algorithm.
+ * Key expansion is done automatically. The key is 64 bits long, but note that
+ * only 56 bits are used (the LSB of each byte is droped). The input and output
+ * blocks may overlap.
+ * 
+ * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
+ * \param in  pointer to the block (64 bit = 8 byte) where the ciphertext is read from
+ * \param key pointer to the key (64 bit = 8 byte)
+ */
+void des_dec(void* out, const void* in, const void* key);
+
+/** \fn void tdes_enc(void* out, const void* in, const void* key)
+ * \brief encrypt a block with Tripple-DES
+ * 
+ * This function encrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
+ * algorithm. Key expansion is done automatically. The key is 192 bits long, but
+ * note that only 178 bits are used (the LSB of each byte is droped). The input
+ * and output blocks may overlap.
+ * 
+ * \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
+ * \param in  pointer to the block (64 bit = 8 byte) where the plaintext is read from
+ * \param key pointer to the key (192 bit = 24 byte)
+ */
+void tdes_enc(void* out, const void* in, const void* key);
+
+/** \fn void tdes_dec(void* out, const void* in, const void* key)
+ * \brief decrypt a block with Tripple-DES
+ * 
+ * This function decrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
+ * algorithm. Key expansion is done automatically. The key is 192 bits long, but
+ * note that only 178 bits are used (the LSB of each byte is droped). The input
+ * and output blocks may overlap.
+ * 
+ * \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
+ * \param in  pointer to the block (64 bit = 8 byte) where the ciphertext is read from
+ * \param key pointer to the key (192 bit = 24 byte)
+ */
+ void tdes_dec(void* out, const void* in, const void* key);
+
+#endif /*DES_H_*/
diff --git a/entropium.c b/entropium.c
deleted file mode 100644 (file)
index ed56607..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* entropium.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file    entropium.c
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \date    2006-05-17
- * \license    GPLv3 or later
- * \brief      This file contains an implementaition of a pseudo-random-number generator.
- * 
- * Extension 1:
- *     rndCore is expanded to 512 bits for more security.
- *
-  \verbatim
-                       ################################################################################################
-                       #                                                                                              #
-                       #         +---------------------------+                                                        #
-                       #         |                           |                                                        #
-                       #         V                           |                                                        #
-                       #      (concat)                       |                                                        #
-   +---------------+   #    o---------o             (xor)+---------+      o---------o        o----o     o---------o   #    +--------------+
-   | entropy Block | -----> | sha-256 | --(offset)-<     | rndCore | ---> | sha-256 | --+----| +1 |---> | sha-256 | -----> | random Block |
-   +---------------+   #    o---------o             (xor)+---------+      o---------o   |    o----o     o---------o   #    +--------------+
-                       #                                 (xor) (xor)                    |                             #
-                       #                                   ^     ^                      |                             #
-                       #                                    \   /                       |                             #
-                       #                                   (offset)---------------------+                             #
-                       #                                                                                              #
-                       ################################################################################################
-  \endverbatim
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "sha256.h"
-#include "entropium.h"
-
-/**
- * \brief secret entropy pool. 
- * This is the core of the random which is generated
- */
-uint32_t rndCore[16]; 
-
-/*************************************************************************/
-
-/* idea is: hash the message and add it via xor to rndCore
- *
- * length in bits 
- * 
- * we simply first "hash" rndCore, then entropy.
- */
-void entropium_addEntropy(unsigned length_b, const 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_b>=512){
-               sha256_nextBlock(&s, data);
-               data = (uint8_t*)data+ 512/8;
-               length_b -= 512;        
-       }
-       sha256_lastBlock(&s, data, length_b);
-       uint8_t i;
-       for (i=0; i<8; ++i){
-               rndCore[i+offset] ^= s.h[i];
-       }
-       offset ^= 8; /* hehe */
-}
-
-/*************************************************************************/
-
-void entropium_getRandomBlock(void *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 */
-       ((uint8_t*)b)[*((uint8_t*)b)&31]++;     /* the important increment step */
-       sha256_init(&s);
-       sha256_lastBlock(&s, b, 256);
-       memcpy(b, s.h, 32);
-}
-
-/*************************************************************************/
-
-uint8_t entropium_getRandomByte(void){
-       static uint8_t block[32];
-       static uint8_t i=32;
-       
-       if (i==32){
-               entropium_getRandomBlock((void*)block);
-               i=0;
-       }       
-       return block[i++];
-}
-
-void entropium_fillBlockRandom(void* block, unsigned length_B){
-       while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){
-               entropium_getRandomBlock(block);
-               block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE;
-               length_B -= ENTROPIUM_RANDOMBLOCK_SIZE;
-       }
-       while(length_B){
-               *((uint8_t*)block) = entropium_getRandomByte();
-               block= (uint8_t*)block +1; --length_B;
-       }
-}
diff --git a/entropium.h b/entropium.h
deleted file mode 100644 (file)
index 303619d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* entropium.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * File:               entropium.h
- * Author:             Daniel Otte
- * Date:               23.07.2006
- * License:            GPL
- * Description:        This file contains the declarations for the pseudo-random-number generator.
- **/
-
-/**
- * \file    entropium.h
- * \author  Daniel Otte
- * \date    23.07.2006
- * \license    GPLv3 or later
- * \brief      This file contains the declarations for the pseudo-random-number generator.
- **/
-
-
-#ifndef ENTROPIUM_H_
-#define ENTROPIUM_H_
-
-#include <stdint.h>
-/*
- * length in bits 
- */
-#define ENTROPIUM_RANDOMBLOCK_SIZE 32 /* bytes */
-/** \fn void entropium_addEntropy(unsigned length_b, const void* data)
- * \brief add entropy to the prng
- * 
- * This function adds data to the internal entropy pool
- * \param length_b length of the data block in bits
- * \param data pointer to the data
- */
-void entropium_addEntropy(unsigned length_b, const void* data); 
-
-/** \fn void entropium_getRandomBlock(void* b)
- * \brief generate a fixed size block of random data 
- * 
- * This function writes 32 bytes of random extracted from the entropy pool
- * in the supplied buffer.
- * \param b buffer where the random data gets written
- */
-void entropium_getRandomBlock(void* b);
-
-/** \fn uint8_t entropium_getRandomByte(void)
- * \brief get a single byte of random data
- * 
- * This function utilizes a internal buffer which gets automatically filled
- * again. 
- * \return a byte of random data
- */ 
-uint8_t entropium_getRandomByte(void);
-
-/** \fn void entropium_fillBlockRandom(void* block, unsigned length_B)
- * \brief get a block of random data
- * 
- * This function writes random data extracted from the entropy pool in the 
- * supplied buffer. It shares a internal buffer with the 
- * entropium_getRandomByte() function.
- * \param block pointer to the buffer where the random data goes
- * \param length_B number of bytes to be written to the buffer
- */
-void entropium_fillBlockRandom(void* block, unsigned length_B);
-
-#endif /*PRNG_H_*/
diff --git a/entropium/entropium.c b/entropium/entropium.c
new file mode 100644 (file)
index 0000000..ed56607
--- /dev/null
@@ -0,0 +1,131 @@
+/* entropium.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file    entropium.c
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date    2006-05-17
+ * \license    GPLv3 or later
+ * \brief      This file contains an implementaition of a pseudo-random-number generator.
+ * 
+ * Extension 1:
+ *     rndCore is expanded to 512 bits for more security.
+ *
+  \verbatim
+                       ################################################################################################
+                       #                                                                                              #
+                       #         +---------------------------+                                                        #
+                       #         |                           |                                                        #
+                       #         V                           |                                                        #
+                       #      (concat)                       |                                                        #
+   +---------------+   #    o---------o             (xor)+---------+      o---------o        o----o     o---------o   #    +--------------+
+   | entropy Block | -----> | sha-256 | --(offset)-<     | rndCore | ---> | sha-256 | --+----| +1 |---> | sha-256 | -----> | random Block |
+   +---------------+   #    o---------o             (xor)+---------+      o---------o   |    o----o     o---------o   #    +--------------+
+                       #                                 (xor) (xor)                    |                             #
+                       #                                   ^     ^                      |                             #
+                       #                                    \   /                       |                             #
+                       #                                   (offset)---------------------+                             #
+                       #                                                                                              #
+                       ################################################################################################
+  \endverbatim
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sha256.h"
+#include "entropium.h"
+
+/**
+ * \brief secret entropy pool. 
+ * This is the core of the random which is generated
+ */
+uint32_t rndCore[16]; 
+
+/*************************************************************************/
+
+/* idea is: hash the message and add it via xor to rndCore
+ *
+ * length in bits 
+ * 
+ * we simply first "hash" rndCore, then entropy.
+ */
+void entropium_addEntropy(unsigned length_b, const 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_b>=512){
+               sha256_nextBlock(&s, data);
+               data = (uint8_t*)data+ 512/8;
+               length_b -= 512;        
+       }
+       sha256_lastBlock(&s, data, length_b);
+       uint8_t i;
+       for (i=0; i<8; ++i){
+               rndCore[i+offset] ^= s.h[i];
+       }
+       offset ^= 8; /* hehe */
+}
+
+/*************************************************************************/
+
+void entropium_getRandomBlock(void *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 */
+       ((uint8_t*)b)[*((uint8_t*)b)&31]++;     /* the important increment step */
+       sha256_init(&s);
+       sha256_lastBlock(&s, b, 256);
+       memcpy(b, s.h, 32);
+}
+
+/*************************************************************************/
+
+uint8_t entropium_getRandomByte(void){
+       static uint8_t block[32];
+       static uint8_t i=32;
+       
+       if (i==32){
+               entropium_getRandomBlock((void*)block);
+               i=0;
+       }       
+       return block[i++];
+}
+
+void entropium_fillBlockRandom(void* block, unsigned length_B){
+       while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){
+               entropium_getRandomBlock(block);
+               block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE;
+               length_B -= ENTROPIUM_RANDOMBLOCK_SIZE;
+       }
+       while(length_B){
+               *((uint8_t*)block) = entropium_getRandomByte();
+               block= (uint8_t*)block +1; --length_B;
+       }
+}
diff --git a/entropium/entropium.h b/entropium/entropium.h
new file mode 100644 (file)
index 0000000..303619d
--- /dev/null
@@ -0,0 +1,84 @@
+/* entropium.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * File:               entropium.h
+ * Author:             Daniel Otte
+ * Date:               23.07.2006
+ * License:            GPL
+ * Description:        This file contains the declarations for the pseudo-random-number generator.
+ **/
+
+/**
+ * \file    entropium.h
+ * \author  Daniel Otte
+ * \date    23.07.2006
+ * \license    GPLv3 or later
+ * \brief      This file contains the declarations for the pseudo-random-number generator.
+ **/
+
+
+#ifndef ENTROPIUM_H_
+#define ENTROPIUM_H_
+
+#include <stdint.h>
+/*
+ * length in bits 
+ */
+#define ENTROPIUM_RANDOMBLOCK_SIZE 32 /* bytes */
+/** \fn void entropium_addEntropy(unsigned length_b, const void* data)
+ * \brief add entropy to the prng
+ * 
+ * This function adds data to the internal entropy pool
+ * \param length_b length of the data block in bits
+ * \param data pointer to the data
+ */
+void entropium_addEntropy(unsigned length_b, const void* data); 
+
+/** \fn void entropium_getRandomBlock(void* b)
+ * \brief generate a fixed size block of random data 
+ * 
+ * This function writes 32 bytes of random extracted from the entropy pool
+ * in the supplied buffer.
+ * \param b buffer where the random data gets written
+ */
+void entropium_getRandomBlock(void* b);
+
+/** \fn uint8_t entropium_getRandomByte(void)
+ * \brief get a single byte of random data
+ * 
+ * This function utilizes a internal buffer which gets automatically filled
+ * again. 
+ * \return a byte of random data
+ */ 
+uint8_t entropium_getRandomByte(void);
+
+/** \fn void entropium_fillBlockRandom(void* block, unsigned length_B)
+ * \brief get a block of random data
+ * 
+ * This function writes random data extracted from the entropy pool in the 
+ * supplied buffer. It shares a internal buffer with the 
+ * entropium_getRandomByte() function.
+ * \param block pointer to the buffer where the random data goes
+ * \param length_B number of bytes to be written to the buffer
+ */
+void entropium_fillBlockRandom(void* block, unsigned length_B);
+
+#endif /*PRNG_H_*/
diff --git a/entropium/sha256-asm.S b/entropium/sha256-asm.S
new file mode 100644 (file)
index 0000000..d9eb6b6
--- /dev/null
@@ -0,0 +1,1042 @@
+/* sha256-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; sha-256 implementation in assembler  
+SHA256_BLOCK_BITS = 512
+SHA256_HASH_BITS = 256
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+       precall
+       hexdump \length
+       postcall
+.endm
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha256_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha256_ctx2hash
+; === sha256_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha256_ctx structure
+;      given in r23,r22
+sha256_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 8
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha256
+; === sha256 ===
+; this function calculates SHA-256 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha256:
+sha256_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 8*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha256_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha256_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha256_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha256_ctx2hash   
+       
+sha256_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 8*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha256_lastBlock
+; === sha256_lastBlock ===
+; this function does padding & Co. for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
+
+
+sha256_lastBlock:
+       cpi r21, 0x02
+       brlo sha256_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 0x02
+       subi r23, -2
+       rjmp sha256_lastBlock   
+sha256_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha256_lastBlock_post_copy
+       mov r1, r18
+sha256_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha256_lastBlock_copy_loop
+sha256_lastBlock_post_copy:    
+sha256_lastBlock_insert_stuffing_bit:  
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha256_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*8+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha256_lastBlock_insert_zeros: 
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha256_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha256_lastBlock_epilog
+sha256_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 8*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha256_nextBlock
+
+sha256_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha256_nextBlock
+; === sha256_nextBlock ===
+; this is the core function for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
+
+Bck1 = 12
+Bck2 = 13
+Bck3 = 14
+Bck4 = 15
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+Accu1 = 16
+Accu2 = 17
+Accu3 = 18
+Accu4 = 19
+XAccu1 = 8
+XAccu2 = 9
+XAccu3 = 10
+XAccu4 = 11
+T1     = 4
+T2     = 5
+T3     = 6
+T4     = 7
+LoopC = 1
+/* byteorder: high number <--> high significance */
+sha256_nextBlock:
+ ; initial, let's make some space ready for local vars
+       push r4 /* replace push & pop by mem ops? */
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha256_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       push r18
+       push r19
+       push r24
+       push r25 /* param1 will be needed later */
+ ; now we fill the w array with message (think about endianess)
+       adiw r26, 1 ; X++
+       ldi r20, 16
+sha256_nextBlock_wcpyloop:     
+       ld r23, Z+
+       ld r22, Z+
+       ld r19, Z+
+       ld r18, Z+
+       st X+, r18
+       st X+, r19
+       st X+, r22      
+       st X+, r23
+       dec r20
+       brne sha256_nextBlock_wcpyloop
+/*     for (i=16; i<64; ++i){
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+       } */
+       /* r25,r24,r23,r24 (r21,r20) are function values
+          r19,r18,r17,r16 are the accumulator
+          r15,r14,r13,rBck1 are backup1
+          r11,r10,r9 ,r8  are xor accu   
+          r1 is round counter                                                          */
+
+       ldi r20, 64-16
+       mov LoopC, r20
+sha256_nextBlock_wcalcloop:             
+       movw r30, r26 ; cp X to Z
+       sbiw r30, 63
+       sbiw r30, 1             ; substract 64 = 16*4
+       ld Accu1, Z+
+       ld Accu2, Z+
+       ld Accu3, Z+
+       ld Accu4, Z+ /* w[i] = w[i-16] */
+       ld Bck1, Z+
+       ld Bck2, Z+
+       ld Bck3, Z+
+       ld Bck4, Z+ /* backup = w[i-15] */
+       /* now sigma 0 */
+       mov Func1, Bck2
+       mov Func2, Bck3
+       mov Func3, Bck4
+       mov Func4, Bck1  /* prerotated by 8 */
+       ldi r20, 1
+       rcall bitrotl
+       movw XAccu1, Func1
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
+sigma0_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2
+       ror Bck1        
+       dec Func2
+       brne sigma0_shr
+       eor XAccu1, Bck1
+       eor XAccu2, Bck2
+       eor XAccu3, Bck3
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */
+       ldd Func2, Z+7*4+1
+       ldd Func3, Z+7*4+2
+       ldd Func4, Z+7*4+3
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
+       ldd Bck2, Z+12*4+1
+       ldd Bck3, Z+12*4+2
+       ldd Bck4, Z+12*4+3
+       /* now sigma 1 */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 1
+       rcall bitrotr
+       movw XAccu3, Func3
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
+;      movw Func1, Bck3
+;      movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
+sigma1_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2        
+       dec Func2
+       brne sigma1_shr
+       eor XAccu1, Bck2
+       eor XAccu2, Bck3
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       /* now let's store the shit */
+       st X+, Accu1
+       st X+, Accu2
+       st X+, Accu3
+       st X+, Accu4
+       dec LoopC
+       breq 3f  ; skip if zero
+       rjmp sha256_nextBlock_wcalcloop
+3:
+       /* we are finished with w array X points one byte post w */
+/* init a array */
+       pop r31
+       pop r30
+       push r30
+       push r31
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
+init_a_array:  
+       ld r1, Z+
+       st X+, r1
+       dec r25
+       brne init_a_array
+       
+/* now the real fun begins */
+/* 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;
+               } */
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
+       sbiw r26, 8*4  /* X still points at a[7]+1*/
+       movw r28, r26
+       ldi r30, lo8(sha256_kv)
+       ldi r31, hi8(sha256_kv)         
+       dec r27  /* X - (64*4 == 256) */
+       ldi r25, 64
+       mov LoopC, r25
+sha256_main_loop:
+       /* now calculate t1 */
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/
+       ldd T1, Y+5*4
+       ldd T2, Y+5*4+1
+       ldd T3, Y+5*4+2
+       ldd T4, Y+5*4+3 /* y in T */
+       ldd Func1, Y+4*4
+       ldd Func2, Y+4*4+1
+       ldd Func3, Y+4*4+2
+       ldd Func4, Y+4*4+3  /* x in Func */
+       ldd Bck1, Y+6*4
+       ldd Bck2, Y+6*4+1
+       ldd Bck3, Y+6*4+2
+       ldd Bck4, Y+6*4+3 /* z in Bck */
+       and T1, Func1
+       and T2, Func2
+       and T3, Func3
+       and T4, Func4
+       com Func1
+       com Func2
+       com Func3
+       com Func4
+       and Bck1, Func1
+       and Bck2, Func2
+       and Bck3, Func3
+       and Bck4, Func4
+       eor T1, Bck1
+       eor T2, Bck2
+       eor T3, Bck3
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */
+       /* now SIGMA1(a[4]) */
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
+       ldd Bck1, Y+4*4+1       
+       ldd Bck2, Y+4*4+2
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2 
+       rcall bitrotl           /* rotr(x,6) */ 
+       movw XAccu1, Func1
+       movw XAccu3, Func3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 3 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
+       ldi r20, 1 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4
+       /* now we've to add a[7], w[i] and k[i] */
+       ldd XAccu1, Y+4*7
+       ldd XAccu2, Y+4*7+1
+       ldd XAccu3, Y+4*7+2
+       ldd XAccu4, Y+4*7+3
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add a[7] */
+       ld XAccu1, X+
+       ld XAccu2, X+
+       ld XAccu3, X+
+       ld XAccu4, X+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add w[i] */
+       lpm XAccu1, Z+
+       lpm XAccu2, Z+
+       lpm XAccu3, Z+
+       lpm XAccu4, Z+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
+               /* starting with MAJ(x,y,z) */
+       ldd Func1, Y+4*0+0
+       ldd Func2, Y+4*0+1
+       ldd Func3, Y+4*0+2
+       ldd Func4, Y+4*0+3 /* load x=a[0] */
+       ldd XAccu1, Y+4*1+0
+       ldd XAccu2, Y+4*1+1
+       ldd XAccu3, Y+4*1+2
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
+       and XAccu1, Func1
+       and XAccu2, Func2
+       and XAccu3, Func3
+       and XAccu4, Func4       /* XAccu == (x & y) */
+       ldd Bck1, Y+4*2+0
+       ldd Bck2, Y+4*2+1
+       ldd Bck3, Y+4*2+2
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
+       ldd Func1, Y+4*1+0
+       ldd Func2, Y+4*1+1
+       ldd Func3, Y+4*1+2
+       ldd Func4, Y+4*1+3 /* load y=a[1] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
+       /* SIGMA0(a[0]) */
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */
+       ldd Bck2, Y+4*0+1
+       ldd Bck3, Y+4*0+2
+       ldd Bck4, Y+4*0+3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2
+       rcall bitrotr
+       movw Accu1, Func1
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
+       movw Func1, Bck3 
+       movw Func3, Bck1 /* prerotate by 16 bits */
+       ldi r20, 3
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
+       mov Func1, Bck4
+       mov Func2, Bck1
+       mov Func3, Bck2
+       mov Func4, Bck3  /* prerotate by 24 bits */
+       ldi r20, 2
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
+       add Accu1, XAccu1 /* add previous result (MAJ)*/
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
+       /* 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]; */
+
+       ldi r21, 7*4
+       adiw r28, 7*4
+a_shift_loop:
+       ld  r25, -Y /* warning: this is PREdecrement */
+       std Y+4, r25
+       dec r21
+       brne a_shift_loop
+
+       ldd Bck1, Y+4*4+0
+       ldd Bck2, Y+4*4+1
+       ldd Bck3, Y+4*4+2
+       ldd Bck4, Y+4*4+3
+       add Bck1, T1
+       adc Bck2, T2
+       adc Bck3, T3
+       adc Bck4, T4
+       std Y+4*4+0, Bck1
+       std Y+4*4+1, Bck2
+       std Y+4*4+2, Bck3
+       std Y+4*4+3, Bck4
+       add Accu1, T1
+       adc Accu2, T2
+       adc Accu3, T3
+       adc Accu4, T4
+       std Y+4*0+0, Accu1
+       std Y+4*0+1, Accu2
+       std Y+4*0+2, Accu3
+       std Y+4*0+3, Accu4 /* a array updated */
+       
+       
+       dec LoopC
+       breq update_state
+       rjmp sha256_main_loop ;brne sha256_main_loop
+update_state:  
+       /* update state */
+       /* pointers to state should still exist on the stack ;-) */
+       pop r31
+       pop r30
+       ldi r21, 8
+update_state_loop:
+       ldd Accu1, Z+0
+       ldd Accu2, Z+1
+       ldd Accu3, Z+2
+       ldd Accu4, Z+3 
+       ld Func1, Y+
+       ld Func2, Y+
+       ld Func3, Y+
+       ld Func4, Y+
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       st Z+, Accu1
+       st Z+, Accu2
+       st Z+, Accu3
+       st Z+, Accu4
+       dec r21
+       brne update_state_loop
+       /* now we just have to update the length */
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
+       ldi r21, 2
+       ldi r22, 6
+       ld r20, Z
+       add r20, r21
+       st Z+, r20      
+       clr r21
+sha256_nextBlock_fix_length:   
+       brcc sha256_nextBlock_epilog
+       ld r20, Z
+       adc r20, r21
+       st Z+, r20
+       dec r22
+       brne sha256_nextBlock_fix_length
+       
+; EPILOG
+sha256_nextBlock_epilog:
+/* now we should clean up the stack */
+       
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4 
+       ret
+
+sha256_kv: ; round-key-vector stored in ProgMem 
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
+
+       
+;###########################################################   
+
+.global sha256_init 
+;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);
+;}
+; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha256_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha256_init_vector))
+       ldi r31, hi8((sha256_init_vector))
+       ldi r22, 32+8
+sha256_init_vloop:     
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha256_init_vloop
+       ret
+       
+sha256_init_vector:
+.word 0xE667, 0x6A09
+.word 0xAE85, 0xBB67 
+.word 0xF372, 0x3C6E 
+.word 0xF53A, 0xA54F 
+.word 0x527F, 0x510E 
+.word 0x688C, 0x9B05 
+.word 0xD9AB, 0x1F83 
+.word 0xCD19, 0x5BE0
+.word 0x0000, 0x0000
+.word 0x0000, 0x0000
+
+;###########################################################   
+
+.global rotl32
+; === ROTL32 ===
+; function that rotates a 32 bit word to the left
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,r22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       clr r21
+       clc
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       rol r21
+       dec r20
+       rjmp bitrotl_loop
+fixrotl:
+       or r22, r21
+       ret
+       
+
+;###########################################################   
+
+.global rotr32
+; === ROTR32 ===
+; function that rotates a 32 bit word to the right
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotr32:
+       cpi r20, 8
+       brlo bitrotr
+       mov r21, r22
+       mov r22, r23
+       mov r23, r24
+       mov r24, r25
+       mov r25, r21
+       subi r20, 8
+       rjmp rotr32
+bitrotr:
+       clr r21
+       clc
+bitrotr_loop:  
+       tst r20
+       breq fixrotr
+       ror r25
+       ror r24
+       ror r23
+       ror r22
+       ror r21
+       dec r20
+       rjmp bitrotr_loop
+fixrotr:
+       or r25, r21
+       ret
+       
+       
+;###########################################################   
+       
+.global change_endian32
+; === change_endian32 ===
+; function that changes the endianess of a 32-bit word
+;  param1: the 32-bit word
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  modifys: r21, r22
+change_endian32:
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)
+       mov r22, r25
+       mov r23, r24
+       mov r24, r21
+       mov r25, r20 
+       ret
+
diff --git a/entropium/sha256.h b/entropium/sha256.h
new file mode 100644 (file)
index 0000000..24960a3
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialise a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automaticaly hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/grain.c b/grain.c
deleted file mode 100644 (file)
index 8d30d22..0000000
--- a/grain.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* grain.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * author: Daniel Otte
- * email:  daniel.otte@rub.de
- * license: GPLv3 or later
- * 
- */
-
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "grain.h"
-
-
-#define GRAIN_REVERSEKEY
-
-/* s0, s1, s2, ..., s78, s79 */
-#define S(i) ((ctx->lfsr[9-((i)/8)])>>(7-((i)%8)))
-/* b0, b1, b2, ..., b78, b79 */
-#define B(i) ((ctx->nfsr[9-((i)/8)])>>(7-((i)%8)))
-#define _B(i) (((ctx->nfsr[9-((i)/8)])>>(7-((i)%8)))&1)
-
-
-uint8_t h_lut[4] PROGMEM = {0x4C, 0xB6, 0xD3, 0x26};
-
-#ifdef GRAIN_BADOPTIMISATION
-uint8_t g_lut[128] PROGMEM = {
-        0xF0, 0xA5, 0x0F, 0x5A, 0x0F, 0x5A, 0xF0, 0xA5, 0x0F, 0x5A, 0xF0, 0xA5, 0xF0, 0x5A, 0x0F, 0x0F, 
-        0xC3, 0x96, 0x3C, 0x69, 0x3C, 0x69, 0xC3, 0x96, 0x9C, 0xC9, 0x63, 0x36, 0x63, 0xC9, 0x9C, 0x9C, 
-        0x0F, 0x5A, 0x0F, 0x5A, 0xF0, 0xA5, 0xF0, 0x5A, 0xF0, 0xA5, 0xF0, 0xA5, 0x0F, 0xA5, 0x0F, 0xF0, 
-        0x3C, 0x69, 0x3C, 0x69, 0xC3, 0x96, 0xC3, 0x69, 0x63, 0x36, 0x63, 0x36, 0x9C, 0x36, 0x9C, 0x63, 
-        0x0F, 0xD2, 0xF0, 0x2D, 0xF0, 0x2D, 0x0F, 0xD2, 0xF0, 0x2D, 0x0F, 0xD2, 0x0F, 0x2D, 0xF0, 0x78, 
-        0x3C, 0xE1, 0xC3, 0x1E, 0xC3, 0x1E, 0x3C, 0xE1, 0x63, 0xBE, 0x9C, 0x41, 0x9C, 0xBE, 0x63, 0xEB, 
-        0x00, 0xDD, 0x00, 0xDD, 0xFF, 0x22, 0xFF, 0xDD, 0xFF, 0x22, 0xFF, 0x22, 0x00, 0x22, 0xF0, 0x87, 
-        0xF3, 0x2E, 0xF3, 0x2E, 0x0C, 0xD1, 0x0C, 0x2E, 0xAC, 0x71, 0xAC, 0x71, 0x53, 0x71, 0xA3, 0xD4  };
-#endif
-
-uint8_t grain_enc(grain_ctx_t* ctx){
-       uint8_t s80, s0, c1, c2;
-       uint8_t i;
-       /* clock the LFSR */
-       s0=S(0);
-       s80 =S(62) ^ S(51) ^ S(38) ^ S(23) ^ S(13) ^ s0;
-       s80 &= 1;
-       c1 = s80;
-       for(i=0; i<10; ++i){
-               c2 = (ctx->lfsr[i])>>7;
-               ctx->lfsr[i] = ((ctx->lfsr[i])<<1) | c1;
-               c1 = c2;
-       }
-       /* clock the NFSR */
-       uint8_t b80;
-/*     778 Byte in this variant / 617 clks enc_time */
-#ifndef GRAIN_BADOPTIMISATION
-    uint8_t a,b,d,e;
-       b80 = B(62) ^ B(60) ^ B(52) ^ B(45) ^ 
-             B(37) ^ B(33) ^ B(28) ^ B(21) ^ 
-             B(14) ^ B( 9) ^ B( 0) ^ s0;
-       b80 ^= (a = B(63) & B(60));
-       b80 ^= (b = B(37) & B(33));
-       b80 ^= B(15) & B( 9); // c 
-       b80 ^= (d = B(60) & B(52) & B(45));
-       b80 ^= (e = B(33) & B(28) & B(21));
-       b80 ^= B(63) & B(45) & B(28) & B(9); // f 
-       /* -- */
-       b80 ^= b & B(60) & B(52); // g 
-       b80 ^= a & B(21) & B(15); // h 
-       b80 ^= d & B(63) & B(37); // i 
-       b80 ^= e & B(15) & B( 9); // j 
-       b80 ^= e & B(52) & B(45) & B(37); // k
-#else
-       /* let's reorder the bits */
-       uint16_t x; 
-
-/*
-       x  = _B(21); x<<=1;
-       x |= _B(33); x<<=1;
-       x |= _B(9) ; x<<=1;
-       x |= _B(45); x<<=1;
-       x |= _B(52); x<<=1;
-       x |= _B(37); x<<=1;
-       x |= _B(60); x<<=1;
-       x |= _B(28); x<<=1;
-       x |= _B(15); x<<=1;
-       x |= _B(63);
-*/
-       x  = ((ctx->nfsr[8])&0x41)<<1; // B15 & B09
-       x |= ((ctx->nfsr[2])&0x09);    // B63 & B60 
-//     x |= ((ctx->nfsr[4])&0x04)<<4; // B45
-       x |= (((ctx->nfsr[5])&0x44) | 
-             ((ctx->nfsr[3])&0x08) | 
-             (((((ctx->nfsr[7])&0x04)<<3) |((ctx->nfsr[4])&0x04))<<2) )<<2; // B37 & B33
-//     x |= ((ctx->nfsr[3])&0x08)<<2; // B52
-       x |= ((ctx->nfsr[6])&0x08)>>1; // B28
-//     x |= ((ctx->nfsr[7])&0x04)<<7; // B21 
-
-
-       b80 = pgm_read_byte(g_lut+(x/8))>>(x%8);
-       b80 ^= s0 ^ B(62) ^ B(14) ^ B(0);
-#endif
-       c1 = b80 & 1;
-       for(i=0; i<10; ++i){
-               c2 = (ctx->nfsr[i])>>7;
-               ctx->nfsr[i] = ((ctx->nfsr[i])<<1) | c1;
-               c1 = c2;
-       }
-       /* now the h function */
-       uint8_t h;
-       i = (S(2)&1) | 
-           ((S(24)&1) << 1) |
-           ((S(45)&1) << 2) |
-           ((S(63)&1) << 3) |
-           ((B(62)&1) << 4);
-       
-       h = (pgm_read_byte(h_lut+(i/8)))>>(i%8);
-       
-       h ^= B(0) ^ B(1) ^ B(3) ^ B(9) ^ B(30) ^ B(42) ^ B(55);
-       return h&1;
-}
-
-#ifdef GRAIN_REVERSEKEY
-
-static
-uint8_t reverse_bits(uint8_t a){
-       uint8_t lut[16] = {
-               0x0, 0x8, 0x4, 0xC,   /* 0000 1000 0100 1100 */
-               0x2, 0xA, 0x6, 0xE,   /* 0010 1010 0110 1110 */
-               0x1, 0x9, 0x5, 0xD,   /* 0001 1001 0101 1101 */
-               0x3, 0xB, 0x7, 0xF }; /* 0011 1011 0111 1111 */
-       uint8_t x;
-       x = ((lut[a&0xf]) << 4) | lut[a>>4];
-       return x;
-}
-#else
-
-#define reverse_bits(a) (a)
-
-#endif
-
-void grain_init(const void* key, const void* iv, grain_ctx_t* ctx){
-       uint8_t i,t;
-       
-       /* load the 80bit key */
-       for(i=0; i<10; ++i){
-               ctx->nfsr[9-i] = reverse_bits(((uint8_t*)key)[i]);
-       }
-       /* load the 64bit iv */
-       for(i=0; i<8; ++i){
-               ctx->lfsr[9-i] = reverse_bits(((uint8_t*)iv)[i]);
-       }
-       /* set the other bits of iv to 1 */
-       ctx->lfsr[0] = ctx->lfsr[1] = 0xFF;
-       
-       /* run it 160 times */
-       for(i=0; i<160; ++i){
-               t = grain_enc(ctx);
-               (ctx->lfsr[0]) ^= t;
-               (ctx->nfsr[0]) ^= t;
-       }
-}
-
-
-
-
-
-
diff --git a/grain.h b/grain.h
deleted file mode 100644 (file)
index 2526fdc..0000000
--- a/grain.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* grain.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/** \file grain.h
- * \author  Daniel Otte
- * \email   daniel.otte@rub.de
- * \license GPLv3 or later
- * \brief implementation of the Grain streamcipher
- */
-
-#ifndef GRAIN_H_
-#define GRAIN_H_
-
-
-#include <stdint.h>
-
-typedef struct gain_ctx_st{
-       uint8_t lfsr[10];
-       uint8_t nfsr[10];
-} grain_ctx_t;
-
-
-uint8_t grain_enc(grain_ctx_t* ctx);
-void grain_init(const void* key, const void* iv, grain_ctx_t* ctx);
-
-#endif /*GRAIN_H_*/
diff --git a/grain/grain.c b/grain/grain.c
new file mode 100644 (file)
index 0000000..8d30d22
--- /dev/null
@@ -0,0 +1,185 @@
+/* grain.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3 or later
+ * 
+ */
+
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "grain.h"
+
+
+#define GRAIN_REVERSEKEY
+
+/* s0, s1, s2, ..., s78, s79 */
+#define S(i) ((ctx->lfsr[9-((i)/8)])>>(7-((i)%8)))
+/* b0, b1, b2, ..., b78, b79 */
+#define B(i) ((ctx->nfsr[9-((i)/8)])>>(7-((i)%8)))
+#define _B(i) (((ctx->nfsr[9-((i)/8)])>>(7-((i)%8)))&1)
+
+
+uint8_t h_lut[4] PROGMEM = {0x4C, 0xB6, 0xD3, 0x26};
+
+#ifdef GRAIN_BADOPTIMISATION
+uint8_t g_lut[128] PROGMEM = {
+        0xF0, 0xA5, 0x0F, 0x5A, 0x0F, 0x5A, 0xF0, 0xA5, 0x0F, 0x5A, 0xF0, 0xA5, 0xF0, 0x5A, 0x0F, 0x0F, 
+        0xC3, 0x96, 0x3C, 0x69, 0x3C, 0x69, 0xC3, 0x96, 0x9C, 0xC9, 0x63, 0x36, 0x63, 0xC9, 0x9C, 0x9C, 
+        0x0F, 0x5A, 0x0F, 0x5A, 0xF0, 0xA5, 0xF0, 0x5A, 0xF0, 0xA5, 0xF0, 0xA5, 0x0F, 0xA5, 0x0F, 0xF0, 
+        0x3C, 0x69, 0x3C, 0x69, 0xC3, 0x96, 0xC3, 0x69, 0x63, 0x36, 0x63, 0x36, 0x9C, 0x36, 0x9C, 0x63, 
+        0x0F, 0xD2, 0xF0, 0x2D, 0xF0, 0x2D, 0x0F, 0xD2, 0xF0, 0x2D, 0x0F, 0xD2, 0x0F, 0x2D, 0xF0, 0x78, 
+        0x3C, 0xE1, 0xC3, 0x1E, 0xC3, 0x1E, 0x3C, 0xE1, 0x63, 0xBE, 0x9C, 0x41, 0x9C, 0xBE, 0x63, 0xEB, 
+        0x00, 0xDD, 0x00, 0xDD, 0xFF, 0x22, 0xFF, 0xDD, 0xFF, 0x22, 0xFF, 0x22, 0x00, 0x22, 0xF0, 0x87, 
+        0xF3, 0x2E, 0xF3, 0x2E, 0x0C, 0xD1, 0x0C, 0x2E, 0xAC, 0x71, 0xAC, 0x71, 0x53, 0x71, 0xA3, 0xD4  };
+#endif
+
+uint8_t grain_enc(grain_ctx_t* ctx){
+       uint8_t s80, s0, c1, c2;
+       uint8_t i;
+       /* clock the LFSR */
+       s0=S(0);
+       s80 =S(62) ^ S(51) ^ S(38) ^ S(23) ^ S(13) ^ s0;
+       s80 &= 1;
+       c1 = s80;
+       for(i=0; i<10; ++i){
+               c2 = (ctx->lfsr[i])>>7;
+               ctx->lfsr[i] = ((ctx->lfsr[i])<<1) | c1;
+               c1 = c2;
+       }
+       /* clock the NFSR */
+       uint8_t b80;
+/*     778 Byte in this variant / 617 clks enc_time */
+#ifndef GRAIN_BADOPTIMISATION
+    uint8_t a,b,d,e;
+       b80 = B(62) ^ B(60) ^ B(52) ^ B(45) ^ 
+             B(37) ^ B(33) ^ B(28) ^ B(21) ^ 
+             B(14) ^ B( 9) ^ B( 0) ^ s0;
+       b80 ^= (a = B(63) & B(60));
+       b80 ^= (b = B(37) & B(33));
+       b80 ^= B(15) & B( 9); // c 
+       b80 ^= (d = B(60) & B(52) & B(45));
+       b80 ^= (e = B(33) & B(28) & B(21));
+       b80 ^= B(63) & B(45) & B(28) & B(9); // f 
+       /* -- */
+       b80 ^= b & B(60) & B(52); // g 
+       b80 ^= a & B(21) & B(15); // h 
+       b80 ^= d & B(63) & B(37); // i 
+       b80 ^= e & B(15) & B( 9); // j 
+       b80 ^= e & B(52) & B(45) & B(37); // k
+#else
+       /* let's reorder the bits */
+       uint16_t x; 
+
+/*
+       x  = _B(21); x<<=1;
+       x |= _B(33); x<<=1;
+       x |= _B(9) ; x<<=1;
+       x |= _B(45); x<<=1;
+       x |= _B(52); x<<=1;
+       x |= _B(37); x<<=1;
+       x |= _B(60); x<<=1;
+       x |= _B(28); x<<=1;
+       x |= _B(15); x<<=1;
+       x |= _B(63);
+*/
+       x  = ((ctx->nfsr[8])&0x41)<<1; // B15 & B09
+       x |= ((ctx->nfsr[2])&0x09);    // B63 & B60 
+//     x |= ((ctx->nfsr[4])&0x04)<<4; // B45
+       x |= (((ctx->nfsr[5])&0x44) | 
+             ((ctx->nfsr[3])&0x08) | 
+             (((((ctx->nfsr[7])&0x04)<<3) |((ctx->nfsr[4])&0x04))<<2) )<<2; // B37 & B33
+//     x |= ((ctx->nfsr[3])&0x08)<<2; // B52
+       x |= ((ctx->nfsr[6])&0x08)>>1; // B28
+//     x |= ((ctx->nfsr[7])&0x04)<<7; // B21 
+
+
+       b80 = pgm_read_byte(g_lut+(x/8))>>(x%8);
+       b80 ^= s0 ^ B(62) ^ B(14) ^ B(0);
+#endif
+       c1 = b80 & 1;
+       for(i=0; i<10; ++i){
+               c2 = (ctx->nfsr[i])>>7;
+               ctx->nfsr[i] = ((ctx->nfsr[i])<<1) | c1;
+               c1 = c2;
+       }
+       /* now the h function */
+       uint8_t h;
+       i = (S(2)&1) | 
+           ((S(24)&1) << 1) |
+           ((S(45)&1) << 2) |
+           ((S(63)&1) << 3) |
+           ((B(62)&1) << 4);
+       
+       h = (pgm_read_byte(h_lut+(i/8)))>>(i%8);
+       
+       h ^= B(0) ^ B(1) ^ B(3) ^ B(9) ^ B(30) ^ B(42) ^ B(55);
+       return h&1;
+}
+
+#ifdef GRAIN_REVERSEKEY
+
+static
+uint8_t reverse_bits(uint8_t a){
+       uint8_t lut[16] = {
+               0x0, 0x8, 0x4, 0xC,   /* 0000 1000 0100 1100 */
+               0x2, 0xA, 0x6, 0xE,   /* 0010 1010 0110 1110 */
+               0x1, 0x9, 0x5, 0xD,   /* 0001 1001 0101 1101 */
+               0x3, 0xB, 0x7, 0xF }; /* 0011 1011 0111 1111 */
+       uint8_t x;
+       x = ((lut[a&0xf]) << 4) | lut[a>>4];
+       return x;
+}
+#else
+
+#define reverse_bits(a) (a)
+
+#endif
+
+void grain_init(const void* key, const void* iv, grain_ctx_t* ctx){
+       uint8_t i,t;
+       
+       /* load the 80bit key */
+       for(i=0; i<10; ++i){
+               ctx->nfsr[9-i] = reverse_bits(((uint8_t*)key)[i]);
+       }
+       /* load the 64bit iv */
+       for(i=0; i<8; ++i){
+               ctx->lfsr[9-i] = reverse_bits(((uint8_t*)iv)[i]);
+       }
+       /* set the other bits of iv to 1 */
+       ctx->lfsr[0] = ctx->lfsr[1] = 0xFF;
+       
+       /* run it 160 times */
+       for(i=0; i<160; ++i){
+               t = grain_enc(ctx);
+               (ctx->lfsr[0]) ^= t;
+               (ctx->nfsr[0]) ^= t;
+       }
+}
+
+
+
+
+
+
diff --git a/grain/grain.h b/grain/grain.h
new file mode 100644 (file)
index 0000000..2526fdc
--- /dev/null
@@ -0,0 +1,42 @@
+/* grain.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/** \file grain.h
+ * \author  Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \license GPLv3 or later
+ * \brief implementation of the Grain streamcipher
+ */
+
+#ifndef GRAIN_H_
+#define GRAIN_H_
+
+
+#include <stdint.h>
+
+typedef struct gain_ctx_st{
+       uint8_t lfsr[10];
+       uint8_t nfsr[10];
+} grain_ctx_t;
+
+
+uint8_t grain_enc(grain_ctx_t* ctx);
+void grain_init(const void* key, const void* iv, grain_ctx_t* ctx);
+
+#endif /*GRAIN_H_*/
diff --git a/hmac-md5.c b/hmac-md5.c
deleted file mode 100644 (file)
index d72dca9..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* hmac-md5.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * implementation of HMAC as described in RFC2104
- * Author:      Daniel Otte
- * email:       daniel.otte@rub.de
- * License:     GPLv3 or later
- **/
-
-/* 
- * hmac = hash ( k^opad , hash( k^ipad  , msg))
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "config.h"
-#include "md5.h"
-#include "hmac-md5.h"
-
-#define IPAD 0x36
-#define OPAD 0x5C
-
-#ifndef HMAC_SHORTONLY
-
-void hmac_md5_init(hmac_md5_ctx_t *s, void* key, uint16_t keylength_b){
-       uint8_t buffer[MD5_BLOCK_BYTES];
-       uint8_t i;
-       
-       memset(buffer, 0, MD5_BLOCK_BYTES);
-       if (keylength_b > MD5_BLOCK_BITS){
-               md5((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<MD5_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       md5_init(&(s->a));
-       md5_nextBlock(&(s->a), buffer);
-       
-       for (i=0; i<MD5_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD^OPAD;
-       }
-       md5_init(&(s->b));
-       md5_nextBlock(&(s->b), buffer);
-       
-#if defined SECURE_WIPE_BUFFER
-       memset(buffer, 0, MD5_BLOCK_BYTES);
-#endif
-}
-
-void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void* block){
-       md5_nextBlock(&(s->a), block);
-}
-
-void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void* block, uint16_t length_b){
-       md5_lastBlock(&(s->a), block, length_b);
-}
-
-void hmac_md5_final(void* dest, hmac_md5_ctx_t *s){
-       md5_ctx2hash((md5_hash_t*)dest, &(s->a));
-       md5_lastBlock(&(s->b), dest, MD5_HASH_BITS);
-       md5_ctx2hash((md5_hash_t*)dest, &(s->b));
-}
-
-#endif
-
-/*
-void hmac_md5_nextBlock()
-void hmac_md5_lastBlock()
-*/
-
-/*
- * keylength in bits!
- * message length in bits!
- */
-void hmac_md5(void* dest, void* key, uint16_t keylength_b, void* msg, uint32_t msglength_b){ /* a one-shot*/
-       md5_ctx_t s;
-       uint8_t i;
-       uint8_t buffer[MD5_BLOCK_BYTES];
-       
-       memset(buffer, 0, MD5_BLOCK_BYTES);
-       
-       /* if key is larger than a block we have to hash it*/
-       if (keylength_b > MD5_BLOCK_BITS){
-               md5((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<MD5_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       md5_init(&s);
-       md5_nextBlock(&s, buffer);
-       while (msglength_b >= MD5_BLOCK_BITS){
-               md5_nextBlock(&s, msg);
-               msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
-               msglength_b -=  MD5_BLOCK_BITS;
-       }
-       md5_lastBlock(&s, msg, msglength_b);
-       /* since buffer still contains key xor ipad we can do ... */
-       for (i=0; i<MD5_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD ^ OPAD;
-       }
-       md5_ctx2hash(dest, &s); /* save inner hash temporary to dest */
-       md5_init(&s);
-       md5_nextBlock(&s, buffer);
-       md5_lastBlock(&s, dest, MD5_HASH_BITS);
-       md5_ctx2hash(dest, &s);
-}
-
diff --git a/hmac-md5.h b/hmac-md5.h
deleted file mode 100644 (file)
index 5bbaeb9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* hmac-md5.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef HMACMD5_H_
-#define HMACMD5_H_
-
-#include "md5.h"
-
-#define HMAC_MD5_BITS        MD5_HASH_BITS
-#define HMAC_MD5_BYTES       MD5_HASH_BYTES
-#define HMAC_MD5_BLOCK_BITS  MD5_BLOCK_BITS
-#define HMAC_MD5_BLOCK_BYTES MD5_BLOCK_BYTES
-
-typedef struct{
-       md5_ctx_t a,b;
-} hmac_md5_ctx_t;
-
-
-void hmac_md5_init(hmac_md5_ctx_t *s, void* key, uint16_t keylength_b);
-void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void* block);
-void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void* block, uint16_t length_b);
-void hmac_md5_final(void* dest, hmac_md5_ctx_t *s);
-
-void hmac_md5(void* dest, void* key, uint16_t keylength_b, void* msg, uint32_t msglength_b);
-
-
-#endif /*HMACMD5_H_*/
diff --git a/hmac-md5/base64_dec.c b/hmac-md5/base64_dec.c
new file mode 100644 (file)
index 0000000..f057f54
--- /dev/null
@@ -0,0 +1,246 @@
+/* base64_dec.c */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * base64 decoder (RFC3548)
+ * Author: Daniel Otte
+ * License: GPLv3
+ * 
+ * 
+ */
+
+#include <stdint.h>
+#include "base64_dec.h"
+
+#include "test_src/cli.h"
+
+/*
+ #define USE_GCC_EXTENSION
+*/
+#if 1
+
+#ifdef USE_GCC_EXTENSION
+
+static
+int ascii2bit6(char a){
+       switch(a){
+               case 'A'...'Z':
+                       return a-'A';
+               case 'a'...'z':
+                       return a-'a'+26;
+               case '0'...'9':
+                       return a-'0'+52;
+               case '+':
+               case '-':
+                       return 62;
+               case '/':
+               case '_':
+                       return 63;
+               default:
+                       return -1;
+       }
+}
+
+#else
+
+static
+uint8_t ascii2bit6(char a){
+       int r;
+       switch(a>>4){
+               case 0x5:
+               case 0x4: 
+                       r=a-'A';
+                       if(r<0 || r>25){
+                               return -1;
+                       } else {
+                               return r;
+                       }
+               case 0x7:
+               case 0x6: 
+                       r=a-'a';
+                       if(r<0 || r>25){
+                               return -1;
+                       } else {
+                               return r+26;
+                       }
+                       break;
+               case 0x3:
+                       if(a>'9')
+                               return -1;
+                       return a-'0'+52;
+               default:
+                       break;  
+       }
+       switch (a){
+               case '+':
+               case '-':
+                       return 62;
+               case '/':
+               case '_':
+                       return 63;
+               default:
+                       return 0xff;
+       }
+}
+
+#endif
+
+#else
+
+static 
+uint8_t ascii2bit6(uint8_t a){
+       if(a>='A' && a<='Z'){
+               return a-'A';
+       } else {
+               if(a>='a' && a<= 'z'){
+                       return a-'a'+26;
+               } else {
+                       if(a>='0' && a<='9'){
+                               return a-'0'+52;
+                       } else {
+                               if(a=='+' || a=='-'){
+                                       return 62;
+                               } else {
+                                       if(a=='/' || a=='_'){
+                                               return 63;
+                                       } else {
+                                               return 0xff;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+#endif
+
+int base64_binlength(char* str, uint8_t strict){
+       int l=0;
+       uint8_t term=0;
+       for(;;){
+               if(*str=='\0')
+                       break;
+               if(*str=='\n' || *str=='\r'){
+                       str++;
+                       continue;
+               }
+               if(*str=='='){
+                       term++;
+                       str++;
+                       if(term==2){
+                               break;
+                       }
+                       continue;
+               }
+               if(term)
+                       return -1;
+               if(ascii2bit6(*str)==-1){
+                       if(strict)
+                               return -1;
+               } else {
+                       l++;
+               }
+               str++;
+       }
+       switch(term){
+               case 0:
+                       if(l%4!=0)
+                               return -1;
+                       return l/4*3;
+               case 1:
+                       if(l%4!=3)
+                               return -1;
+                       return (l+1)/4*3-1;
+               case 2:
+                       if(l%4!=2)
+                               return -1;
+                       return (l+2)/4*3-2;
+               default:
+                       return -1;
+       }
+}
+
+/*
+  |543210543210543210543210|
+  |765432107654321076543210|
+
+        .      .      .     .
+  |54321054|32105432|10543210|
+  |76543210|76543210|76543210|
+
+*/
+
+int base64dec(void* dest, char* b64str, uint8_t strict){
+       uint8_t buffer[4];
+       uint8_t idx=0;
+       uint8_t term=0;
+       for(;;){
+//             cli_putstr_P(PSTR("\r\n  DBG: got 0x"));
+//             cli_hexdump(b64str, 1);
+               buffer[idx]= ascii2bit6(*b64str);
+//             cli_putstr_P(PSTR(" --> 0x"));
+//             cli_hexdump(buffer+idx, 1);
+               
+               if(buffer[idx]==0xFF){
+                       if(*b64str=='='){
+                               term++;
+                               b64str++;
+                               if(term==2)
+                                       goto finalize; /* definitly the end */
+                       }else{
+                               if(*b64str == '\0'){
+                                       goto finalize; /* definitly the end */
+                               }else{
+                                       if(*b64str == '\r' || *b64str == '\n' || !(strict)){
+                                               b64str++; /* charcters that we simply ignore */
+                                       }else{
+                                               return -1;
+                                       }
+                               }
+                       }
+               }else{
+                       if(term)
+                               return -1; /* this happens if we get a '=' in the stream */
+                       idx++;
+                       b64str++;
+               }
+               if(idx==4){
+                       ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+                       ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;
+                       ((uint8_t*)dest)[2] = buffer[2]<<6 | buffer[3];
+                       dest = (uint8_t*)dest +3;
+                       idx=0;
+               }
+       }
+  finalize:    
+       /* the final touch */
+       if(idx==0)
+               return 0;
+       if(term==1){
+               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+               ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;                      
+               return 0;
+       }
+       if(term==2){
+               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
+               return 0;
+       }
+       return -1;
+}
diff --git a/hmac-md5/base64_dec.h b/hmac-md5/base64_dec.h
new file mode 100644 (file)
index 0000000..39beff8
--- /dev/null
@@ -0,0 +1,29 @@
+/* base64_dec.h */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef BASE64_DEC_H_
+#define BASE64_DEC_H_
+
+#include <stdint.h>
+
+int base64_binlength(char* str, uint8_t strict);
+int base64dec(void* dest, char* b64str, uint8_t strict);
+
+#endif /*BASE64_DEC_H_*/
diff --git a/hmac-md5/base64_enc.c b/hmac-md5/base64_enc.c
new file mode 100644 (file)
index 0000000..400f25c
--- /dev/null
@@ -0,0 +1,117 @@
+/* base64_enc.c */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * base64 encoder (RFC3548)
+ * Author: Daniel Otte
+ * License: GPLv3
+ * 
+ * 
+ */
+
+#include <stdint.h>
+#include "base64_enc.h"
+
+#if 1
+#include <avr/pgmspace.h>
+
+char base64_alphabet[64] PROGMEM = {
+       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
+       'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
+       'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 
+       'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 
+       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
+       'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 
+       'w', 'x', 'y', 'z', '0', '1', '2', '3', 
+       '4', '5', '6', '7', '8', '9', '+', '/' }; 
+
+static 
+char bit6toAscii(uint8_t a){
+       a &= (uint8_t)0x3F;
+       return pgm_read_byte(base64_alphabet+a);
+}
+
+#else
+
+static 
+char bit6toAscii(uint8_t a){
+       a &= (uint8_t)0x3F;
+       
+       if(a<=25){
+               return a+'A';
+       } else {
+               if(a<=51){
+                       return a-26+'a';
+               } else {
+                       if(a<=61){
+                               return a-52+'0';
+                       } else {
+                               if(a==62){
+                                       return '+';
+                               } else {
+                                       return '/'; /* a == 63 */
+                               }
+                       }
+               }
+       }
+}
+
+#endif
+
+void base64enc(char* dest, void* src, uint16_t length){
+       uint16_t i,j;
+       uint8_t a[4];
+       for(i=0; i<length/3; ++i){
+               a[0]= (((uint8_t*)src)[i*3+0])>>2;
+               a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
+               a[2]= (((((uint8_t*)src)[i*3+1])<<2) | ((((uint8_t*)src)[i*3+2])>>6)) & 0x3F;
+               a[3]= (((uint8_t*)src)[i*3+2]) & 0x3F;
+               for(j=0; j<4; ++j){
+                       *dest++=bit6toAscii(a[j]);
+               }
+       }
+       /* now we do the rest */
+       switch(length%3){
+               case 0: 
+                       break;
+               case 1:
+                       a[0]=(((uint8_t*)src)[i*3+0])>>2;
+                       a[1]=((((uint8_t*)src)[i*3+0])<<4)&0x3F;
+                       *dest++ = bit6toAscii(a[0]);
+                       *dest++ = bit6toAscii(a[1]);
+                       *dest++ = '=';
+                       *dest++ = '=';
+                       break;
+               case 2:         
+                       a[0]= (((uint8_t*)src)[i*3+0])>>2;
+                       a[1]= (((((uint8_t*)src)[i*3+0])<<4) | ((((uint8_t*)src)[i*3+1])>>4)) & 0x3F;
+                       a[2]= ((((uint8_t*)src)[i*3+1])<<2) & 0x3F;
+                       *dest++ = bit6toAscii(a[0]);
+                       *dest++ = bit6toAscii(a[1]);
+                       *dest++ = bit6toAscii(a[2]);
+                       *dest++ = '=';
+                       break;
+               default: /* this will not happen! */
+                       break;  
+       }
+/*  finalize: */
+       *dest='\0';
+}
+
diff --git a/hmac-md5/base64_enc.h b/hmac-md5/base64_enc.h
new file mode 100644 (file)
index 0000000..9065132
--- /dev/null
@@ -0,0 +1,28 @@
+/* base64_enc.h */
+/*
+ *   This file is part of the AVR-Crypto-Lib.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef BASE64_ENC_H_
+#define BASE64_ENC_H_
+
+#include <stdint.h>
+
+void base64enc(char* dest, void* src, uint16_t length);
+
+#endif /*BASE64_ENC_H_*/
diff --git a/hmac-md5/hmac-md5.c b/hmac-md5/hmac-md5.c
new file mode 100644 (file)
index 0000000..d72dca9
--- /dev/null
@@ -0,0 +1,130 @@
+/* hmac-md5.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * implementation of HMAC as described in RFC2104
+ * Author:      Daniel Otte
+ * email:       daniel.otte@rub.de
+ * License:     GPLv3 or later
+ **/
+
+/* 
+ * hmac = hash ( k^opad , hash( k^ipad  , msg))
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "config.h"
+#include "md5.h"
+#include "hmac-md5.h"
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+#ifndef HMAC_SHORTONLY
+
+void hmac_md5_init(hmac_md5_ctx_t *s, void* key, uint16_t keylength_b){
+       uint8_t buffer[MD5_BLOCK_BYTES];
+       uint8_t i;
+       
+       memset(buffer, 0, MD5_BLOCK_BYTES);
+       if (keylength_b > MD5_BLOCK_BITS){
+               md5((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<MD5_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       md5_init(&(s->a));
+       md5_nextBlock(&(s->a), buffer);
+       
+       for (i=0; i<MD5_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD^OPAD;
+       }
+       md5_init(&(s->b));
+       md5_nextBlock(&(s->b), buffer);
+       
+#if defined SECURE_WIPE_BUFFER
+       memset(buffer, 0, MD5_BLOCK_BYTES);
+#endif
+}
+
+void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void* block){
+       md5_nextBlock(&(s->a), block);
+}
+
+void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void* block, uint16_t length_b){
+       md5_lastBlock(&(s->a), block, length_b);
+}
+
+void hmac_md5_final(void* dest, hmac_md5_ctx_t *s){
+       md5_ctx2hash((md5_hash_t*)dest, &(s->a));
+       md5_lastBlock(&(s->b), dest, MD5_HASH_BITS);
+       md5_ctx2hash((md5_hash_t*)dest, &(s->b));
+}
+
+#endif
+
+/*
+void hmac_md5_nextBlock()
+void hmac_md5_lastBlock()
+*/
+
+/*
+ * keylength in bits!
+ * message length in bits!
+ */
+void hmac_md5(void* dest, void* key, uint16_t keylength_b, void* msg, uint32_t msglength_b){ /* a one-shot*/
+       md5_ctx_t s;
+       uint8_t i;
+       uint8_t buffer[MD5_BLOCK_BYTES];
+       
+       memset(buffer, 0, MD5_BLOCK_BYTES);
+       
+       /* if key is larger than a block we have to hash it*/
+       if (keylength_b > MD5_BLOCK_BITS){
+               md5((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<MD5_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       md5_init(&s);
+       md5_nextBlock(&s, buffer);
+       while (msglength_b >= MD5_BLOCK_BITS){
+               md5_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
+               msglength_b -=  MD5_BLOCK_BITS;
+       }
+       md5_lastBlock(&s, msg, msglength_b);
+       /* since buffer still contains key xor ipad we can do ... */
+       for (i=0; i<MD5_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD ^ OPAD;
+       }
+       md5_ctx2hash(dest, &s); /* save inner hash temporary to dest */
+       md5_init(&s);
+       md5_nextBlock(&s, buffer);
+       md5_lastBlock(&s, dest, MD5_HASH_BITS);
+       md5_ctx2hash(dest, &s);
+}
+
diff --git a/hmac-md5/hmac-md5.h b/hmac-md5/hmac-md5.h
new file mode 100644 (file)
index 0000000..5bbaeb9
--- /dev/null
@@ -0,0 +1,42 @@
+/* hmac-md5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef HMACMD5_H_
+#define HMACMD5_H_
+
+#include "md5.h"
+
+#define HMAC_MD5_BITS        MD5_HASH_BITS
+#define HMAC_MD5_BYTES       MD5_HASH_BYTES
+#define HMAC_MD5_BLOCK_BITS  MD5_BLOCK_BITS
+#define HMAC_MD5_BLOCK_BYTES MD5_BLOCK_BYTES
+
+typedef struct{
+       md5_ctx_t a,b;
+} hmac_md5_ctx_t;
+
+
+void hmac_md5_init(hmac_md5_ctx_t *s, void* key, uint16_t keylength_b);
+void hmac_md5_nextBlock(hmac_md5_ctx_t *s, const void* block);
+void hmac_md5_lastBlock(hmac_md5_ctx_t *s, const void* block, uint16_t length_b);
+void hmac_md5_final(void* dest, hmac_md5_ctx_t *s);
+
+void hmac_md5(void* dest, void* key, uint16_t keylength_b, void* msg, uint32_t msglength_b);
+
+
+#endif /*HMACMD5_H_*/
diff --git a/hmac-md5/md5-asm.S b/hmac-md5/md5-asm.S
new file mode 100644 (file)
index 0000000..de3b170
--- /dev/null
@@ -0,0 +1,977 @@
+/* md5-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:  Daniel Otte
+ * License: GPLv3 or later
+ * Date:    2008-11-15
+*/
+
+
+#include "avr-asm-macros.S"
+
+;###########################################################   
+; S-BOX
+
+T_table:
+.hword 0xa478, 0xd76a, 0xb756, 0xe8c7, 0x70db, 0x2420, 0xceee, 0xc1bd, 0x0faf, 0xf57c 
+.hword 0xc62a, 0x4787, 0x4613, 0xa830, 0x9501, 0xfd46, 0x98d8, 0x6980, 0xf7af, 0x8b44 
+.hword 0x5bb1, 0xffff, 0xd7be, 0x895c, 0x1122, 0x6b90, 0x7193, 0xfd98, 0x438e, 0xa679 
+.hword 0x0821, 0x49b4, 0x2562, 0xf61e, 0xb340, 0xc040, 0x5a51, 0x265e, 0xc7aa, 0xe9b6 
+.hword 0x105d, 0xd62f, 0x1453, 0x0244, 0xe681, 0xd8a1, 0xfbc8, 0xe7d3, 0xcde6, 0x21e1 
+.hword 0x07d6, 0xc337, 0x0d87, 0xf4d5, 0x14ed, 0x455a, 0xe905, 0xa9e3, 0xa3f8, 0xfcef 
+.hword 0x02d9, 0x676f, 0x4c8a, 0x8d2a, 0x3942, 0xfffa, 0xf681, 0x8771, 0x6122, 0x6d9d 
+.hword 0x380c, 0xfde5, 0xea44, 0xa4be, 0xcfa9, 0x4bde, 0x4b60, 0xf6bb, 0xbc70, 0xbebf 
+.hword 0x7ec6, 0x289b, 0x27fa, 0xeaa1, 0x3085, 0xd4ef, 0x1d05, 0x0488, 0xd039, 0xd9d4 
+.hword 0x99e5, 0xe6db, 0x7cf8, 0x1fa2, 0x5665, 0xc4ac, 0x2244, 0xf429, 0xff97, 0x432a 
+.hword 0x23a7, 0xab94, 0xa039, 0xfc93, 0x59c3, 0x655b, 0xcc92, 0x8f0c, 0xf47d, 0xffef 
+.hword 0x5dd1, 0x8584, 0x7e4f, 0x6fa8, 0xe6e0, 0xfe2c, 0x4314, 0xa301, 0x11a1, 0x4e08 
+.hword 0x7e82, 0xf753, 0xf235, 0xbd3a, 0xd2bb, 0x2ad7, 0xd391, 0xeb86
+
+
+#define MD5_init_fast
+
+.global md5_init 
+#ifndef MD5_init_fast
+;###########################################################   
+;void md5_init(md5_ctx_t *state)
+; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), X(r25,r26)
+; size = 9+5*4 WORDS = 29 WORDS = 58 Bytes
+md5_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8(md5_init_vector)
+       ldi r31, hi8(md5_init_vector)
+       ldi r24, 16+4
+md5_init_vloop:        
+       lpm r0, Z+ 
+       st X+, r0
+       dec r24
+       brne md5_init_vloop
+       ret
+       
+md5_init_vector:
+.hword 0x2301, 0x6745
+.hword 0xAB89, 0xEFCD 
+.hword 0xDCFE, 0x98BA 
+.hword 0x5476, 0x1032 
+.hword 0x0000, 0x0000
+
+#else
+;###########################################################   
+.global md5_init_fast 
+;void md5_init(md5_ctx_t *state)
+; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: r23, r22
+; cycles = 1+16*3+4*2+4 = 1+48+12 = 61
+; size = 1+16*2+4+1 WORDS = 38 WORDS = 76 Bytes
+md5_init:
+md5_init_fast:
+       movw r26, r24
+       ldi r24, 0x01
+       st X+, r24
+       ldi r24, 0x23
+       st X+, r24
+       ldi r24, 0x45
+       st X+, r24
+       ldi r24, 0x67
+       st X+, r24
+       ldi r24, 0x89
+       st X+, r24
+       ldi r24, 0xAB
+       st X+, r24
+       ldi r24, 0xCD
+       st X+, r24
+       ldi r24, 0xEF
+       st X+, r24
+       ldi r24, 0xFE
+       st X+, r24
+       ldi r24, 0xDC
+       st X+, r24
+       ldi r24, 0xBA
+       st X+, r24
+       ldi r24, 0x98
+       st X+, r24
+       ldi r24, 0x76
+       st X+, r24
+       ldi r24, 0x54
+       st X+, r24
+       ldi r24, 0x32
+       st X+, r24
+       ldi r24, 0x10
+       st X+, r24
+       st X+, r1
+       st X+, r1
+       st X+, r1
+       st X+, r1
+       ret
+#endif
+;###########################################################   
+
+/*
+static 
+uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)|((~x)&z));
+}
+*/
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_F:
+       and r18, r22
+       and r19, r23
+       and r20, r24
+       and r21, r25
+       com r22
+       com r23
+       com r24
+       com r25
+       and r22, r14
+       and r23, r15
+       and r24, r16
+       and r25, r17
+       or  r22, r18
+       or  r23, r19
+       or  r24, r20
+       or  r25, r21
+       rjmp md5_core_F_exit
+       
+/*
+static
+uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&z)|((~z)&y));
+}
+*/
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_G:
+       and r22, r14
+       and r23, r15
+       and r24, r16
+       and r25, r17
+       com r14
+       com r15
+       com r16
+       com r17
+       and r18, r14
+       and r19, r15
+       and r20, r16
+       and r21, r17
+       or  r22, r18
+       or  r23, r19
+       or  r24, r20
+       or  r25, r21
+       rjmp md5_core_F_exit
+/*
+static
+uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
+       return (x^y^z);
+}
+*/
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_H:
+       eor r22, r18
+       eor r22, r14
+       eor r23, r19
+       eor r23, r15
+       eor r24, r20
+       eor r24, r16
+       eor r25, r21
+       eor r25, r17
+       rjmp md5_core_F_exit
+/*
+static
+uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
+       return (y ^ (x | (~z)));
+}
+*/
+
+jump_table:
+       rjmp md5_F
+       rjmp md5_G
+       rjmp md5_H
+;      rjmp md5_I
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_I:
+       com r14
+       com r15
+       com r16
+       com r17
+       or  r22, r14
+       or  r23, r15
+       or  r24, r16
+       or  r25, r17
+       eor r22, r18
+       eor r23, r19
+       eor r24, r20
+       eor r25, r21
+       rjmp md5_core_F_exit
+
+as_table:
+;     (as+0)&3  (as+3)&3  (as+1)&3  (as+2)&3
+;                  Z         X         Y
+;     AS_SAVE0  AS_SAVE1  AS_SAVE2  AS_SAVE3 
+.byte   1*4,      0*4,      2*4,      3*4    ;as=1
+.byte   2*4,      1*4,      3*4,      0*4    ;as=2
+.byte   3*4,      2*4,      0*4,      1*4    ;as=3
+.byte   0*4,      3*4,      1*4,      2*4    ;as=4
+
+;###########################################################   
+.global md5_core
+md5_core:
+       mov r21, r20
+       mov r20, r18
+       mov r19, r16
+       mov r18, r14
+;      rjmp md5_core_asm
+/*
+void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
+       uint32_t t;
+       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
+       as &= 0x3;
+       / * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). * /
+       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) + *((uint32_t*)block) + md5_T[i] ;
+       a[as]=a[(as+1)&3] + ROTL32(t, s);
+}
+*/
+; a:     r24-r25
+; block: r22-r23
+; as:    r21
+; s:     r20
+; i:     r19
+; fi:    r18
+P_A0 = 24
+P_A1 = 25
+P_B0 = 22
+P_B1 = 23
+P_AS = 21
+P_S  = 20
+P_I  = 19
+P_FI = 18
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+
+
+AS_SAVE0  =  4
+AS_SAVE1  =  5
+AS_SAVE2  =  6
+AS_SAVE3  =  7
+FI_SAVE   =  8
+S_SAVE    =  9
+ACCU0     = 10
+ACCU1     = 11
+ACCU2     = 12
+ACCU3     = 13
+ARG_X0    = 22
+ARG_X1    = 23
+ARG_X2    = 24
+ARG_X3    = 25
+ARG_Y0    = 18
+ARG_Y1    = 19
+ARG_Y2    = 20
+ARG_Y3    = 21
+ARG_Z0    = 14
+ARG_Z1    = 15
+ARG_Z2    = 16
+ARG_Z3    = 17
+
+
+md5_core_asm:
+       push r16
+       push r17
+       push_range 4, 8
+       ldi r30, lo8(T_table)
+       ldi r31, hi8(T_table)
+       lsl P_I
+       rol r1
+       lsl P_I
+       rol r1
+       add r30, P_I
+       adc r31, r1
+       clr r1
+       mov FI_SAVE, r18
+       /* loading T[i] into ACCU */    
+       lpm ACCU0, Z+   
+       lpm ACCU1, Z+   
+       lpm ACCU2, Z+   
+       lpm ACCU3, Z
+       /* add *block to ACCU */
+       movw r30, P_B0
+       ld r0, Z+
+       add ACCU0, r0
+       ld r0, Z+
+       adc ACCU1, r0
+       ld r0, Z+
+       adc ACCU2, r0
+       ld r0, Z+
+       adc ACCU3, r0
+       /* add a[as+0&3] to ACCU */
+       ldi r30, lo8(as_table)
+       ldi r31, hi8(as_table)
+       dec P_AS
+       andi P_AS, 0x03
+       lsl P_AS
+       lsl P_AS
+       add r30, r21
+       adc r31, r1       ; Z points to the correct row in as_table
+       lpm AS_SAVE0, Z+
+       lpm AS_SAVE1, Z+
+       lpm AS_SAVE2, Z+
+       lpm AS_SAVE3, Z
+       movw r26, r24     ; X points to a[0]
+       add r26, AS_SAVE0
+       adc r27, r1       ; X points at a[as&3]
+       ld r0, X+
+       add ACCU0, r0
+       ld r0, X+
+       adc ACCU1, r0
+       ld r0, X+
+       adc ACCU2, r0
+       ld r0, X+
+       adc ACCU3, r0
+       mov S_SAVE, r20
+
+       movw r28, r24
+       /* loading z value */
+       movw r26, r28
+       add r26, AS_SAVE1
+       adc r27, r1
+       ld ARG_Z0, X+
+       ld ARG_Z1, X+
+       ld ARG_Z2, X+
+       ld ARG_Z3, X
+
+       /* loading x value */
+       movw r26, r28   
+       add r26, AS_SAVE2
+       adc r27, r1
+       ld ARG_X0, X+
+       ld ARG_X1, X+
+       ld ARG_X2, X+
+       ld ARG_X3, X
+
+       /* loading y value */
+       movw r26, r28
+       add r26, AS_SAVE3
+       adc r27, r1
+       ldi r30, pm_lo8(jump_table)
+       ldi r31, pm_hi8(jump_table)
+       add r30, FI_SAVE
+       adc r31, r1    ; Z points to the correct entry in our jump table
+       ld ARG_Y0, X+
+       ld ARG_Y1, X+
+       ld ARG_Y2, X+
+       ld ARG_Y3, X
+
+       ijmp /* calls the function pointed by Z */
+md5_core_F_exit:               
+
+       /* add ACCU to result of f() */
+       add r22, ACCU0
+       adc r23, ACCU1
+       adc r24, ACCU2
+       adc r25, ACCU3
+
+       /* rotate */
+       mov r20, S_SAVE
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       mov r21, r25
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+bitrotl_loop2: 
+       lsl r21
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       dec r20
+       brne bitrotl_loop2
+fixrotl:
+
+       /* add a[(as+1)&3]  */
+       movw r26, r28
+       add r26, AS_SAVE2
+       adc r27, r1
+       ld r0, X+
+       add r22, r0
+       ld r0, X+
+       adc r23, r0
+       ld r0, X+
+       adc r24, r0
+       ld r0, X
+       adc r25, r0
+
+       /* store result */
+       movw r26, r28
+       add r26, AS_SAVE0
+       adc r27, r1
+       st X+, r22
+       st X+, r23
+       st X+, r24
+       st X , r25      
+md5_core_exit:
+       pop_range 4, 8
+       pop r17
+       pop r16
+       ret
+
+;###################################################################
+/*
+void md5_nextBlock(md5_ctx_t *state, void* block){
+       uint32_t        a[4];
+       uint8_t         m,n,i=0;
+
+       a[0]=state->a[0];
+       a[1]=state->a[1];
+       a[2]=state->a[2];
+       a[3]=state->a[3];
+       
+       / * round 1 * /
+       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
+               }
+       }
+       / * round 2 * /
+       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
+               }
+       }
+       / * round 3 * /
+       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
+               }
+       }
+       / * round 4 * /
+       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
+               }
+       }
+       state->a[0] += a[0];
+       state->a[1] += a[1];
+       state->a[2] += a[2];
+       state->a[3] += a[3];
+       state->counter++;
+}
+*/
+
+shift_table_1:  .byte  7,12,17,22
+shift_table_2:  .byte  5, 9,14,20
+shift_table_3:  .byte  4,11,16,23
+shift_table_4:  .byte  6,10,15,21
+
+index_table_r2:
+;(1+m*4+n*5)&0xf:
+        .byte 0x04, 0x18, 0x2c, 0x00 
+        .byte 0x14, 0x28, 0x3c, 0x10 
+        .byte 0x24, 0x38, 0x0c, 0x20 
+        .byte 0x34, 0x08, 0x1c, 0x30 
+
+index_table_r3:
+;(5-m*4+n*3)&0xf:
+        .byte 0x14, 0x20, 0x2c, 0x38 
+        .byte 0x04, 0x10, 0x1c, 0x28 
+        .byte 0x34, 0x00, 0x0c, 0x18 
+        .byte 0x24, 0x30, 0x3c, 0x08 
+
+index_table_r4:
+;(0-m*4+n*7)&0xf:
+        .byte 0x00, 0x1c, 0x38, 0x14 
+        .byte 0x30, 0x0c, 0x28, 0x04 
+        .byte 0x20, 0x3c, 0x18, 0x34 
+        .byte 0x10, 0x2c, 0x08, 0x24
+
+APTR_REG = 2
+BPTR_REG = 4
+N_REG = 6
+M_REG = 7
+I_REG = 8
+.global md5_nextBlock
+md5_nextBlock:
+       stack_alloc 16
+       push_range 2, 17
+       push r28
+       push r29
+       push r24
+       push r25
+       adiw r30, 1 /* Z now points to the beginning of the allocated memory */
+       movw r2, r30
+       movw r4, r22
+       movw r26, r24
+       ldi r20, 16
+1:
+       ld r0, X+
+       st Z+, r0
+       dec r20
+       brne 1b
+       /* state now copied to stack memory */
+       clr I_REG       
+       /* Round 1 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       lsl r0
+       lsl r0
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_1)
+       ldi r31, hi8(shift_table_1)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 0
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+       
+       /* Round 2 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r2)
+       ldi r31, hi8(index_table_r2)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_2)
+       ldi r31, hi8(shift_table_2)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 1
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+       /* Round 3 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r3)
+       ldi r31, hi8(index_table_r3)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_3)
+       ldi r31, hi8(shift_table_3)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 2
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+       /* Round 4 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r4)
+       ldi r31, hi8(index_table_r4)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_4)
+       ldi r31, hi8(shift_table_4)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 3
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+
+       pop r27
+       pop r26 /* X now points to the context */
+       movw r30, APTR_REG
+       ldi r16, 4
+1:
+       ld r0, X
+       ld r2, Z+
+       add r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       dec r16
+       brne 1b
+
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f 
+       ld r0, X
+       inc r0
+       st X+, r0       
+2:                     
+
+       pop r29
+       pop r28
+       pop_range 2, 17
+       stack_free 16
+       ret
+
+;###############################################################################
+/*
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
+       uint16_t l;
+       uint8_t b[64];
+       while (length_b >= 512){
+               md5_nextBlock(state, block);
+               length_b -= 512;
+               block = ((uint8_t*)block) + 512/8;
+       }
+       memset(b, 0, 64);
+       memcpy(b, block, length_b/8);
+       / * insert padding one * /
+       l=length_b/8;
+       if(length_b%8){
+               uint8_t t;
+               t = ((uint8_t*)block)[l];
+               t |= (0x80>>(length_b%8));
+               b[l]=t;
+       }else{
+               b[l]=0x80;
+       }
+       / * insert length value * /
+       if(l+sizeof(uint64_t) >= 512/8){
+               md5_nextBlock(state, b);
+               state->counter--;
+               memset(b, 0, 64-8);
+       }
+       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
+       md5_nextBlock(state, b);
+}
+*/
+; state_ptr : r24,r25
+; block_ptr : r22,r23
+; length_b  : r20,r21
+.global md5_lastBlock
+md5_lastBlock:
+       stack_alloc_large 64
+       push_range 12, 17
+       push r30
+       push r31
+       movw r16, r20 /* length_b  */ 
+       movw r14, r22 /* block_ptr */
+       movw r12, r24 /* state_ptr */
+       ldi r18, 64
+2:
+       cpi r17, 2 /* hi8(512) */       
+       brlo 2f
+1:
+       movw r24, r12
+       movw r22, r14
+       rcall md5_nextBlock
+       add r14, r18
+       adc r15, r1
+       subi r17, 2
+       rjmp 2b
+2:
+       pop r31
+       pop r30
+
+       adiw r30, 1 /* adjust Z to point to buffer */
+       movw r26, r14
+       movw r24, r16
+       adiw r24, 7
+
+       lsr r25
+       ror r24
+       lsr r25
+       ror r24
+       lsr r24 /* r24 now holds how many bytes are to copy */
+    ldi r18, 64
+       sub r18, r24 /* r18 will hold the amount of used bytes in buffer */
+       tst r24
+4:
+       breq 5f
+       ld r0, X+
+       st Z+, r0 
+       dec r24
+       rjmp 4b /* Z points to the byte after msg in buffer */
+5:     /* append 1-bit */
+       mov r20, r16
+       ldi r19, 0x80
+       andi r20, 0x07
+       brne bit_fucking
+       st Z+, r19
+       dec r18 /* 'allocate' another byte in buffer */
+       rjmp after_bit_fucking
+bit_fucking:
+1:
+       lsr r19
+       dec r20
+       brne 1b
+       or r0, r19
+       st -Z, r0
+    adiw r30, 1
+after_bit_fucking:
+       clt     
+       cpi r18, 8
+       brmi 2f
+       set         /* store in t if the counter will also fit in this block (1 if fit)*/
+2:
+       tst r18
+       breq 2f
+1: /* fill remaning buffer with zeros */
+       st Z+, r1
+       dec r18
+       brne 1b
+2:
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r14, r30 /* r14:r15 now points to buffer */        
+       brts load_counter
+       /* counter does not fit, finalize this block */
+       movw r24, r12
+       movw r22, r14
+       rcall md5_nextBlock
+       movw r30, r14
+       ldi r20, 64-8
+3:
+       st Z+, r1
+       dec r20
+       brne 3b
+       
+load_counter:          
+       movw r26, r12 /* X points to state */
+       adiw r26, 16
+       ld r19, X+
+       ld r20, X+
+       ld r21, X+
+       ld r22, X+
+       brts post_counter_decrement     /* do not decremen because counter fits */
+counter_decrement:
+       subi r19, 1
+       sbci r20, 0
+       sbci r21, 0
+       sbci r22, 0
+post_counter_decrement:
+       clr r18
+       clr r23
+       lsl r19
+       rol r20
+       rol r21
+       rol r22
+       rol r23
+       mov r18, r16 /* r16:r17 length_b */
+       add r19, r17
+       adc r20, r1
+       adc r21, r1
+       adc r22, r1
+       adc r23, r1
+       movw r30, r14
+       adiw r30, 64-8
+       st Z+, r18
+       st Z+, r19
+       st Z+, r20
+       st Z+, r21
+       st Z+, r22
+       st Z+, r23
+       st Z+, r1
+       st Z, r1
+
+       sbiw r30, 63
+;      sbiw r30, 1
+       movw r24, r12
+       movw r22, r30
+       rcall md5_nextBlock
+md5_lastBlock_exit:    
+       pop_range 12, 17
+       stack_free_large 64
+       ret
+
+
+;###############################################################################
+
+
+.global md5_ctx2hash
+md5_ctx2hash:
+       movw r26, r24
+       movw r30, r22
+       ldi r22, 16
+1:
+       ld r0, Z+
+       st X+, r0
+       dec r22
+       brne 1b 
+       ret
+
+
+;###############################################################################
+
+
+.global md5
+md5:
+       stack_alloc 20
+       push_range  8, 17
+       adiw r30, 1
+       movw  r8, r30 /* ctx           */
+       movw r10, r24 /* dest          */
+       movw r12, r22 /* msg           */
+       movw r14, r18 /* length (low)  */
+       movw r16, r20 /* length (high) */
+       movw r24, r30
+       rcall md5_init
+1:
+       tst r16
+       brne next_round
+       tst r17
+       breq last_round
+next_round:
+       movw r24,  r8
+       movw r22, r12
+       rcall md5_nextBlock
+       ldi r22, 64
+       add r12, r22
+       adc r13, r1
+       ldi r22, 2
+       sub r15, r22
+       sbci r16, 0
+       sbci r17, 0
+       rjmp 1b
+last_round:            
+       movw r24, r8
+       movw r22, r12
+       movw r20, r14
+       rcall md5_lastBlock
+       movw r24, r10
+       movw r22,  r8
+       rcall md5_ctx2hash
+       pop_range  8, 17
+       stack_free 20
+       ret
+
+
+
diff --git a/hmac-md5/md5.h b/hmac-md5/md5.h
new file mode 100644 (file)
index 0000000..6b65c4a
--- /dev/null
@@ -0,0 +1,55 @@
+/* md5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * 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_
+
+#include <stdint.h>
+
+
+#define MD5_HASH_BITS  128
+#define MD5_HASH_BYTES (MD5_HASH_BITS/8)
+#define MD5_BLOCK_BITS 512
+#define MD5_BLOCK_BYTES (MD5_BLOCK_BITS/8)
+
+
+typedef struct md5_ctx_st {
+       uint32_t a[4];
+       uint32_t counter;
+} md5_ctx_t;
+
+typedef uint8_t md5_hash_t[MD5_HASH_BYTES];
+
+void md5_init(md5_ctx_t *s);
+void md5_nextBlock(md5_ctx_t *state, const void* block);
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length);
+void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state);
+void md5(md5_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*MD5_H_*/
diff --git a/hmac-sha1.c b/hmac-sha1.c
deleted file mode 100644 (file)
index 56d90ac..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* hmac-sha1.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * implementation of HMAC as described in RFC2104
- * Author:      Daniel Otte
- * email:       daniel.otte@rub.de
- * License:     GPLv3 or later
- **/
-
-/* 
- * hmac = hash ( k^opad , hash( k^ipad  , msg))
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "config.h"
-#include "sha1.h"
-#include "hmac-sha1.h"
-
-#define IPAD 0x36
-#define OPAD 0x5C
-
-
-#ifndef HMAC_SHORTONLY
-
-void hmac_sha1_init(hmac_sha1_ctx_t *s, const void* key, uint16_t keylength_b){
-       uint8_t buffer[SHA1_BLOCK_BYTES];
-       uint8_t i;
-       
-       memset(buffer, 0, SHA1_BLOCK_BYTES);
-       if (keylength_b > SHA1_BLOCK_BITS){
-               sha1((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       sha1_init(&(s->a));
-       sha1_nextBlock(&(s->a), buffer);
-       
-       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD^OPAD;
-       }
-       sha1_init(&(s->b));
-       sha1_nextBlock(&(s->b), buffer);
-       
-       
-#if defined SECURE_WIPE_BUFFER
-       memset(buffer, 0, SHA1_BLOCK_BYTES);
-#endif
-}
-
-void hmac_sha1_nextBlock(hmac_sha1_ctx_t *s, const void* block){
-       sha1_nextBlock(&(s->a), block);
-}
-void hmac_sha1_lastBlock(hmac_sha1_ctx_t *s, const void* block, uint16_t length_b){
-       while(length_b>=SHA1_BLOCK_BITS){
-               sha1_nextBlock(&(s->a), block);
-               block = (uint8_t*)block + SHA1_BLOCK_BYTES;
-               length_b -= SHA1_BLOCK_BITS;
-       }
-       sha1_lastBlock(&(s->a), block, length_b);
-}
-
-void hmac_sha1_final(void* dest, hmac_sha1_ctx_t *s){
-       sha1_ctx2hash((sha1_hash_t*)dest, &(s->a));
-       sha1_lastBlock(&(s->b), dest, SHA1_HASH_BITS);
-       sha1_ctx2hash((sha1_hash_t*)dest, &(s->b));
-}
-
-#endif
-
-/*
- * keylength in bits!
- * message length in bits!
- */
-void hmac_sha1(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b){ /* a one-shot*/
-       sha1_ctx_t s;
-       uint8_t i;
-       uint8_t buffer[SHA1_BLOCK_BYTES];
-       
-       memset(buffer, 0, SHA1_BLOCK_BYTES);
-       
-       /* if key is larger than a block we have to hash it*/
-       if (keylength_b > SHA1_BLOCK_BITS){
-               sha1((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       sha1_init(&s);
-       sha1_nextBlock(&s, buffer);
-       while (msglength_b >= SHA1_BLOCK_BITS){
-               sha1_nextBlock(&s, msg);
-               msg = (uint8_t*)msg + SHA1_BLOCK_BYTES;
-               msglength_b -=  SHA1_BLOCK_BITS;
-       }
-       sha1_lastBlock(&s, msg, msglength_b);
-       /* since buffer still contains key xor ipad we can do ... */
-       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD ^ OPAD;
-       }
-       sha1_ctx2hash(dest, &s); /* save inner hash temporary to dest */
-       sha1_init(&s);
-       sha1_nextBlock(&s, buffer);
-       sha1_lastBlock(&s, dest, SHA1_HASH_BITS);
-       sha1_ctx2hash(dest, &s);
-}
-
diff --git a/hmac-sha1.h b/hmac-sha1.h
deleted file mode 100644 (file)
index d0be029..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* hmac-sha1.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef HMACSHA1_H_
-#define HMACSHA1_H_
-
-#include "sha1.h"
-
-#define HMAC_SHA1_BITS        SHA1_HASH_BITS
-#define HMAC_SHA1_BYTES       SHA1_HASH_BYTES
-#define HMAC_SHA1_BLOCK_BITS  SHA1_BLOCK_BITS
-#define HMAC_SHA1_BLOCK_BYTES SHA1_BLOCK_BYTES
-
-typedef struct{
-        sha1_ctx_t a, b;
-} hmac_sha1_ctx_t;
-
-
-void hmac_sha1_init(hmac_sha1_ctx_t *s, const void* key, uint16_t keylength_b);
-void hmac_sha1_nextBlock(hmac_sha1_ctx_t *s, const void* block);
-void hmac_sha1_lastBlock(hmac_sha1_ctx_t *s, const void* block, uint16_t length_b);
-void hmac_sha1_final(void* dest, hmac_sha1_ctx_t *s);
-
-void hmac_sha1(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b);
-
-#endif /*HMACSHA1_H_*/
diff --git a/hmac-sha1/hmac-sha1.c b/hmac-sha1/hmac-sha1.c
new file mode 100644 (file)
index 0000000..56d90ac
--- /dev/null
@@ -0,0 +1,131 @@
+/* hmac-sha1.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * implementation of HMAC as described in RFC2104
+ * Author:      Daniel Otte
+ * email:       daniel.otte@rub.de
+ * License:     GPLv3 or later
+ **/
+
+/* 
+ * hmac = hash ( k^opad , hash( k^ipad  , msg))
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "config.h"
+#include "sha1.h"
+#include "hmac-sha1.h"
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+
+#ifndef HMAC_SHORTONLY
+
+void hmac_sha1_init(hmac_sha1_ctx_t *s, const void* key, uint16_t keylength_b){
+       uint8_t buffer[SHA1_BLOCK_BYTES];
+       uint8_t i;
+       
+       memset(buffer, 0, SHA1_BLOCK_BYTES);
+       if (keylength_b > SHA1_BLOCK_BITS){
+               sha1((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       sha1_init(&(s->a));
+       sha1_nextBlock(&(s->a), buffer);
+       
+       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD^OPAD;
+       }
+       sha1_init(&(s->b));
+       sha1_nextBlock(&(s->b), buffer);
+       
+       
+#if defined SECURE_WIPE_BUFFER
+       memset(buffer, 0, SHA1_BLOCK_BYTES);
+#endif
+}
+
+void hmac_sha1_nextBlock(hmac_sha1_ctx_t *s, const void* block){
+       sha1_nextBlock(&(s->a), block);
+}
+void hmac_sha1_lastBlock(hmac_sha1_ctx_t *s, const void* block, uint16_t length_b){
+       while(length_b>=SHA1_BLOCK_BITS){
+               sha1_nextBlock(&(s->a), block);
+               block = (uint8_t*)block + SHA1_BLOCK_BYTES;
+               length_b -= SHA1_BLOCK_BITS;
+       }
+       sha1_lastBlock(&(s->a), block, length_b);
+}
+
+void hmac_sha1_final(void* dest, hmac_sha1_ctx_t *s){
+       sha1_ctx2hash((sha1_hash_t*)dest, &(s->a));
+       sha1_lastBlock(&(s->b), dest, SHA1_HASH_BITS);
+       sha1_ctx2hash((sha1_hash_t*)dest, &(s->b));
+}
+
+#endif
+
+/*
+ * keylength in bits!
+ * message length in bits!
+ */
+void hmac_sha1(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b){ /* a one-shot*/
+       sha1_ctx_t s;
+       uint8_t i;
+       uint8_t buffer[SHA1_BLOCK_BYTES];
+       
+       memset(buffer, 0, SHA1_BLOCK_BYTES);
+       
+       /* if key is larger than a block we have to hash it*/
+       if (keylength_b > SHA1_BLOCK_BITS){
+               sha1((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       sha1_init(&s);
+       sha1_nextBlock(&s, buffer);
+       while (msglength_b >= SHA1_BLOCK_BITS){
+               sha1_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + SHA1_BLOCK_BYTES;
+               msglength_b -=  SHA1_BLOCK_BITS;
+       }
+       sha1_lastBlock(&s, msg, msglength_b);
+       /* since buffer still contains key xor ipad we can do ... */
+       for (i=0; i<SHA1_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD ^ OPAD;
+       }
+       sha1_ctx2hash(dest, &s); /* save inner hash temporary to dest */
+       sha1_init(&s);
+       sha1_nextBlock(&s, buffer);
+       sha1_lastBlock(&s, dest, SHA1_HASH_BITS);
+       sha1_ctx2hash(dest, &s);
+}
+
diff --git a/hmac-sha1/hmac-sha1.h b/hmac-sha1/hmac-sha1.h
new file mode 100644 (file)
index 0000000..d0be029
--- /dev/null
@@ -0,0 +1,41 @@
+/* hmac-sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef HMACSHA1_H_
+#define HMACSHA1_H_
+
+#include "sha1.h"
+
+#define HMAC_SHA1_BITS        SHA1_HASH_BITS
+#define HMAC_SHA1_BYTES       SHA1_HASH_BYTES
+#define HMAC_SHA1_BLOCK_BITS  SHA1_BLOCK_BITS
+#define HMAC_SHA1_BLOCK_BYTES SHA1_BLOCK_BYTES
+
+typedef struct{
+        sha1_ctx_t a, b;
+} hmac_sha1_ctx_t;
+
+
+void hmac_sha1_init(hmac_sha1_ctx_t *s, const void* key, uint16_t keylength_b);
+void hmac_sha1_nextBlock(hmac_sha1_ctx_t *s, const void* block);
+void hmac_sha1_lastBlock(hmac_sha1_ctx_t *s, const void* block, uint16_t length_b);
+void hmac_sha1_final(void* dest, hmac_sha1_ctx_t *s);
+
+void hmac_sha1(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b);
+
+#endif /*HMACSHA1_H_*/
diff --git a/hmac-sha1/sha1-asm.S b/hmac-sha1/sha1-asm.S
new file mode 100644 (file)
index 0000000..f571685
--- /dev/null
@@ -0,0 +1,886 @@
+/* sha1-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; SHA1 implementation in assembler for AVR
+SHA1_BLOCK_BITS = 512
+SHA1_HASH_BITS = 160
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+.macro delay
+/*     
+       push r0
+       push r1
+       clr r0
+1:     clr r1
+2:     dec r1
+       brne 2b
+       dec r0
+       brne 1b
+       pop r1
+       pop r0  // */
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+/*     
+       precall
+       hexdump \length
+       postcall
+       // */
+.endm
+
+
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha1_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha1_ctx2hash
+; === sha1_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha1_ctx structure
+;      given in r23,r22
+sha1_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 5
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha1
+; === sha1 ===
+; this function calculates SHA-1 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha1:
+sha1_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 5*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha1_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha1_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha1_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha1_ctx2hash     
+       
+sha1_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 5*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha1_lastBlock
+; === sha1_lastBlock ===
+; this function does padding & Co. for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha1_lastBlock_localSpace = (SHA1_BLOCK_BITS/8+1)
+
+
+sha1_lastBlock:
+       cpi r21, 0x02
+       brlo sha1_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 2
+       subi r23, -2
+       rjmp sha1_lastBlock
+sha1_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64) /* ??? */
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha1_lastBlock_post_copy
+       mov r1, r18
+sha1_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha1_lastBlock_copy_loop
+sha1_lastBlock_post_copy:      
+sha1_lastBlock_insert_stuffing_bit:    
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha1_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*5+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha1_lastBlock_insert_zeros:   
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha1_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha1_lastBlock_epilog
+sha1_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 5*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha1_nextBlock
+
+sha1_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha1_nextBlock
+; === sha1_nextBlock ===
+; this is the core function for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha1_nextBlock_localSpace = (16+5+1)*4 ; 16 32-bit values for w array and 5 32-bit values for a array (total 84 byte)
+
+xtmp = 0
+xNULL = 1
+W1 = 10
+W2 = 11
+T1     = 12
+T2     = 13
+T3     = 14
+T4     = 15
+LoopC = 16
+S        = 17
+tmp1 = 18
+tmp2 = 19
+tmp3 = 20
+tmp4 = 21
+F1 = 22
+F2 = 23
+F3 = 24
+F4 = 25
+
+/* byteorder: high number <--> high significance */
+sha1_nextBlock:
+ ; initial, let's make some space ready for local vars
+                        /* replace push & pop by mem ops? */
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack /* maybe removeable? */ 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha1_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha1_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       push r18
+       push r19 /* push old SP on new stack */
+       push r24
+       push r25 /* param1 will be needed later */
+       
+       /* load a[] with state */
+       movw 28, r24 /* load pointer to state in Y */
+       adiw r26, 1 ; X++
+
+       ldi LoopC, 5*4  
+1:     ld tmp1, Y+
+       st X+, tmp1
+       dec LoopC
+       brne 1b
+
+       movw W1, r26 /* save pointer to w[0] */
+       /* load w[] with endian fixed message */
+               /* we might also use the changeendian32() function at bottom */
+       movw r30, r22 /* mv param2 (ponter to msg) to Z */      
+       ldi LoopC, 16
+1:
+       ldd tmp1, Z+3
+       st X+, tmp1
+       ldd tmp1, Z+2
+       st X+, tmp1
+       ldd tmp1, Z+1
+       st X+, tmp1
+       ld tmp1, Z
+       st X+, tmp1
+       adiw r30, 4
+       dec LoopC
+       brne 1b
+       
+       ;clr LoopC /* LoopC is named t in FIPS 180-2 */ 
+       clr xtmp
+sha1_nextBlock_mainloop:
+       mov S, LoopC
+       lsl S
+       lsl S
+       andi S, 0x3C /* S is a bytepointer so *4 */
+       /* load w[s] */
+       movw r26, W1
+       add r26, S /* X points at w[s] */
+       adc r27, xNULL
+       ld T1, X+
+       ld T2, X+
+       ld T3, X+
+       ld T4, X+
+
+       /**/
+       push r26
+       push r27
+       push T4
+       push T3
+       push T2
+       push T1
+       in r26, SPL
+       in r27, SPH
+       adiw r26, 1
+       dbg_hexdump 4
+       pop T1
+       pop T2
+       pop T3
+       pop T4
+       pop r27
+       pop r26
+       /**/
+
+       cpi LoopC, 16
+       brlt sha1_nextBlock_mainloop_core
+       /* update w[s] */
+       ldi tmp1, 2*4
+       rcall 1f
+       ldi tmp1, 8*4
+       rcall 1f
+       ldi tmp1, 13*4
+       rcall 1f
+       rjmp 2f
+1:             /* this might be "outsourced" to save the jump above */
+       add tmp1, S
+       andi tmp1, 0x3f
+       movw r26, W1
+       add r26, tmp1
+       adc r27, xNULL
+       ld tmp2, X+
+       eor T1, tmp2
+       ld tmp2, X+
+       eor T2, tmp2
+       ld tmp2, X+
+       eor T3, tmp2
+       ld tmp2, X+
+       eor T4, tmp2
+       ret
+2:     /* now we just hav to do a ROTL(T) and save T back */
+       mov tmp2, T4
+       rol tmp2
+       rol T1
+       rol T2
+       rol T3
+       rol T4
+       movw r26, W1
+       add r26, S
+       adc r27, xNULL
+       st X+, T1
+       st X+, T2
+       st X+, T3
+       st X+, T4
+       
+sha1_nextBlock_mainloop_core:  /* ther core function; T=ROTL5(a) ....*/        
+                                                               /* T already contains w[s] */
+       movw r26, W1
+       sbiw r26, 4*1           /* X points at a[4] aka e */
+       ld tmp1, X+ 
+       add T1, tmp1
+       ld tmp1, X+ 
+       adc T2, tmp1
+       ld tmp1, X+ 
+       adc T3, tmp1
+       ld tmp1, X+ 
+       adc T4, tmp1            /* T = w[s]+e */
+       sbiw r26, 4*5           /* X points at a[0] aka a */
+       ld F1, X+ 
+       ld F2, X+ 
+       ld F3, X+ 
+       ld F4, X+ 
+       mov tmp1, F4            /* X points at a[1] aka b */
+       ldi tmp2, 5
+1:
+       rol tmp1
+       rol F1
+       rol F2
+       rol F3
+       rol F4
+       dec tmp2
+       brne 1b
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, F4 /* T = ROTL(a,5) + e + w[s] */
+       
+       /* now we have to do this fucking conditional stuff */
+       ldi r30, lo8(sha1_nextBlock_xTable)
+       ldi r31, hi8(sha1_nextBlock_xTable)
+       add r30, xtmp
+       adc r31, xNULL
+       lpm tmp1, Z
+       cp tmp1, LoopC
+       brne 1f
+       inc xtmp
+1:     ldi r30, lo8(sha1_nextBlock_KTable)
+       ldi r31, hi8(sha1_nextBlock_KTable)
+       lsl xtmp
+       lsl xtmp
+       add r30, xtmp
+       adc r31, xNULL
+       lsr xtmp
+       lsr xtmp
+        
+       lpm tmp1, Z+
+       add T1, tmp1
+       lpm tmp1, Z+
+       adc T2, tmp1
+       lpm tmp1, Z+
+       adc T3, tmp1
+       lpm tmp1, Z+
+       adc T4, tmp1
+                       /* T = ROTL(a,5) + e + kt + w[s] */
+       
+       /* Z-4 is just pointing to kt ... */
+       movw r28, r26 /* copy X in Y */
+       adiw r30, 3*4 /* now Z points to the rigth locatin in our jump-vector-table */
+       lsr r31
+       ror r30
+               
+       icall
+       mov F1, tmp1
+       icall
+       mov F2, tmp1
+       icall
+       mov F3, tmp1
+       icall
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, tmp1 /* T = ROTL5(a) + f_t(b,c,d) + e + k_t + w[s] */
+                                /* X points still at a[1] aka b, Y points at a[2] aka c */     
+       /* update a[] */
+sha1_nextBlock_update_a:
+       /*first we move all vars in a[] "one up" e=d, d=c, c=b, b=a*/
+       //adiw r28, 3*4  /* Y should point at a[4] aka e */
+       movw r28, W1
+       sbiw r28, 4
+       
+       ldi tmp2, 4*4 
+1:     
+       ld tmp1, -Y
+       std Y+4, tmp1
+       dec tmp2
+       brne 1b
+       /* Y points at a[0] aka a*/
+       
+       movw r28, W1
+       sbiw r28, 5*4
+       /* store T in a[0] aka a */
+       st Y+, T1
+       st Y+, T2
+       st Y+, T3
+       st Y+, T4
+       /* Y points at a[1] aka b*/
+       
+       /* rotate c */
+       ldd T1, Y+1*4
+       ldd T2, Y+1*4+1
+       ldd T3, Y+1*4+2
+       ldd T4, Y+1*4+3
+       mov tmp1, T1
+       ldi tmp2, 2
+1:     ror tmp1
+       ror T4
+       ror T3
+       ror T2
+       ror T1
+       dec tmp2
+       brne 1b
+       std Y+1*4+0, T1
+       std Y+1*4+1, T2
+       std Y+1*4+2, T3
+       std Y+1*4+3, T4
+       
+       push r27
+       push r26
+       movw r26, W1
+       sbiw r26, 4*5
+       dbg_hexdump 4*5
+       pop r26
+       pop r27
+       
+       inc LoopC
+       cpi LoopC, 80
+       brge 1f
+       rjmp sha1_nextBlock_mainloop
+/**************************************/
+1:     
+   /* littel patch */
+       sbiw r28, 4
+
+/* add a[] to state and inc length */  
+       pop r27
+       pop r26         /* now X points to state (and Y still at a[0]) */
+       ldi tmp4, 5
+1:     clc
+       ldi tmp3, 4
+2:     ld tmp1, X
+       ld tmp2, Y+
+       adc tmp1, tmp2
+       st X+, tmp1
+       dec tmp3
+       brne 2b
+       dec tmp4
+       brne 1b
+       
+       /* now length += 512 */
+       adiw r26, 1 /* we skip the least significant byte */
+       ld tmp1, X
+       ldi tmp2, hi8(512) /* 2 */
+       add tmp1, tmp2
+       st X+, tmp1
+       ldi tmp2, 6
+1:
+       ld tmp1, X
+       adc tmp1, xNULL
+       st X+, tmp1
+       dec tmp2
+       brne 1b
+       
+; EPILOG
+sha1_nextBlock_epilog:
+/* now we should clean up the stack */
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       ret
+
+sha1_nextBlock_xTable:
+.byte 20,40,60,0
+sha1_nextBlock_KTable:
+.int   0x5a827999 
+.int   0x6ed9eba1 
+.int   0x8f1bbcdc 
+.int   0xca62c1d6
+sha1_nextBlock_JumpTable:
+rjmp sha1_nextBlock_Ch
+       nop     
+rjmp sha1_nextBlock_Parity
+       nop
+rjmp sha1_nextBlock_Maj
+       nop
+rjmp sha1_nextBlock_Parity
+
+        /* X and Y still point at a[1] aka b ; return value in tmp1 */
+sha1_nextBlock_Ch:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       com tmp2
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp3, Y+7   /* load from d */
+       and tmp2, tmp3
+       eor tmp1, tmp2
+       ret
+       
+sha1_nextBlock_Maj:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp4, Y+7   /* load from d */
+       and tmp2, tmp4
+       eor tmp1, tmp2
+       and tmp3, tmp4
+       eor tmp1, tmp3
+       ret
+
+sha1_nextBlock_Parity:
+       ld tmp1, Y+
+       ldd tmp2, Y+3   /* load from c */
+       eor tmp1, tmp2
+       ldd tmp2, Y+7   /* load from d */
+       eor tmp1, tmp2
+       ret
+/*     
+ch_str:                        .asciz "\r\nCh"
+maj_str:               .asciz "\r\nMaj"
+parity_str:    .asciz "\r\nParity"
+*/
+;###########################################################   
+
+.global sha1_init 
+;void sha1_init(sha1_ctx_t *state){
+;      DEBUG_S("\r\nSHA1_INIT");
+;      state->h[0] = 0x67452301;
+;      state->h[1] = 0xefcdab89;
+;      state->h[2] = 0x98badcfe;
+;      state->h[3] = 0x10325476;
+;      state->h[4] = 0xc3d2e1f0;
+;      state->length = 0;
+;}
+; param1: (Func3,r24) 16-bit pointer to sha1_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha1_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha1_init_vector))
+       ldi r31, hi8((sha1_init_vector))
+       ldi r22, 5*4 /* bytes to copy */
+sha1_init_vloop:       
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha1_init_vloop
+       ldi r22, 8
+sha1_init_lloop:
+       st X+, r1
+       dec r22
+       brne sha1_init_lloop
+       ret
+       
+sha1_init_vector:
+.int 0x67452301;
+.int 0xefcdab89;
+.int 0x98badcfe;
+.int 0x10325476;
+.int 0xc3d2e1f0;
+
diff --git a/hmac-sha1/sha1.h b/hmac-sha1/sha1.h
new file mode 100644 (file)
index 0000000..6675d20
--- /dev/null
@@ -0,0 +1,117 @@
+/* sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha1.h
+ * \author     Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief   SHA-1 declaration.
+ * \ingroup SHA-1
+ * 
+ */
+#ifndef SHA1_H_
+#define SHA1_H_
+
+#include <stdint.h>
+/** \def SHA1_HASH_BITS
+ * definees the size of a SHA-1 hash in bits 
+ */
+
+/** \def SHA1_HASH_BYTES
+ * definees the size of a SHA-1 hash in bytes 
+ */
+
+/** \def SHA1_BLOCK_BITS
+ * definees the size of a SHA-1 input block in bits 
+ */
+
+/** \def SHA1_BLOCK_BYTES
+ * definees the size of a SHA-1 input block in bytes 
+ */
+#define SHA1_HASH_BITS  160
+#define SHA1_HASH_BYTES (SHA1_HASH_BITS/8)
+#define SHA1_BLOCK_BITS 512
+#define SHA1_BLOCK_BYTES (SHA1_BLOCK_BITS/8)
+
+/** \typedef sha1_ctx_t
+ * \brief SHA-1 context type
+ * 
+ * A vatiable of this type may hold the state of a SHA-1 hashing process
+ */
+typedef struct {
+       uint32_t h[5];
+       uint64_t length;
+} sha1_ctx_t;
+
+/** \typedef sha1_hash_t
+ * \brief hash value type
+ * A variable of this type may hold a SHA-1 hash value 
+ */
+typedef uint8_t sha1_hash_t[SHA1_HASH_BITS/8];
+
+/** \fn sha1_init(sha1_ctx_t *state)
+ * \brief initializes a SHA-1 context
+ * This function sets a ::sha1_ctx_t variable to the initialization vector
+ * for SHA-1 hashing.
+ * \param state pointer to the SHA-1 context variable
+ */
+void sha1_init(sha1_ctx_t *state);
+
+/** \fn sha1_nextBlock(sha1_ctx_t *state, const void* block)
+ *  \brief process one input block
+ * This function processes one input block and updates the hash context 
+ * accordingly
+ * \param state pointer to the state variable to update
+ * \param block pointer to the message block to process
+ */
+void sha1_nextBlock (sha1_ctx_t *state, const void* block);
+
+/** \fn sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length_b)
+ * \brief processes the given block and finalizes the context
+ * This function processes the last block in a SHA-1 hashing process.
+ * The block should have a maximum length of a single input block.
+ * \param state pointer to the state variable to update and finalize
+ * \param block pointer to themessage block to process
+ * \param length_b length of the message block in bits  
+ */
+void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
+
+/** \fn sha1_ctx2hash(sha1_hash_t *dest, sha1_ctx_t *state)
+ * \brief convert a state variable into an actual hash value
+ * Writes the hash value corresponding to the state to the memory pointed by dest.
+ * \param dest pointer to the hash value destination
+ * \param state pointer to the hash context
+ */ 
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
+
+/** \fn sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b)
+ * \brief hashing a message which in located entirely in RAM
+ * This function automatically hashes a message which is entirely in RAM with
+ * the SHA-1 hashing algorithm.
+ * \param dest pointer to the hash value destination
+ * \param msg  pointer to the message which should be hashed
+ * \param length_b length of the message in bits
+ */ 
+void sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b);
+
+
+
+#endif /*SHA1_H_*/
diff --git a/hmac-sha256.c b/hmac-sha256.c
deleted file mode 100644 (file)
index 6a57189..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* hmac-sha256.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * implementation of HMAC as described in RFC2104
- * Author:      Daniel Otte
- * email:       daniel.otte@rub.de
- * License:     GPLv3 or later
- **/
-
-/* 
- * hmac = hash ( k^opad , hash( k^ipad  , msg))
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "config.h"
-#include "sha256.h"
-#include "hmac-sha256.h"
-
-#define IPAD 0x36
-#define OPAD 0x5C
-
-#ifndef HMAC_SHA256_SHORTONLY
-
-void hmac_sha256_init(hmac_sha256_ctx_t *s, const void* key, uint16_t keylength_b){
-       uint8_t buffer[HMAC_SHA256_BLOCK_BYTES];
-       uint8_t i;
-       
-       memset(buffer, 0, HMAC_SHA256_BLOCK_BYTES);
-       if (keylength_b > HMAC_SHA256_BLOCK_BITS){
-               sha256((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       
-       sha256_init(&(s->a));
-       sha256_nextBlock(&(s->a), buffer);
-       
-       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD^OPAD;
-       }
-       sha256_init(&(s->b));
-       sha256_nextBlock(&(s->b), buffer);
-       
-#if defined SECURE_WIPE_BUFFER
-       memset(buffer, 0, SHA256_BLOCK_BYTES);
-#endif
-}
-
-void hmac_sha256_nextBlock(hmac_sha256_ctx_t *s, const void* block){
-       sha256_nextBlock(&(s->a), block);
-}
-
-void hmac_sha256_lastBlock(hmac_sha256_ctx_t *s, const void* block, uint16_t length_b){
-/*     while(length_b>=SHA256_BLOCK_BITS){
-               sha256_nextBlock(&(s->a), block);
-               block = (uint8_t*)block + SHA256_BLOCK_BYTES;
-               length_b -= SHA256_BLOCK_BITS;
-       }
-*/     sha256_lastBlock(&(s->a), block, length_b);
-}
-
-void hmac_sha256_final(void* dest, hmac_sha256_ctx_t *s){
-       sha256_ctx2hash((sha256_hash_t*)dest, &(s->a));
-       sha256_lastBlock(&(s->b), dest, SHA256_HASH_BITS);
-       sha256_ctx2hash((sha256_hash_t*)dest, &(s->b));                 
-}
-
-#endif
-
-/*
- * keylength in bits!
- * message length in bits!
- */
-void hmac_sha256(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b){ /* a one-shot*/
-       sha256_ctx_t s;
-       uint8_t i;
-       uint8_t buffer[HMAC_SHA256_BLOCK_BYTES];
-       
-       memset(buffer, 0, HMAC_SHA256_BLOCK_BYTES);
-       
-       /* if key is larger than a block we have to hash it*/
-       if (keylength_b > SHA256_BLOCK_BITS){
-               sha256((void*)buffer, key, keylength_b);
-       } else {
-               memcpy(buffer, key, (keylength_b+7)/8);
-       }
-       
-       for (i=0; i<SHA256_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD;
-       }
-       sha256_init(&s);
-       sha256_nextBlock(&s, buffer);
-       while (msglength_b >= HMAC_SHA256_BLOCK_BITS){
-               sha256_nextBlock(&s, msg);
-               msg = (uint8_t*)msg + HMAC_SHA256_BLOCK_BYTES;
-               msglength_b -=  HMAC_SHA256_BLOCK_BITS;
-       }
-       sha256_lastBlock(&s, msg, msglength_b);
-       /* since buffer still contains key xor ipad we can do ... */
-       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
-               buffer[i] ^= IPAD ^ OPAD;
-       }
-       sha256_ctx2hash(dest, &s); /* save inner hash temporary to dest */
-       sha256_init(&s);
-       sha256_nextBlock(&s, buffer);
-       sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
-       sha256_ctx2hash(dest, &s);
-}
diff --git a/hmac-sha256.h b/hmac-sha256.h
deleted file mode 100644 (file)
index 4df6af5..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* hmac-sha256.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef HMACSHA256_H_
-#define HMACSHA256_H_
-
-#include "sha256.h"
-
-#define HMAC_SHA256_BITS        SHA256_HASH_BITS
-#define HMAC_SHA256_BYTES       SHA256_HASH_BYTES
-#define HMAC_SHA256_BLOCK_BITS  SHA256_BLOCK_BITS
-#define HMAC_SHA256_BLOCK_BYTES SHA256_BLOCK_BYTES
-
-
-typedef struct {
-       sha256_ctx_t a,b;
-} hmac_sha256_ctx_t;
-
-
-void hmac_sha256_init(hmac_sha256_ctx_t *s, const void* key, uint16_t keylength_b);
-void hmac_sha256_nextBlock(hmac_sha256_ctx_t *s, const void* block);
-void hmac_sha256_lastBlock(hmac_sha256_ctx_t *s, const void* block, uint16_t length_b);
-void hmac_sha256_final(void* dest, hmac_sha256_ctx_t *s);
-
-void hmac_sha256(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b);
-
-
-#endif /*HMACSHA256_H_*/
diff --git a/hmac-sha256/hmac-sha256.c b/hmac-sha256/hmac-sha256.c
new file mode 100644 (file)
index 0000000..6a57189
--- /dev/null
@@ -0,0 +1,130 @@
+/* hmac-sha256.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * implementation of HMAC as described in RFC2104
+ * Author:      Daniel Otte
+ * email:       daniel.otte@rub.de
+ * License:     GPLv3 or later
+ **/
+
+/* 
+ * hmac = hash ( k^opad , hash( k^ipad  , msg))
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "config.h"
+#include "sha256.h"
+#include "hmac-sha256.h"
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+#ifndef HMAC_SHA256_SHORTONLY
+
+void hmac_sha256_init(hmac_sha256_ctx_t *s, const void* key, uint16_t keylength_b){
+       uint8_t buffer[HMAC_SHA256_BLOCK_BYTES];
+       uint8_t i;
+       
+       memset(buffer, 0, HMAC_SHA256_BLOCK_BYTES);
+       if (keylength_b > HMAC_SHA256_BLOCK_BITS){
+               sha256((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       
+       sha256_init(&(s->a));
+       sha256_nextBlock(&(s->a), buffer);
+       
+       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD^OPAD;
+       }
+       sha256_init(&(s->b));
+       sha256_nextBlock(&(s->b), buffer);
+       
+#if defined SECURE_WIPE_BUFFER
+       memset(buffer, 0, SHA256_BLOCK_BYTES);
+#endif
+}
+
+void hmac_sha256_nextBlock(hmac_sha256_ctx_t *s, const void* block){
+       sha256_nextBlock(&(s->a), block);
+}
+
+void hmac_sha256_lastBlock(hmac_sha256_ctx_t *s, const void* block, uint16_t length_b){
+/*     while(length_b>=SHA256_BLOCK_BITS){
+               sha256_nextBlock(&(s->a), block);
+               block = (uint8_t*)block + SHA256_BLOCK_BYTES;
+               length_b -= SHA256_BLOCK_BITS;
+       }
+*/     sha256_lastBlock(&(s->a), block, length_b);
+}
+
+void hmac_sha256_final(void* dest, hmac_sha256_ctx_t *s){
+       sha256_ctx2hash((sha256_hash_t*)dest, &(s->a));
+       sha256_lastBlock(&(s->b), dest, SHA256_HASH_BITS);
+       sha256_ctx2hash((sha256_hash_t*)dest, &(s->b));                 
+}
+
+#endif
+
+/*
+ * keylength in bits!
+ * message length in bits!
+ */
+void hmac_sha256(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b){ /* a one-shot*/
+       sha256_ctx_t s;
+       uint8_t i;
+       uint8_t buffer[HMAC_SHA256_BLOCK_BYTES];
+       
+       memset(buffer, 0, HMAC_SHA256_BLOCK_BYTES);
+       
+       /* if key is larger than a block we have to hash it*/
+       if (keylength_b > SHA256_BLOCK_BITS){
+               sha256((void*)buffer, key, keylength_b);
+       } else {
+               memcpy(buffer, key, (keylength_b+7)/8);
+       }
+       
+       for (i=0; i<SHA256_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD;
+       }
+       sha256_init(&s);
+       sha256_nextBlock(&s, buffer);
+       while (msglength_b >= HMAC_SHA256_BLOCK_BITS){
+               sha256_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + HMAC_SHA256_BLOCK_BYTES;
+               msglength_b -=  HMAC_SHA256_BLOCK_BITS;
+       }
+       sha256_lastBlock(&s, msg, msglength_b);
+       /* since buffer still contains key xor ipad we can do ... */
+       for (i=0; i<HMAC_SHA256_BLOCK_BYTES; ++i){
+               buffer[i] ^= IPAD ^ OPAD;
+       }
+       sha256_ctx2hash(dest, &s); /* save inner hash temporary to dest */
+       sha256_init(&s);
+       sha256_nextBlock(&s, buffer);
+       sha256_lastBlock(&s, dest, SHA256_HASH_BITS);
+       sha256_ctx2hash(dest, &s);
+}
diff --git a/hmac-sha256/hmac-sha256.h b/hmac-sha256/hmac-sha256.h
new file mode 100644 (file)
index 0000000..4df6af5
--- /dev/null
@@ -0,0 +1,43 @@
+/* hmac-sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef HMACSHA256_H_
+#define HMACSHA256_H_
+
+#include "sha256.h"
+
+#define HMAC_SHA256_BITS        SHA256_HASH_BITS
+#define HMAC_SHA256_BYTES       SHA256_HASH_BYTES
+#define HMAC_SHA256_BLOCK_BITS  SHA256_BLOCK_BITS
+#define HMAC_SHA256_BLOCK_BYTES SHA256_BLOCK_BYTES
+
+
+typedef struct {
+       sha256_ctx_t a,b;
+} hmac_sha256_ctx_t;
+
+
+void hmac_sha256_init(hmac_sha256_ctx_t *s, const void* key, uint16_t keylength_b);
+void hmac_sha256_nextBlock(hmac_sha256_ctx_t *s, const void* block);
+void hmac_sha256_lastBlock(hmac_sha256_ctx_t *s, const void* block, uint16_t length_b);
+void hmac_sha256_final(void* dest, hmac_sha256_ctx_t *s);
+
+void hmac_sha256(void* dest, const void* key, uint16_t keylength_b, const void* msg, uint32_t msglength_b);
+
+
+#endif /*HMACSHA256_H_*/
diff --git a/hmac-sha256/sha256-asm.S b/hmac-sha256/sha256-asm.S
new file mode 100644 (file)
index 0000000..d9eb6b6
--- /dev/null
@@ -0,0 +1,1042 @@
+/* sha256-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; sha-256 implementation in assembler  
+SHA256_BLOCK_BITS = 512
+SHA256_HASH_BITS = 256
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+       precall
+       hexdump \length
+       postcall
+.endm
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha256_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha256_ctx2hash
+; === sha256_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha256_ctx structure
+;      given in r23,r22
+sha256_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 8
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha256
+; === sha256 ===
+; this function calculates SHA-256 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha256:
+sha256_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 8*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha256_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha256_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha256_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha256_ctx2hash   
+       
+sha256_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 8*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha256_lastBlock
+; === sha256_lastBlock ===
+; this function does padding & Co. for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
+
+
+sha256_lastBlock:
+       cpi r21, 0x02
+       brlo sha256_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 0x02
+       subi r23, -2
+       rjmp sha256_lastBlock   
+sha256_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha256_lastBlock_post_copy
+       mov r1, r18
+sha256_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha256_lastBlock_copy_loop
+sha256_lastBlock_post_copy:    
+sha256_lastBlock_insert_stuffing_bit:  
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha256_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*8+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha256_lastBlock_insert_zeros: 
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha256_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha256_lastBlock_epilog
+sha256_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 8*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha256_nextBlock
+
+sha256_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha256_nextBlock
+; === sha256_nextBlock ===
+; this is the core function for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
+
+Bck1 = 12
+Bck2 = 13
+Bck3 = 14
+Bck4 = 15
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+Accu1 = 16
+Accu2 = 17
+Accu3 = 18
+Accu4 = 19
+XAccu1 = 8
+XAccu2 = 9
+XAccu3 = 10
+XAccu4 = 11
+T1     = 4
+T2     = 5
+T3     = 6
+T4     = 7
+LoopC = 1
+/* byteorder: high number <--> high significance */
+sha256_nextBlock:
+ ; initial, let's make some space ready for local vars
+       push r4 /* replace push & pop by mem ops? */
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha256_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       push r18
+       push r19
+       push r24
+       push r25 /* param1 will be needed later */
+ ; now we fill the w array with message (think about endianess)
+       adiw r26, 1 ; X++
+       ldi r20, 16
+sha256_nextBlock_wcpyloop:     
+       ld r23, Z+
+       ld r22, Z+
+       ld r19, Z+
+       ld r18, Z+
+       st X+, r18
+       st X+, r19
+       st X+, r22      
+       st X+, r23
+       dec r20
+       brne sha256_nextBlock_wcpyloop
+/*     for (i=16; i<64; ++i){
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+       } */
+       /* r25,r24,r23,r24 (r21,r20) are function values
+          r19,r18,r17,r16 are the accumulator
+          r15,r14,r13,rBck1 are backup1
+          r11,r10,r9 ,r8  are xor accu   
+          r1 is round counter                                                          */
+
+       ldi r20, 64-16
+       mov LoopC, r20
+sha256_nextBlock_wcalcloop:             
+       movw r30, r26 ; cp X to Z
+       sbiw r30, 63
+       sbiw r30, 1             ; substract 64 = 16*4
+       ld Accu1, Z+
+       ld Accu2, Z+
+       ld Accu3, Z+
+       ld Accu4, Z+ /* w[i] = w[i-16] */
+       ld Bck1, Z+
+       ld Bck2, Z+
+       ld Bck3, Z+
+       ld Bck4, Z+ /* backup = w[i-15] */
+       /* now sigma 0 */
+       mov Func1, Bck2
+       mov Func2, Bck3
+       mov Func3, Bck4
+       mov Func4, Bck1  /* prerotated by 8 */
+       ldi r20, 1
+       rcall bitrotl
+       movw XAccu1, Func1
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
+sigma0_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2
+       ror Bck1        
+       dec Func2
+       brne sigma0_shr
+       eor XAccu1, Bck1
+       eor XAccu2, Bck2
+       eor XAccu3, Bck3
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */
+       ldd Func2, Z+7*4+1
+       ldd Func3, Z+7*4+2
+       ldd Func4, Z+7*4+3
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
+       ldd Bck2, Z+12*4+1
+       ldd Bck3, Z+12*4+2
+       ldd Bck4, Z+12*4+3
+       /* now sigma 1 */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 1
+       rcall bitrotr
+       movw XAccu3, Func3
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
+;      movw Func1, Bck3
+;      movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
+sigma1_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2        
+       dec Func2
+       brne sigma1_shr
+       eor XAccu1, Bck2
+       eor XAccu2, Bck3
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       /* now let's store the shit */
+       st X+, Accu1
+       st X+, Accu2
+       st X+, Accu3
+       st X+, Accu4
+       dec LoopC
+       breq 3f  ; skip if zero
+       rjmp sha256_nextBlock_wcalcloop
+3:
+       /* we are finished with w array X points one byte post w */
+/* init a array */
+       pop r31
+       pop r30
+       push r30
+       push r31
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
+init_a_array:  
+       ld r1, Z+
+       st X+, r1
+       dec r25
+       brne init_a_array
+       
+/* now the real fun begins */
+/* 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;
+               } */
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
+       sbiw r26, 8*4  /* X still points at a[7]+1*/
+       movw r28, r26
+       ldi r30, lo8(sha256_kv)
+       ldi r31, hi8(sha256_kv)         
+       dec r27  /* X - (64*4 == 256) */
+       ldi r25, 64
+       mov LoopC, r25
+sha256_main_loop:
+       /* now calculate t1 */
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/
+       ldd T1, Y+5*4
+       ldd T2, Y+5*4+1
+       ldd T3, Y+5*4+2
+       ldd T4, Y+5*4+3 /* y in T */
+       ldd Func1, Y+4*4
+       ldd Func2, Y+4*4+1
+       ldd Func3, Y+4*4+2
+       ldd Func4, Y+4*4+3  /* x in Func */
+       ldd Bck1, Y+6*4
+       ldd Bck2, Y+6*4+1
+       ldd Bck3, Y+6*4+2
+       ldd Bck4, Y+6*4+3 /* z in Bck */
+       and T1, Func1
+       and T2, Func2
+       and T3, Func3
+       and T4, Func4
+       com Func1
+       com Func2
+       com Func3
+       com Func4
+       and Bck1, Func1
+       and Bck2, Func2
+       and Bck3, Func3
+       and Bck4, Func4
+       eor T1, Bck1
+       eor T2, Bck2
+       eor T3, Bck3
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */
+       /* now SIGMA1(a[4]) */
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
+       ldd Bck1, Y+4*4+1       
+       ldd Bck2, Y+4*4+2
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2 
+       rcall bitrotl           /* rotr(x,6) */ 
+       movw XAccu1, Func1
+       movw XAccu3, Func3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 3 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
+       ldi r20, 1 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4
+       /* now we've to add a[7], w[i] and k[i] */
+       ldd XAccu1, Y+4*7
+       ldd XAccu2, Y+4*7+1
+       ldd XAccu3, Y+4*7+2
+       ldd XAccu4, Y+4*7+3
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add a[7] */
+       ld XAccu1, X+
+       ld XAccu2, X+
+       ld XAccu3, X+
+       ld XAccu4, X+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add w[i] */
+       lpm XAccu1, Z+
+       lpm XAccu2, Z+
+       lpm XAccu3, Z+
+       lpm XAccu4, Z+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
+               /* starting with MAJ(x,y,z) */
+       ldd Func1, Y+4*0+0
+       ldd Func2, Y+4*0+1
+       ldd Func3, Y+4*0+2
+       ldd Func4, Y+4*0+3 /* load x=a[0] */
+       ldd XAccu1, Y+4*1+0
+       ldd XAccu2, Y+4*1+1
+       ldd XAccu3, Y+4*1+2
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
+       and XAccu1, Func1
+       and XAccu2, Func2
+       and XAccu3, Func3
+       and XAccu4, Func4       /* XAccu == (x & y) */
+       ldd Bck1, Y+4*2+0
+       ldd Bck2, Y+4*2+1
+       ldd Bck3, Y+4*2+2
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
+       ldd Func1, Y+4*1+0
+       ldd Func2, Y+4*1+1
+       ldd Func3, Y+4*1+2
+       ldd Func4, Y+4*1+3 /* load y=a[1] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
+       /* SIGMA0(a[0]) */
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */
+       ldd Bck2, Y+4*0+1
+       ldd Bck3, Y+4*0+2
+       ldd Bck4, Y+4*0+3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2
+       rcall bitrotr
+       movw Accu1, Func1
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
+       movw Func1, Bck3 
+       movw Func3, Bck1 /* prerotate by 16 bits */
+       ldi r20, 3
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
+       mov Func1, Bck4
+       mov Func2, Bck1
+       mov Func3, Bck2
+       mov Func4, Bck3  /* prerotate by 24 bits */
+       ldi r20, 2
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
+       add Accu1, XAccu1 /* add previous result (MAJ)*/
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
+       /* 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]; */
+
+       ldi r21, 7*4
+       adiw r28, 7*4
+a_shift_loop:
+       ld  r25, -Y /* warning: this is PREdecrement */
+       std Y+4, r25
+       dec r21
+       brne a_shift_loop
+
+       ldd Bck1, Y+4*4+0
+       ldd Bck2, Y+4*4+1
+       ldd Bck3, Y+4*4+2
+       ldd Bck4, Y+4*4+3
+       add Bck1, T1
+       adc Bck2, T2
+       adc Bck3, T3
+       adc Bck4, T4
+       std Y+4*4+0, Bck1
+       std Y+4*4+1, Bck2
+       std Y+4*4+2, Bck3
+       std Y+4*4+3, Bck4
+       add Accu1, T1
+       adc Accu2, T2
+       adc Accu3, T3
+       adc Accu4, T4
+       std Y+4*0+0, Accu1
+       std Y+4*0+1, Accu2
+       std Y+4*0+2, Accu3
+       std Y+4*0+3, Accu4 /* a array updated */
+       
+       
+       dec LoopC
+       breq update_state
+       rjmp sha256_main_loop ;brne sha256_main_loop
+update_state:  
+       /* update state */
+       /* pointers to state should still exist on the stack ;-) */
+       pop r31
+       pop r30
+       ldi r21, 8
+update_state_loop:
+       ldd Accu1, Z+0
+       ldd Accu2, Z+1
+       ldd Accu3, Z+2
+       ldd Accu4, Z+3 
+       ld Func1, Y+
+       ld Func2, Y+
+       ld Func3, Y+
+       ld Func4, Y+
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       st Z+, Accu1
+       st Z+, Accu2
+       st Z+, Accu3
+       st Z+, Accu4
+       dec r21
+       brne update_state_loop
+       /* now we just have to update the length */
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
+       ldi r21, 2
+       ldi r22, 6
+       ld r20, Z
+       add r20, r21
+       st Z+, r20      
+       clr r21
+sha256_nextBlock_fix_length:   
+       brcc sha256_nextBlock_epilog
+       ld r20, Z
+       adc r20, r21
+       st Z+, r20
+       dec r22
+       brne sha256_nextBlock_fix_length
+       
+; EPILOG
+sha256_nextBlock_epilog:
+/* now we should clean up the stack */
+       
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4 
+       ret
+
+sha256_kv: ; round-key-vector stored in ProgMem 
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
+
+       
+;###########################################################   
+
+.global sha256_init 
+;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);
+;}
+; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha256_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha256_init_vector))
+       ldi r31, hi8((sha256_init_vector))
+       ldi r22, 32+8
+sha256_init_vloop:     
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha256_init_vloop
+       ret
+       
+sha256_init_vector:
+.word 0xE667, 0x6A09
+.word 0xAE85, 0xBB67 
+.word 0xF372, 0x3C6E 
+.word 0xF53A, 0xA54F 
+.word 0x527F, 0x510E 
+.word 0x688C, 0x9B05 
+.word 0xD9AB, 0x1F83 
+.word 0xCD19, 0x5BE0
+.word 0x0000, 0x0000
+.word 0x0000, 0x0000
+
+;###########################################################   
+
+.global rotl32
+; === ROTL32 ===
+; function that rotates a 32 bit word to the left
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,r22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       clr r21
+       clc
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       rol r21
+       dec r20
+       rjmp bitrotl_loop
+fixrotl:
+       or r22, r21
+       ret
+       
+
+;###########################################################   
+
+.global rotr32
+; === ROTR32 ===
+; function that rotates a 32 bit word to the right
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotr32:
+       cpi r20, 8
+       brlo bitrotr
+       mov r21, r22
+       mov r22, r23
+       mov r23, r24
+       mov r24, r25
+       mov r25, r21
+       subi r20, 8
+       rjmp rotr32
+bitrotr:
+       clr r21
+       clc
+bitrotr_loop:  
+       tst r20
+       breq fixrotr
+       ror r25
+       ror r24
+       ror r23
+       ror r22
+       ror r21
+       dec r20
+       rjmp bitrotr_loop
+fixrotr:
+       or r25, r21
+       ret
+       
+       
+;###########################################################   
+       
+.global change_endian32
+; === change_endian32 ===
+; function that changes the endianess of a 32-bit word
+;  param1: the 32-bit word
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  modifys: r21, r22
+change_endian32:
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)
+       mov r22, r25
+       mov r23, r24
+       mov r24, r21
+       mov r25, r20 
+       ret
+
diff --git a/hmac-sha256/sha256.h b/hmac-sha256/sha256.h
new file mode 100644 (file)
index 0000000..24960a3
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialise a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automaticaly hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/md5-asm.S b/md5-asm.S
deleted file mode 100644 (file)
index de3b170..0000000
--- a/md5-asm.S
+++ /dev/null
@@ -1,977 +0,0 @@
-/* md5-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * Author:  Daniel Otte
- * License: GPLv3 or later
- * Date:    2008-11-15
-*/
-
-
-#include "avr-asm-macros.S"
-
-;###########################################################   
-; S-BOX
-
-T_table:
-.hword 0xa478, 0xd76a, 0xb756, 0xe8c7, 0x70db, 0x2420, 0xceee, 0xc1bd, 0x0faf, 0xf57c 
-.hword 0xc62a, 0x4787, 0x4613, 0xa830, 0x9501, 0xfd46, 0x98d8, 0x6980, 0xf7af, 0x8b44 
-.hword 0x5bb1, 0xffff, 0xd7be, 0x895c, 0x1122, 0x6b90, 0x7193, 0xfd98, 0x438e, 0xa679 
-.hword 0x0821, 0x49b4, 0x2562, 0xf61e, 0xb340, 0xc040, 0x5a51, 0x265e, 0xc7aa, 0xe9b6 
-.hword 0x105d, 0xd62f, 0x1453, 0x0244, 0xe681, 0xd8a1, 0xfbc8, 0xe7d3, 0xcde6, 0x21e1 
-.hword 0x07d6, 0xc337, 0x0d87, 0xf4d5, 0x14ed, 0x455a, 0xe905, 0xa9e3, 0xa3f8, 0xfcef 
-.hword 0x02d9, 0x676f, 0x4c8a, 0x8d2a, 0x3942, 0xfffa, 0xf681, 0x8771, 0x6122, 0x6d9d 
-.hword 0x380c, 0xfde5, 0xea44, 0xa4be, 0xcfa9, 0x4bde, 0x4b60, 0xf6bb, 0xbc70, 0xbebf 
-.hword 0x7ec6, 0x289b, 0x27fa, 0xeaa1, 0x3085, 0xd4ef, 0x1d05, 0x0488, 0xd039, 0xd9d4 
-.hword 0x99e5, 0xe6db, 0x7cf8, 0x1fa2, 0x5665, 0xc4ac, 0x2244, 0xf429, 0xff97, 0x432a 
-.hword 0x23a7, 0xab94, 0xa039, 0xfc93, 0x59c3, 0x655b, 0xcc92, 0x8f0c, 0xf47d, 0xffef 
-.hword 0x5dd1, 0x8584, 0x7e4f, 0x6fa8, 0xe6e0, 0xfe2c, 0x4314, 0xa301, 0x11a1, 0x4e08 
-.hword 0x7e82, 0xf753, 0xf235, 0xbd3a, 0xd2bb, 0x2ad7, 0xd391, 0xeb86
-
-
-#define MD5_init_fast
-
-.global md5_init 
-#ifndef MD5_init_fast
-;###########################################################   
-;void md5_init(md5_ctx_t *state)
-; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
-; modifys: Z(r30,r31), X(r25,r26)
-; size = 9+5*4 WORDS = 29 WORDS = 58 Bytes
-md5_init:
-       movw r26, r24 ; (24,25) --> (26,27) load X with param1
-       ldi r30, lo8(md5_init_vector)
-       ldi r31, hi8(md5_init_vector)
-       ldi r24, 16+4
-md5_init_vloop:        
-       lpm r0, Z+ 
-       st X+, r0
-       dec r24
-       brne md5_init_vloop
-       ret
-       
-md5_init_vector:
-.hword 0x2301, 0x6745
-.hword 0xAB89, 0xEFCD 
-.hword 0xDCFE, 0x98BA 
-.hword 0x5476, 0x1032 
-.hword 0x0000, 0x0000
-
-#else
-;###########################################################   
-.global md5_init_fast 
-;void md5_init(md5_ctx_t *state)
-; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
-; modifys: r23, r22
-; cycles = 1+16*3+4*2+4 = 1+48+12 = 61
-; size = 1+16*2+4+1 WORDS = 38 WORDS = 76 Bytes
-md5_init:
-md5_init_fast:
-       movw r26, r24
-       ldi r24, 0x01
-       st X+, r24
-       ldi r24, 0x23
-       st X+, r24
-       ldi r24, 0x45
-       st X+, r24
-       ldi r24, 0x67
-       st X+, r24
-       ldi r24, 0x89
-       st X+, r24
-       ldi r24, 0xAB
-       st X+, r24
-       ldi r24, 0xCD
-       st X+, r24
-       ldi r24, 0xEF
-       st X+, r24
-       ldi r24, 0xFE
-       st X+, r24
-       ldi r24, 0xDC
-       st X+, r24
-       ldi r24, 0xBA
-       st X+, r24
-       ldi r24, 0x98
-       st X+, r24
-       ldi r24, 0x76
-       st X+, r24
-       ldi r24, 0x54
-       st X+, r24
-       ldi r24, 0x32
-       st X+, r24
-       ldi r24, 0x10
-       st X+, r24
-       st X+, r1
-       st X+, r1
-       st X+, r1
-       st X+, r1
-       ret
-#endif
-;###########################################################   
-
-/*
-static 
-uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
-       return ((x&y)|((~x)&z));
-}
-*/
-; x: r22-r25
-; y: r18-r21
-; z: r14-r17
-md5_F:
-       and r18, r22
-       and r19, r23
-       and r20, r24
-       and r21, r25
-       com r22
-       com r23
-       com r24
-       com r25
-       and r22, r14
-       and r23, r15
-       and r24, r16
-       and r25, r17
-       or  r22, r18
-       or  r23, r19
-       or  r24, r20
-       or  r25, r21
-       rjmp md5_core_F_exit
-       
-/*
-static
-uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
-       return ((x&z)|((~z)&y));
-}
-*/
-
-; x: r22-r25
-; y: r18-r21
-; z: r14-r17
-md5_G:
-       and r22, r14
-       and r23, r15
-       and r24, r16
-       and r25, r17
-       com r14
-       com r15
-       com r16
-       com r17
-       and r18, r14
-       and r19, r15
-       and r20, r16
-       and r21, r17
-       or  r22, r18
-       or  r23, r19
-       or  r24, r20
-       or  r25, r21
-       rjmp md5_core_F_exit
-/*
-static
-uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
-       return (x^y^z);
-}
-*/
-; x: r22-r25
-; y: r18-r21
-; z: r14-r17
-md5_H:
-       eor r22, r18
-       eor r22, r14
-       eor r23, r19
-       eor r23, r15
-       eor r24, r20
-       eor r24, r16
-       eor r25, r21
-       eor r25, r17
-       rjmp md5_core_F_exit
-/*
-static
-uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
-       return (y ^ (x | (~z)));
-}
-*/
-
-jump_table:
-       rjmp md5_F
-       rjmp md5_G
-       rjmp md5_H
-;      rjmp md5_I
-
-; x: r22-r25
-; y: r18-r21
-; z: r14-r17
-md5_I:
-       com r14
-       com r15
-       com r16
-       com r17
-       or  r22, r14
-       or  r23, r15
-       or  r24, r16
-       or  r25, r17
-       eor r22, r18
-       eor r23, r19
-       eor r24, r20
-       eor r25, r21
-       rjmp md5_core_F_exit
-
-as_table:
-;     (as+0)&3  (as+3)&3  (as+1)&3  (as+2)&3
-;                  Z         X         Y
-;     AS_SAVE0  AS_SAVE1  AS_SAVE2  AS_SAVE3 
-.byte   1*4,      0*4,      2*4,      3*4    ;as=1
-.byte   2*4,      1*4,      3*4,      0*4    ;as=2
-.byte   3*4,      2*4,      0*4,      1*4    ;as=3
-.byte   0*4,      3*4,      1*4,      2*4    ;as=4
-
-;###########################################################   
-.global md5_core
-md5_core:
-       mov r21, r20
-       mov r20, r18
-       mov r19, r16
-       mov r18, r14
-;      rjmp md5_core_asm
-/*
-void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
-       uint32_t t;
-       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
-       as &= 0x3;
-       / * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). * /
-       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) + *((uint32_t*)block) + md5_T[i] ;
-       a[as]=a[(as+1)&3] + ROTL32(t, s);
-}
-*/
-; a:     r24-r25
-; block: r22-r23
-; as:    r21
-; s:     r20
-; i:     r19
-; fi:    r18
-P_A0 = 24
-P_A1 = 25
-P_B0 = 22
-P_B1 = 23
-P_AS = 21
-P_S  = 20
-P_I  = 19
-P_FI = 18
-
-; x: r22-r25
-; y: r18-r21
-; z: r14-r17
-
-
-AS_SAVE0  =  4
-AS_SAVE1  =  5
-AS_SAVE2  =  6
-AS_SAVE3  =  7
-FI_SAVE   =  8
-S_SAVE    =  9
-ACCU0     = 10
-ACCU1     = 11
-ACCU2     = 12
-ACCU3     = 13
-ARG_X0    = 22
-ARG_X1    = 23
-ARG_X2    = 24
-ARG_X3    = 25
-ARG_Y0    = 18
-ARG_Y1    = 19
-ARG_Y2    = 20
-ARG_Y3    = 21
-ARG_Z0    = 14
-ARG_Z1    = 15
-ARG_Z2    = 16
-ARG_Z3    = 17
-
-
-md5_core_asm:
-       push r16
-       push r17
-       push_range 4, 8
-       ldi r30, lo8(T_table)
-       ldi r31, hi8(T_table)
-       lsl P_I
-       rol r1
-       lsl P_I
-       rol r1
-       add r30, P_I
-       adc r31, r1
-       clr r1
-       mov FI_SAVE, r18
-       /* loading T[i] into ACCU */    
-       lpm ACCU0, Z+   
-       lpm ACCU1, Z+   
-       lpm ACCU2, Z+   
-       lpm ACCU3, Z
-       /* add *block to ACCU */
-       movw r30, P_B0
-       ld r0, Z+
-       add ACCU0, r0
-       ld r0, Z+
-       adc ACCU1, r0
-       ld r0, Z+
-       adc ACCU2, r0
-       ld r0, Z+
-       adc ACCU3, r0
-       /* add a[as+0&3] to ACCU */
-       ldi r30, lo8(as_table)
-       ldi r31, hi8(as_table)
-       dec P_AS
-       andi P_AS, 0x03
-       lsl P_AS
-       lsl P_AS
-       add r30, r21
-       adc r31, r1       ; Z points to the correct row in as_table
-       lpm AS_SAVE0, Z+
-       lpm AS_SAVE1, Z+
-       lpm AS_SAVE2, Z+
-       lpm AS_SAVE3, Z
-       movw r26, r24     ; X points to a[0]
-       add r26, AS_SAVE0
-       adc r27, r1       ; X points at a[as&3]
-       ld r0, X+
-       add ACCU0, r0
-       ld r0, X+
-       adc ACCU1, r0
-       ld r0, X+
-       adc ACCU2, r0
-       ld r0, X+
-       adc ACCU3, r0
-       mov S_SAVE, r20
-
-       movw r28, r24
-       /* loading z value */
-       movw r26, r28
-       add r26, AS_SAVE1
-       adc r27, r1
-       ld ARG_Z0, X+
-       ld ARG_Z1, X+
-       ld ARG_Z2, X+
-       ld ARG_Z3, X
-
-       /* loading x value */
-       movw r26, r28   
-       add r26, AS_SAVE2
-       adc r27, r1
-       ld ARG_X0, X+
-       ld ARG_X1, X+
-       ld ARG_X2, X+
-       ld ARG_X3, X
-
-       /* loading y value */
-       movw r26, r28
-       add r26, AS_SAVE3
-       adc r27, r1
-       ldi r30, pm_lo8(jump_table)
-       ldi r31, pm_hi8(jump_table)
-       add r30, FI_SAVE
-       adc r31, r1    ; Z points to the correct entry in our jump table
-       ld ARG_Y0, X+
-       ld ARG_Y1, X+
-       ld ARG_Y2, X+
-       ld ARG_Y3, X
-
-       ijmp /* calls the function pointed by Z */
-md5_core_F_exit:               
-
-       /* add ACCU to result of f() */
-       add r22, ACCU0
-       adc r23, ACCU1
-       adc r24, ACCU2
-       adc r25, ACCU3
-
-       /* rotate */
-       mov r20, S_SAVE
-rotl32:
-       cpi r20, 8
-       brlo bitrotl
-       mov r21, r25
-       mov r25, r24
-       mov r24, r23
-       mov r23, r22
-       mov r22, r21
-       subi r20, 8
-       rjmp rotl32
-bitrotl:
-       mov r21, r25
-bitrotl_loop:  
-       tst r20
-       breq fixrotl
-bitrotl_loop2: 
-       lsl r21
-       rol r22
-       rol r23
-       rol r24
-       rol r25
-       dec r20
-       brne bitrotl_loop2
-fixrotl:
-
-       /* add a[(as+1)&3]  */
-       movw r26, r28
-       add r26, AS_SAVE2
-       adc r27, r1
-       ld r0, X+
-       add r22, r0
-       ld r0, X+
-       adc r23, r0
-       ld r0, X+
-       adc r24, r0
-       ld r0, X
-       adc r25, r0
-
-       /* store result */
-       movw r26, r28
-       add r26, AS_SAVE0
-       adc r27, r1
-       st X+, r22
-       st X+, r23
-       st X+, r24
-       st X , r25      
-md5_core_exit:
-       pop_range 4, 8
-       pop r17
-       pop r16
-       ret
-
-;###################################################################
-/*
-void md5_nextBlock(md5_ctx_t *state, void* block){
-       uint32_t        a[4];
-       uint8_t         m,n,i=0;
-
-       a[0]=state->a[0];
-       a[1]=state->a[1];
-       a[2]=state->a[2];
-       a[3]=state->a[3];
-       
-       / * round 1 * /
-       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
-               }
-       }
-       / * round 2 * /
-       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
-               }
-       }
-       / * round 3 * /
-       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
-               }
-       }
-       / * round 4 * /
-       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
-               }
-       }
-       state->a[0] += a[0];
-       state->a[1] += a[1];
-       state->a[2] += a[2];
-       state->a[3] += a[3];
-       state->counter++;
-}
-*/
-
-shift_table_1:  .byte  7,12,17,22
-shift_table_2:  .byte  5, 9,14,20
-shift_table_3:  .byte  4,11,16,23
-shift_table_4:  .byte  6,10,15,21
-
-index_table_r2:
-;(1+m*4+n*5)&0xf:
-        .byte 0x04, 0x18, 0x2c, 0x00 
-        .byte 0x14, 0x28, 0x3c, 0x10 
-        .byte 0x24, 0x38, 0x0c, 0x20 
-        .byte 0x34, 0x08, 0x1c, 0x30 
-
-index_table_r3:
-;(5-m*4+n*3)&0xf:
-        .byte 0x14, 0x20, 0x2c, 0x38 
-        .byte 0x04, 0x10, 0x1c, 0x28 
-        .byte 0x34, 0x00, 0x0c, 0x18 
-        .byte 0x24, 0x30, 0x3c, 0x08 
-
-index_table_r4:
-;(0-m*4+n*7)&0xf:
-        .byte 0x00, 0x1c, 0x38, 0x14 
-        .byte 0x30, 0x0c, 0x28, 0x04 
-        .byte 0x20, 0x3c, 0x18, 0x34 
-        .byte 0x10, 0x2c, 0x08, 0x24
-
-APTR_REG = 2
-BPTR_REG = 4
-N_REG = 6
-M_REG = 7
-I_REG = 8
-.global md5_nextBlock
-md5_nextBlock:
-       stack_alloc 16
-       push_range 2, 17
-       push r28
-       push r29
-       push r24
-       push r25
-       adiw r30, 1 /* Z now points to the beginning of the allocated memory */
-       movw r2, r30
-       movw r4, r22
-       movw r26, r24
-       ldi r20, 16
-1:
-       ld r0, X+
-       st Z+, r0
-       dec r20
-       brne 1b
-       /* state now copied to stack memory */
-       clr I_REG       
-       /* Round 1 */
-       clr M_REG
-       ldi r17, 4
-1:
-       clr N_REG       
-       ldi r16, 4
-2:
-       movw r24, APTR_REG
-       movw r22, BPTR_REG 
-       mov r0, M_REG
-       lsl r0
-       lsl r0
-       add r0, N_REG
-       lsl r0
-       lsl r0
-       add r22, r0
-       adc r23, r1
-       mov r21, r16    
-       ldi r30, lo8(shift_table_1)
-       ldi r31, hi8(shift_table_1)
-       add r30, N_REG
-       adc r31, r1
-       lpm r20, Z
-       mov r19, I_REG
-       ldi r18, 0
-       rcall md5_core_asm
-       inc I_REG
-       inc N_REG
-       dec r16
-       brne 2b
-       inc M_REG
-       dec r17
-       brne 1b
-       
-       /* Round 2 */
-       clr M_REG
-       ldi r17, 4
-1:
-       clr N_REG       
-       ldi r16, 4
-2:
-       movw r24, APTR_REG
-       movw r22, BPTR_REG 
-       ldi r30, lo8(index_table_r2)
-       ldi r31, hi8(index_table_r2)
-       mov r0, M_REG
-       lsl r0
-       lsl r0
-       add r0, N_REG
-       add r30, r0
-       adc r31, r1
-       lpm r0, Z       
-       add r22, r0
-       adc r23, r1
-       mov r21, r16    
-       ldi r30, lo8(shift_table_2)
-       ldi r31, hi8(shift_table_2)
-       add r30, N_REG
-       adc r31, r1
-       lpm r20, Z
-       mov r19, I_REG
-       ldi r18, 1
-       rcall md5_core_asm
-       inc I_REG
-       inc N_REG
-       dec r16
-       brne 2b
-       inc M_REG
-       dec r17
-       brne 1b
-
-       /* Round 3 */
-       clr M_REG
-       ldi r17, 4
-1:
-       clr N_REG       
-       ldi r16, 4
-2:
-       movw r24, APTR_REG
-       movw r22, BPTR_REG 
-       ldi r30, lo8(index_table_r3)
-       ldi r31, hi8(index_table_r3)
-       mov r0, M_REG
-       lsl r0
-       lsl r0
-       add r0, N_REG
-       add r30, r0
-       adc r31, r1
-       lpm r0, Z       
-       add r22, r0
-       adc r23, r1
-       mov r21, r16    
-       ldi r30, lo8(shift_table_3)
-       ldi r31, hi8(shift_table_3)
-       add r30, N_REG
-       adc r31, r1
-       lpm r20, Z
-       mov r19, I_REG
-       ldi r18, 2
-       rcall md5_core_asm
-       inc I_REG
-       inc N_REG
-       dec r16
-       brne 2b
-       inc M_REG
-       dec r17
-       brne 1b
-
-       /* Round 4 */
-       clr M_REG
-       ldi r17, 4
-1:
-       clr N_REG       
-       ldi r16, 4
-2:
-       movw r24, APTR_REG
-       movw r22, BPTR_REG 
-       ldi r30, lo8(index_table_r4)
-       ldi r31, hi8(index_table_r4)
-       mov r0, M_REG
-       lsl r0
-       lsl r0
-       add r0, N_REG
-       add r30, r0
-       adc r31, r1
-       lpm r0, Z       
-       add r22, r0
-       adc r23, r1
-       mov r21, r16    
-       ldi r30, lo8(shift_table_4)
-       ldi r31, hi8(shift_table_4)
-       add r30, N_REG
-       adc r31, r1
-       lpm r20, Z
-       mov r19, I_REG
-       ldi r18, 3
-       rcall md5_core_asm
-       inc I_REG
-       inc N_REG
-       dec r16
-       brne 2b
-       inc M_REG
-       dec r17
-       brne 1b
-
-
-       pop r27
-       pop r26 /* X now points to the context */
-       movw r30, APTR_REG
-       ldi r16, 4
-1:
-       ld r0, X
-       ld r2, Z+
-       add r0, r2
-       st X+, r0       
-       ld r0, X
-       ld r2, Z+
-       adc r0, r2
-       st X+, r0       
-       ld r0, X
-       ld r2, Z+
-       adc r0, r2
-       st X+, r0       
-       ld r0, X
-       ld r2, Z+
-       adc r0, r2
-       st X+, r0       
-       dec r16
-       brne 1b
-
-       ld r0, X
-       inc r0
-       st X+, r0       
-       brne 2f
-       ld r0, X
-       inc r0
-       st X+, r0       
-       brne 2f
-       ld r0, X
-       inc r0
-       st X+, r0       
-       brne 2f 
-       ld r0, X
-       inc r0
-       st X+, r0       
-2:                     
-
-       pop r29
-       pop r28
-       pop_range 2, 17
-       stack_free 16
-       ret
-
-;###############################################################################
-/*
-void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
-       uint16_t l;
-       uint8_t b[64];
-       while (length_b >= 512){
-               md5_nextBlock(state, block);
-               length_b -= 512;
-               block = ((uint8_t*)block) + 512/8;
-       }
-       memset(b, 0, 64);
-       memcpy(b, block, length_b/8);
-       / * insert padding one * /
-       l=length_b/8;
-       if(length_b%8){
-               uint8_t t;
-               t = ((uint8_t*)block)[l];
-               t |= (0x80>>(length_b%8));
-               b[l]=t;
-       }else{
-               b[l]=0x80;
-       }
-       / * insert length value * /
-       if(l+sizeof(uint64_t) >= 512/8){
-               md5_nextBlock(state, b);
-               state->counter--;
-               memset(b, 0, 64-8);
-       }
-       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
-       md5_nextBlock(state, b);
-}
-*/
-; state_ptr : r24,r25
-; block_ptr : r22,r23
-; length_b  : r20,r21
-.global md5_lastBlock
-md5_lastBlock:
-       stack_alloc_large 64
-       push_range 12, 17
-       push r30
-       push r31
-       movw r16, r20 /* length_b  */ 
-       movw r14, r22 /* block_ptr */
-       movw r12, r24 /* state_ptr */
-       ldi r18, 64
-2:
-       cpi r17, 2 /* hi8(512) */       
-       brlo 2f
-1:
-       movw r24, r12
-       movw r22, r14
-       rcall md5_nextBlock
-       add r14, r18
-       adc r15, r1
-       subi r17, 2
-       rjmp 2b
-2:
-       pop r31
-       pop r30
-
-       adiw r30, 1 /* adjust Z to point to buffer */
-       movw r26, r14
-       movw r24, r16
-       adiw r24, 7
-
-       lsr r25
-       ror r24
-       lsr r25
-       ror r24
-       lsr r24 /* r24 now holds how many bytes are to copy */
-    ldi r18, 64
-       sub r18, r24 /* r18 will hold the amount of used bytes in buffer */
-       tst r24
-4:
-       breq 5f
-       ld r0, X+
-       st Z+, r0 
-       dec r24
-       rjmp 4b /* Z points to the byte after msg in buffer */
-5:     /* append 1-bit */
-       mov r20, r16
-       ldi r19, 0x80
-       andi r20, 0x07
-       brne bit_fucking
-       st Z+, r19
-       dec r18 /* 'allocate' another byte in buffer */
-       rjmp after_bit_fucking
-bit_fucking:
-1:
-       lsr r19
-       dec r20
-       brne 1b
-       or r0, r19
-       st -Z, r0
-    adiw r30, 1
-after_bit_fucking:
-       clt     
-       cpi r18, 8
-       brmi 2f
-       set         /* store in t if the counter will also fit in this block (1 if fit)*/
-2:
-       tst r18
-       breq 2f
-1: /* fill remaning buffer with zeros */
-       st Z+, r1
-       dec r18
-       brne 1b
-2:
-       sbiw r30, 63
-       sbiw r30,  1
-       movw r14, r30 /* r14:r15 now points to buffer */        
-       brts load_counter
-       /* counter does not fit, finalize this block */
-       movw r24, r12
-       movw r22, r14
-       rcall md5_nextBlock
-       movw r30, r14
-       ldi r20, 64-8
-3:
-       st Z+, r1
-       dec r20
-       brne 3b
-       
-load_counter:          
-       movw r26, r12 /* X points to state */
-       adiw r26, 16
-       ld r19, X+
-       ld r20, X+
-       ld r21, X+
-       ld r22, X+
-       brts post_counter_decrement     /* do not decremen because counter fits */
-counter_decrement:
-       subi r19, 1
-       sbci r20, 0
-       sbci r21, 0
-       sbci r22, 0
-post_counter_decrement:
-       clr r18
-       clr r23
-       lsl r19
-       rol r20
-       rol r21
-       rol r22
-       rol r23
-       mov r18, r16 /* r16:r17 length_b */
-       add r19, r17
-       adc r20, r1
-       adc r21, r1
-       adc r22, r1
-       adc r23, r1
-       movw r30, r14
-       adiw r30, 64-8
-       st Z+, r18
-       st Z+, r19
-       st Z+, r20
-       st Z+, r21
-       st Z+, r22
-       st Z+, r23
-       st Z+, r1
-       st Z, r1
-
-       sbiw r30, 63
-;      sbiw r30, 1
-       movw r24, r12
-       movw r22, r30
-       rcall md5_nextBlock
-md5_lastBlock_exit:    
-       pop_range 12, 17
-       stack_free_large 64
-       ret
-
-
-;###############################################################################
-
-
-.global md5_ctx2hash
-md5_ctx2hash:
-       movw r26, r24
-       movw r30, r22
-       ldi r22, 16
-1:
-       ld r0, Z+
-       st X+, r0
-       dec r22
-       brne 1b 
-       ret
-
-
-;###############################################################################
-
-
-.global md5
-md5:
-       stack_alloc 20
-       push_range  8, 17
-       adiw r30, 1
-       movw  r8, r30 /* ctx           */
-       movw r10, r24 /* dest          */
-       movw r12, r22 /* msg           */
-       movw r14, r18 /* length (low)  */
-       movw r16, r20 /* length (high) */
-       movw r24, r30
-       rcall md5_init
-1:
-       tst r16
-       brne next_round
-       tst r17
-       breq last_round
-next_round:
-       movw r24,  r8
-       movw r22, r12
-       rcall md5_nextBlock
-       ldi r22, 64
-       add r12, r22
-       adc r13, r1
-       ldi r22, 2
-       sub r15, r22
-       sbci r16, 0
-       sbci r17, 0
-       rjmp 1b
-last_round:            
-       movw r24, r8
-       movw r22, r12
-       movw r20, r14
-       rcall md5_lastBlock
-       movw r24, r10
-       movw r22,  r8
-       rcall md5_ctx2hash
-       pop_range  8, 17
-       stack_free 20
-       ret
-
-
-
diff --git a/md5.c b/md5.c
deleted file mode 100644 (file)
index 003699e..0000000
--- a/md5.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* md5.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * \file       md5.c
- * \author     Daniel Otte
- * \date       2006-07-31
- * \license GPLv3 or later
- * \brief   Implementation of the MD5 hash algorithm as described in RFC 1321
- * 
- */
-
- #include "md5.h"
- #include "md5_sbox.h"
- #include "cli.h" 
- #include <stdint.h>
- #include <string.h>
- #undef DEBUG
-void md5_init(md5_ctx_t *s){
-       s->counter = 0;
-       s->a[0] = 0x67452301;
-       s->a[1] = 0xefcdab89;
-       s->a[2] = 0x98badcfe;
-       s->a[3] = 0x10325476;
-}
-
-static 
-uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
-       return ((x&y)|((~x)&z));
-}
-
-static
-uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
-       return ((x&z)|((~z)&y));
-}
-
-static
-uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
-       return (x^y^z);
-}
-
-static
-uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
-       return (y ^ (x | (~z)));
-}
-
-typedef uint32_t md5_func_t(uint32_t, uint32_t, uint32_t);
-
-#define ROTL32(x,n) (((x)<<(n)) | ((x)>>(32-(n))))  
-
-static
-void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
-       uint32_t t;
-       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
-       as &= 0x3;
-       /* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#ifdef DEBUG
-       char funcc[]={'*', '-', '+', '~'};
-       cli_putstr("\r\n DBG: md5_core [");
-       cli_putc(funcc[fi]);
-       cli_hexdump(&as, 1); cli_putc(' ');
-       cli_hexdump(&k, 1); cli_putc(' ');
-       cli_hexdump(&s, 1); cli_putc(' ');
-       cli_hexdump(&i, 1); cli_putc(']');
-#endif 
-       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) 
-           + *((uint32_t*)block) + pgm_read_dword(md5_T+i) ;
-       a[as]=a[(as+1)&3] + ROTL32(t, s);
-}
-
-void md5_nextBlock(md5_ctx_t *state, const void* block){
-       uint32_t        a[4];
-       uint8_t         m,n,i=0;
-       /* this requires other mixed sboxes */
-#ifdef DEBUG
-       cli_putstr("\r\n DBG: md5_nextBlock: block:\r\n");
-       cli_hexdump(block, 16); cli_putstr("\r\n");
-       cli_hexdump(block+16, 16);      cli_putstr("\r\n");
-       cli_hexdump(block+32, 16);      cli_putstr("\r\n");
-       cli_hexdump(block+48, 16);      cli_putstr("\r\n");
-#endif 
-       
-       a[0]=state->a[0];
-       a[1]=state->a[1];
-       a[2]=state->a[2];
-       a[3]=state->a[3];
-       
-       /* round 1 */
-       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
-               }
-       }
-       /* round 2 */
-       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
-               }
-       }
-       /* round 3 */
-       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
-               }
-       }
-       /* round 4 */
-       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
-       for(m=0;m<4;++m){
-               for(n=0;n<4;++n){
-                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
-               }
-       }
-       state->a[0] += a[0];
-       state->a[1] += a[1];
-       state->a[2] += a[2];
-       state->a[3] += a[3];
-       state->counter++;
-}
-
-void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
-       uint16_t l;
-       uint8_t b[64];
-       while (length_b >= 512){
-               md5_nextBlock(state, block);
-               length_b -= 512;
-               block = ((uint8_t*)block) + 512/8;
-       }
-       memset(b, 0, 64);
-       memcpy(b, block, length_b/8);
-       /* insert padding one */
-       l=length_b/8;
-       if(length_b%8){
-               uint8_t t;
-               t = ((uint8_t*)block)[l];
-               t |= (0x80>>(length_b%8));
-               b[l]=t;
-       }else{
-               b[l]=0x80;
-       }
-       /* insert length value */
-       if(l+sizeof(uint64_t) >= 512/8){
-               md5_nextBlock(state, b);
-               state->counter--;
-               memset(b, 0, 64-8);
-       }
-       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
-       md5_nextBlock(state, b);
-}
-
-void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state){
-       memcpy(dest, state->a, MD5_HASH_BYTES);
-}
-
-void md5(md5_hash_t* dest, const void* msg, uint32_t length_b){
-       md5_ctx_t ctx;
-       md5_init(&ctx);
-       while(length_b>=MD5_BLOCK_BITS){
-               md5_nextBlock(&ctx, msg);
-               msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
-               length_b -= MD5_BLOCK_BITS;
-       }
-       md5_lastBlock(&ctx, msg, length_b);
-       md5_ctx2hash(dest, &ctx);
-}
-
diff --git a/md5.h b/md5.h
deleted file mode 100644 (file)
index 6b65c4a..0000000
--- a/md5.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* md5.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * 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_
-
-#include <stdint.h>
-
-
-#define MD5_HASH_BITS  128
-#define MD5_HASH_BYTES (MD5_HASH_BITS/8)
-#define MD5_BLOCK_BITS 512
-#define MD5_BLOCK_BYTES (MD5_BLOCK_BITS/8)
-
-
-typedef struct md5_ctx_st {
-       uint32_t a[4];
-       uint32_t counter;
-} md5_ctx_t;
-
-typedef uint8_t md5_hash_t[MD5_HASH_BYTES];
-
-void md5_init(md5_ctx_t *s);
-void md5_nextBlock(md5_ctx_t *state, const void* block);
-void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length);
-void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state);
-void md5(md5_hash_t* dest, const void* msg, uint32_t length_b);
-
-#endif /*MD5_H_*/
diff --git a/md5/md5-asm.S b/md5/md5-asm.S
new file mode 100644 (file)
index 0000000..de3b170
--- /dev/null
@@ -0,0 +1,977 @@
+/* md5-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:  Daniel Otte
+ * License: GPLv3 or later
+ * Date:    2008-11-15
+*/
+
+
+#include "avr-asm-macros.S"
+
+;###########################################################   
+; S-BOX
+
+T_table:
+.hword 0xa478, 0xd76a, 0xb756, 0xe8c7, 0x70db, 0x2420, 0xceee, 0xc1bd, 0x0faf, 0xf57c 
+.hword 0xc62a, 0x4787, 0x4613, 0xa830, 0x9501, 0xfd46, 0x98d8, 0x6980, 0xf7af, 0x8b44 
+.hword 0x5bb1, 0xffff, 0xd7be, 0x895c, 0x1122, 0x6b90, 0x7193, 0xfd98, 0x438e, 0xa679 
+.hword 0x0821, 0x49b4, 0x2562, 0xf61e, 0xb340, 0xc040, 0x5a51, 0x265e, 0xc7aa, 0xe9b6 
+.hword 0x105d, 0xd62f, 0x1453, 0x0244, 0xe681, 0xd8a1, 0xfbc8, 0xe7d3, 0xcde6, 0x21e1 
+.hword 0x07d6, 0xc337, 0x0d87, 0xf4d5, 0x14ed, 0x455a, 0xe905, 0xa9e3, 0xa3f8, 0xfcef 
+.hword 0x02d9, 0x676f, 0x4c8a, 0x8d2a, 0x3942, 0xfffa, 0xf681, 0x8771, 0x6122, 0x6d9d 
+.hword 0x380c, 0xfde5, 0xea44, 0xa4be, 0xcfa9, 0x4bde, 0x4b60, 0xf6bb, 0xbc70, 0xbebf 
+.hword 0x7ec6, 0x289b, 0x27fa, 0xeaa1, 0x3085, 0xd4ef, 0x1d05, 0x0488, 0xd039, 0xd9d4 
+.hword 0x99e5, 0xe6db, 0x7cf8, 0x1fa2, 0x5665, 0xc4ac, 0x2244, 0xf429, 0xff97, 0x432a 
+.hword 0x23a7, 0xab94, 0xa039, 0xfc93, 0x59c3, 0x655b, 0xcc92, 0x8f0c, 0xf47d, 0xffef 
+.hword 0x5dd1, 0x8584, 0x7e4f, 0x6fa8, 0xe6e0, 0xfe2c, 0x4314, 0xa301, 0x11a1, 0x4e08 
+.hword 0x7e82, 0xf753, 0xf235, 0xbd3a, 0xd2bb, 0x2ad7, 0xd391, 0xeb86
+
+
+#define MD5_init_fast
+
+.global md5_init 
+#ifndef MD5_init_fast
+;###########################################################   
+;void md5_init(md5_ctx_t *state)
+; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), X(r25,r26)
+; size = 9+5*4 WORDS = 29 WORDS = 58 Bytes
+md5_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8(md5_init_vector)
+       ldi r31, hi8(md5_init_vector)
+       ldi r24, 16+4
+md5_init_vloop:        
+       lpm r0, Z+ 
+       st X+, r0
+       dec r24
+       brne md5_init_vloop
+       ret
+       
+md5_init_vector:
+.hword 0x2301, 0x6745
+.hword 0xAB89, 0xEFCD 
+.hword 0xDCFE, 0x98BA 
+.hword 0x5476, 0x1032 
+.hword 0x0000, 0x0000
+
+#else
+;###########################################################   
+.global md5_init_fast 
+;void md5_init(md5_ctx_t *state)
+; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: r23, r22
+; cycles = 1+16*3+4*2+4 = 1+48+12 = 61
+; size = 1+16*2+4+1 WORDS = 38 WORDS = 76 Bytes
+md5_init:
+md5_init_fast:
+       movw r26, r24
+       ldi r24, 0x01
+       st X+, r24
+       ldi r24, 0x23
+       st X+, r24
+       ldi r24, 0x45
+       st X+, r24
+       ldi r24, 0x67
+       st X+, r24
+       ldi r24, 0x89
+       st X+, r24
+       ldi r24, 0xAB
+       st X+, r24
+       ldi r24, 0xCD
+       st X+, r24
+       ldi r24, 0xEF
+       st X+, r24
+       ldi r24, 0xFE
+       st X+, r24
+       ldi r24, 0xDC
+       st X+, r24
+       ldi r24, 0xBA
+       st X+, r24
+       ldi r24, 0x98
+       st X+, r24
+       ldi r24, 0x76
+       st X+, r24
+       ldi r24, 0x54
+       st X+, r24
+       ldi r24, 0x32
+       st X+, r24
+       ldi r24, 0x10
+       st X+, r24
+       st X+, r1
+       st X+, r1
+       st X+, r1
+       st X+, r1
+       ret
+#endif
+;###########################################################   
+
+/*
+static 
+uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)|((~x)&z));
+}
+*/
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_F:
+       and r18, r22
+       and r19, r23
+       and r20, r24
+       and r21, r25
+       com r22
+       com r23
+       com r24
+       com r25
+       and r22, r14
+       and r23, r15
+       and r24, r16
+       and r25, r17
+       or  r22, r18
+       or  r23, r19
+       or  r24, r20
+       or  r25, r21
+       rjmp md5_core_F_exit
+       
+/*
+static
+uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&z)|((~z)&y));
+}
+*/
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_G:
+       and r22, r14
+       and r23, r15
+       and r24, r16
+       and r25, r17
+       com r14
+       com r15
+       com r16
+       com r17
+       and r18, r14
+       and r19, r15
+       and r20, r16
+       and r21, r17
+       or  r22, r18
+       or  r23, r19
+       or  r24, r20
+       or  r25, r21
+       rjmp md5_core_F_exit
+/*
+static
+uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
+       return (x^y^z);
+}
+*/
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_H:
+       eor r22, r18
+       eor r22, r14
+       eor r23, r19
+       eor r23, r15
+       eor r24, r20
+       eor r24, r16
+       eor r25, r21
+       eor r25, r17
+       rjmp md5_core_F_exit
+/*
+static
+uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
+       return (y ^ (x | (~z)));
+}
+*/
+
+jump_table:
+       rjmp md5_F
+       rjmp md5_G
+       rjmp md5_H
+;      rjmp md5_I
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+md5_I:
+       com r14
+       com r15
+       com r16
+       com r17
+       or  r22, r14
+       or  r23, r15
+       or  r24, r16
+       or  r25, r17
+       eor r22, r18
+       eor r23, r19
+       eor r24, r20
+       eor r25, r21
+       rjmp md5_core_F_exit
+
+as_table:
+;     (as+0)&3  (as+3)&3  (as+1)&3  (as+2)&3
+;                  Z         X         Y
+;     AS_SAVE0  AS_SAVE1  AS_SAVE2  AS_SAVE3 
+.byte   1*4,      0*4,      2*4,      3*4    ;as=1
+.byte   2*4,      1*4,      3*4,      0*4    ;as=2
+.byte   3*4,      2*4,      0*4,      1*4    ;as=3
+.byte   0*4,      3*4,      1*4,      2*4    ;as=4
+
+;###########################################################   
+.global md5_core
+md5_core:
+       mov r21, r20
+       mov r20, r18
+       mov r19, r16
+       mov r18, r14
+;      rjmp md5_core_asm
+/*
+void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
+       uint32_t t;
+       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
+       as &= 0x3;
+       / * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). * /
+       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) + *((uint32_t*)block) + md5_T[i] ;
+       a[as]=a[(as+1)&3] + ROTL32(t, s);
+}
+*/
+; a:     r24-r25
+; block: r22-r23
+; as:    r21
+; s:     r20
+; i:     r19
+; fi:    r18
+P_A0 = 24
+P_A1 = 25
+P_B0 = 22
+P_B1 = 23
+P_AS = 21
+P_S  = 20
+P_I  = 19
+P_FI = 18
+
+; x: r22-r25
+; y: r18-r21
+; z: r14-r17
+
+
+AS_SAVE0  =  4
+AS_SAVE1  =  5
+AS_SAVE2  =  6
+AS_SAVE3  =  7
+FI_SAVE   =  8
+S_SAVE    =  9
+ACCU0     = 10
+ACCU1     = 11
+ACCU2     = 12
+ACCU3     = 13
+ARG_X0    = 22
+ARG_X1    = 23
+ARG_X2    = 24
+ARG_X3    = 25
+ARG_Y0    = 18
+ARG_Y1    = 19
+ARG_Y2    = 20
+ARG_Y3    = 21
+ARG_Z0    = 14
+ARG_Z1    = 15
+ARG_Z2    = 16
+ARG_Z3    = 17
+
+
+md5_core_asm:
+       push r16
+       push r17
+       push_range 4, 8
+       ldi r30, lo8(T_table)
+       ldi r31, hi8(T_table)
+       lsl P_I
+       rol r1
+       lsl P_I
+       rol r1
+       add r30, P_I
+       adc r31, r1
+       clr r1
+       mov FI_SAVE, r18
+       /* loading T[i] into ACCU */    
+       lpm ACCU0, Z+   
+       lpm ACCU1, Z+   
+       lpm ACCU2, Z+   
+       lpm ACCU3, Z
+       /* add *block to ACCU */
+       movw r30, P_B0
+       ld r0, Z+
+       add ACCU0, r0
+       ld r0, Z+
+       adc ACCU1, r0
+       ld r0, Z+
+       adc ACCU2, r0
+       ld r0, Z+
+       adc ACCU3, r0
+       /* add a[as+0&3] to ACCU */
+       ldi r30, lo8(as_table)
+       ldi r31, hi8(as_table)
+       dec P_AS
+       andi P_AS, 0x03
+       lsl P_AS
+       lsl P_AS
+       add r30, r21
+       adc r31, r1       ; Z points to the correct row in as_table
+       lpm AS_SAVE0, Z+
+       lpm AS_SAVE1, Z+
+       lpm AS_SAVE2, Z+
+       lpm AS_SAVE3, Z
+       movw r26, r24     ; X points to a[0]
+       add r26, AS_SAVE0
+       adc r27, r1       ; X points at a[as&3]
+       ld r0, X+
+       add ACCU0, r0
+       ld r0, X+
+       adc ACCU1, r0
+       ld r0, X+
+       adc ACCU2, r0
+       ld r0, X+
+       adc ACCU3, r0
+       mov S_SAVE, r20
+
+       movw r28, r24
+       /* loading z value */
+       movw r26, r28
+       add r26, AS_SAVE1
+       adc r27, r1
+       ld ARG_Z0, X+
+       ld ARG_Z1, X+
+       ld ARG_Z2, X+
+       ld ARG_Z3, X
+
+       /* loading x value */
+       movw r26, r28   
+       add r26, AS_SAVE2
+       adc r27, r1
+       ld ARG_X0, X+
+       ld ARG_X1, X+
+       ld ARG_X2, X+
+       ld ARG_X3, X
+
+       /* loading y value */
+       movw r26, r28
+       add r26, AS_SAVE3
+       adc r27, r1
+       ldi r30, pm_lo8(jump_table)
+       ldi r31, pm_hi8(jump_table)
+       add r30, FI_SAVE
+       adc r31, r1    ; Z points to the correct entry in our jump table
+       ld ARG_Y0, X+
+       ld ARG_Y1, X+
+       ld ARG_Y2, X+
+       ld ARG_Y3, X
+
+       ijmp /* calls the function pointed by Z */
+md5_core_F_exit:               
+
+       /* add ACCU to result of f() */
+       add r22, ACCU0
+       adc r23, ACCU1
+       adc r24, ACCU2
+       adc r25, ACCU3
+
+       /* rotate */
+       mov r20, S_SAVE
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       mov r21, r25
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+bitrotl_loop2: 
+       lsl r21
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       dec r20
+       brne bitrotl_loop2
+fixrotl:
+
+       /* add a[(as+1)&3]  */
+       movw r26, r28
+       add r26, AS_SAVE2
+       adc r27, r1
+       ld r0, X+
+       add r22, r0
+       ld r0, X+
+       adc r23, r0
+       ld r0, X+
+       adc r24, r0
+       ld r0, X
+       adc r25, r0
+
+       /* store result */
+       movw r26, r28
+       add r26, AS_SAVE0
+       adc r27, r1
+       st X+, r22
+       st X+, r23
+       st X+, r24
+       st X , r25      
+md5_core_exit:
+       pop_range 4, 8
+       pop r17
+       pop r16
+       ret
+
+;###################################################################
+/*
+void md5_nextBlock(md5_ctx_t *state, void* block){
+       uint32_t        a[4];
+       uint8_t         m,n,i=0;
+
+       a[0]=state->a[0];
+       a[1]=state->a[1];
+       a[2]=state->a[2];
+       a[3]=state->a[3];
+       
+       / * round 1 * /
+       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
+               }
+       }
+       / * round 2 * /
+       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
+               }
+       }
+       / * round 3 * /
+       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
+               }
+       }
+       / * round 4 * /
+       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
+               }
+       }
+       state->a[0] += a[0];
+       state->a[1] += a[1];
+       state->a[2] += a[2];
+       state->a[3] += a[3];
+       state->counter++;
+}
+*/
+
+shift_table_1:  .byte  7,12,17,22
+shift_table_2:  .byte  5, 9,14,20
+shift_table_3:  .byte  4,11,16,23
+shift_table_4:  .byte  6,10,15,21
+
+index_table_r2:
+;(1+m*4+n*5)&0xf:
+        .byte 0x04, 0x18, 0x2c, 0x00 
+        .byte 0x14, 0x28, 0x3c, 0x10 
+        .byte 0x24, 0x38, 0x0c, 0x20 
+        .byte 0x34, 0x08, 0x1c, 0x30 
+
+index_table_r3:
+;(5-m*4+n*3)&0xf:
+        .byte 0x14, 0x20, 0x2c, 0x38 
+        .byte 0x04, 0x10, 0x1c, 0x28 
+        .byte 0x34, 0x00, 0x0c, 0x18 
+        .byte 0x24, 0x30, 0x3c, 0x08 
+
+index_table_r4:
+;(0-m*4+n*7)&0xf:
+        .byte 0x00, 0x1c, 0x38, 0x14 
+        .byte 0x30, 0x0c, 0x28, 0x04 
+        .byte 0x20, 0x3c, 0x18, 0x34 
+        .byte 0x10, 0x2c, 0x08, 0x24
+
+APTR_REG = 2
+BPTR_REG = 4
+N_REG = 6
+M_REG = 7
+I_REG = 8
+.global md5_nextBlock
+md5_nextBlock:
+       stack_alloc 16
+       push_range 2, 17
+       push r28
+       push r29
+       push r24
+       push r25
+       adiw r30, 1 /* Z now points to the beginning of the allocated memory */
+       movw r2, r30
+       movw r4, r22
+       movw r26, r24
+       ldi r20, 16
+1:
+       ld r0, X+
+       st Z+, r0
+       dec r20
+       brne 1b
+       /* state now copied to stack memory */
+       clr I_REG       
+       /* Round 1 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       lsl r0
+       lsl r0
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_1)
+       ldi r31, hi8(shift_table_1)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 0
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+       
+       /* Round 2 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r2)
+       ldi r31, hi8(index_table_r2)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_2)
+       ldi r31, hi8(shift_table_2)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 1
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+       /* Round 3 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r3)
+       ldi r31, hi8(index_table_r3)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_3)
+       ldi r31, hi8(shift_table_3)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 2
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+       /* Round 4 */
+       clr M_REG
+       ldi r17, 4
+1:
+       clr N_REG       
+       ldi r16, 4
+2:
+       movw r24, APTR_REG
+       movw r22, BPTR_REG 
+       ldi r30, lo8(index_table_r4)
+       ldi r31, hi8(index_table_r4)
+       mov r0, M_REG
+       lsl r0
+       lsl r0
+       add r0, N_REG
+       add r30, r0
+       adc r31, r1
+       lpm r0, Z       
+       add r22, r0
+       adc r23, r1
+       mov r21, r16    
+       ldi r30, lo8(shift_table_4)
+       ldi r31, hi8(shift_table_4)
+       add r30, N_REG
+       adc r31, r1
+       lpm r20, Z
+       mov r19, I_REG
+       ldi r18, 3
+       rcall md5_core_asm
+       inc I_REG
+       inc N_REG
+       dec r16
+       brne 2b
+       inc M_REG
+       dec r17
+       brne 1b
+
+
+       pop r27
+       pop r26 /* X now points to the context */
+       movw r30, APTR_REG
+       ldi r16, 4
+1:
+       ld r0, X
+       ld r2, Z+
+       add r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       ld r0, X
+       ld r2, Z+
+       adc r0, r2
+       st X+, r0       
+       dec r16
+       brne 1b
+
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f
+       ld r0, X
+       inc r0
+       st X+, r0       
+       brne 2f 
+       ld r0, X
+       inc r0
+       st X+, r0       
+2:                     
+
+       pop r29
+       pop r28
+       pop_range 2, 17
+       stack_free 16
+       ret
+
+;###############################################################################
+/*
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
+       uint16_t l;
+       uint8_t b[64];
+       while (length_b >= 512){
+               md5_nextBlock(state, block);
+               length_b -= 512;
+               block = ((uint8_t*)block) + 512/8;
+       }
+       memset(b, 0, 64);
+       memcpy(b, block, length_b/8);
+       / * insert padding one * /
+       l=length_b/8;
+       if(length_b%8){
+               uint8_t t;
+               t = ((uint8_t*)block)[l];
+               t |= (0x80>>(length_b%8));
+               b[l]=t;
+       }else{
+               b[l]=0x80;
+       }
+       / * insert length value * /
+       if(l+sizeof(uint64_t) >= 512/8){
+               md5_nextBlock(state, b);
+               state->counter--;
+               memset(b, 0, 64-8);
+       }
+       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
+       md5_nextBlock(state, b);
+}
+*/
+; state_ptr : r24,r25
+; block_ptr : r22,r23
+; length_b  : r20,r21
+.global md5_lastBlock
+md5_lastBlock:
+       stack_alloc_large 64
+       push_range 12, 17
+       push r30
+       push r31
+       movw r16, r20 /* length_b  */ 
+       movw r14, r22 /* block_ptr */
+       movw r12, r24 /* state_ptr */
+       ldi r18, 64
+2:
+       cpi r17, 2 /* hi8(512) */       
+       brlo 2f
+1:
+       movw r24, r12
+       movw r22, r14
+       rcall md5_nextBlock
+       add r14, r18
+       adc r15, r1
+       subi r17, 2
+       rjmp 2b
+2:
+       pop r31
+       pop r30
+
+       adiw r30, 1 /* adjust Z to point to buffer */
+       movw r26, r14
+       movw r24, r16
+       adiw r24, 7
+
+       lsr r25
+       ror r24
+       lsr r25
+       ror r24
+       lsr r24 /* r24 now holds how many bytes are to copy */
+    ldi r18, 64
+       sub r18, r24 /* r18 will hold the amount of used bytes in buffer */
+       tst r24
+4:
+       breq 5f
+       ld r0, X+
+       st Z+, r0 
+       dec r24
+       rjmp 4b /* Z points to the byte after msg in buffer */
+5:     /* append 1-bit */
+       mov r20, r16
+       ldi r19, 0x80
+       andi r20, 0x07
+       brne bit_fucking
+       st Z+, r19
+       dec r18 /* 'allocate' another byte in buffer */
+       rjmp after_bit_fucking
+bit_fucking:
+1:
+       lsr r19
+       dec r20
+       brne 1b
+       or r0, r19
+       st -Z, r0
+    adiw r30, 1
+after_bit_fucking:
+       clt     
+       cpi r18, 8
+       brmi 2f
+       set         /* store in t if the counter will also fit in this block (1 if fit)*/
+2:
+       tst r18
+       breq 2f
+1: /* fill remaning buffer with zeros */
+       st Z+, r1
+       dec r18
+       brne 1b
+2:
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r14, r30 /* r14:r15 now points to buffer */        
+       brts load_counter
+       /* counter does not fit, finalize this block */
+       movw r24, r12
+       movw r22, r14
+       rcall md5_nextBlock
+       movw r30, r14
+       ldi r20, 64-8
+3:
+       st Z+, r1
+       dec r20
+       brne 3b
+       
+load_counter:          
+       movw r26, r12 /* X points to state */
+       adiw r26, 16
+       ld r19, X+
+       ld r20, X+
+       ld r21, X+
+       ld r22, X+
+       brts post_counter_decrement     /* do not decremen because counter fits */
+counter_decrement:
+       subi r19, 1
+       sbci r20, 0
+       sbci r21, 0
+       sbci r22, 0
+post_counter_decrement:
+       clr r18
+       clr r23
+       lsl r19
+       rol r20
+       rol r21
+       rol r22
+       rol r23
+       mov r18, r16 /* r16:r17 length_b */
+       add r19, r17
+       adc r20, r1
+       adc r21, r1
+       adc r22, r1
+       adc r23, r1
+       movw r30, r14
+       adiw r30, 64-8
+       st Z+, r18
+       st Z+, r19
+       st Z+, r20
+       st Z+, r21
+       st Z+, r22
+       st Z+, r23
+       st Z+, r1
+       st Z, r1
+
+       sbiw r30, 63
+;      sbiw r30, 1
+       movw r24, r12
+       movw r22, r30
+       rcall md5_nextBlock
+md5_lastBlock_exit:    
+       pop_range 12, 17
+       stack_free_large 64
+       ret
+
+
+;###############################################################################
+
+
+.global md5_ctx2hash
+md5_ctx2hash:
+       movw r26, r24
+       movw r30, r22
+       ldi r22, 16
+1:
+       ld r0, Z+
+       st X+, r0
+       dec r22
+       brne 1b 
+       ret
+
+
+;###############################################################################
+
+
+.global md5
+md5:
+       stack_alloc 20
+       push_range  8, 17
+       adiw r30, 1
+       movw  r8, r30 /* ctx           */
+       movw r10, r24 /* dest          */
+       movw r12, r22 /* msg           */
+       movw r14, r18 /* length (low)  */
+       movw r16, r20 /* length (high) */
+       movw r24, r30
+       rcall md5_init
+1:
+       tst r16
+       brne next_round
+       tst r17
+       breq last_round
+next_round:
+       movw r24,  r8
+       movw r22, r12
+       rcall md5_nextBlock
+       ldi r22, 64
+       add r12, r22
+       adc r13, r1
+       ldi r22, 2
+       sub r15, r22
+       sbci r16, 0
+       sbci r17, 0
+       rjmp 1b
+last_round:            
+       movw r24, r8
+       movw r22, r12
+       movw r20, r14
+       rcall md5_lastBlock
+       movw r24, r10
+       movw r22,  r8
+       rcall md5_ctx2hash
+       pop_range  8, 17
+       stack_free 20
+       ret
+
+
+
diff --git a/md5/md5.c b/md5/md5.c
new file mode 100644 (file)
index 0000000..003699e
--- /dev/null
+++ b/md5/md5.c
@@ -0,0 +1,185 @@
+/* md5.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * \file       md5.c
+ * \author     Daniel Otte
+ * \date       2006-07-31
+ * \license GPLv3 or later
+ * \brief   Implementation of the MD5 hash algorithm as described in RFC 1321
+ * 
+ */
+
+ #include "md5.h"
+ #include "md5_sbox.h"
+ #include "cli.h" 
+ #include <stdint.h>
+ #include <string.h>
+ #undef DEBUG
+void md5_init(md5_ctx_t *s){
+       s->counter = 0;
+       s->a[0] = 0x67452301;
+       s->a[1] = 0xefcdab89;
+       s->a[2] = 0x98badcfe;
+       s->a[3] = 0x10325476;
+}
+
+static 
+uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&y)|((~x)&z));
+}
+
+static
+uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
+       return ((x&z)|((~z)&y));
+}
+
+static
+uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
+       return (x^y^z);
+}
+
+static
+uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
+       return (y ^ (x | (~z)));
+}
+
+typedef uint32_t md5_func_t(uint32_t, uint32_t, uint32_t);
+
+#define ROTL32(x,n) (((x)<<(n)) | ((x)>>(32-(n))))  
+
+static
+void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
+       uint32_t t;
+       md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
+       as &= 0x3;
+       /* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#ifdef DEBUG
+       char funcc[]={'*', '-', '+', '~'};
+       cli_putstr("\r\n DBG: md5_core [");
+       cli_putc(funcc[fi]);
+       cli_hexdump(&as, 1); cli_putc(' ');
+       cli_hexdump(&k, 1); cli_putc(' ');
+       cli_hexdump(&s, 1); cli_putc(' ');
+       cli_hexdump(&i, 1); cli_putc(']');
+#endif 
+       t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) 
+           + *((uint32_t*)block) + pgm_read_dword(md5_T+i) ;
+       a[as]=a[(as+1)&3] + ROTL32(t, s);
+}
+
+void md5_nextBlock(md5_ctx_t *state, const void* block){
+       uint32_t        a[4];
+       uint8_t         m,n,i=0;
+       /* this requires other mixed sboxes */
+#ifdef DEBUG
+       cli_putstr("\r\n DBG: md5_nextBlock: block:\r\n");
+       cli_hexdump(block, 16); cli_putstr("\r\n");
+       cli_hexdump(block+16, 16);      cli_putstr("\r\n");
+       cli_hexdump(block+32, 16);      cli_putstr("\r\n");
+       cli_hexdump(block+48, 16);      cli_putstr("\r\n");
+#endif 
+       
+       a[0]=state->a[0];
+       a[1]=state->a[1];
+       a[2]=state->a[2];
+       a[3]=state->a[3];
+       
+       /* round 1 */
+       uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
+               }
+       }
+       /* round 2 */
+       uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
+               }
+       }
+       /* round 3 */
+       uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
+               }
+       }
+       /* round 4 */
+       uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
+       for(m=0;m<4;++m){
+               for(n=0;n<4;++n){
+                       md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
+               }
+       }
+       state->a[0] += a[0];
+       state->a[1] += a[1];
+       state->a[2] += a[2];
+       state->a[3] += a[3];
+       state->counter++;
+}
+
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length_b){
+       uint16_t l;
+       uint8_t b[64];
+       while (length_b >= 512){
+               md5_nextBlock(state, block);
+               length_b -= 512;
+               block = ((uint8_t*)block) + 512/8;
+       }
+       memset(b, 0, 64);
+       memcpy(b, block, length_b/8);
+       /* insert padding one */
+       l=length_b/8;
+       if(length_b%8){
+               uint8_t t;
+               t = ((uint8_t*)block)[l];
+               t |= (0x80>>(length_b%8));
+               b[l]=t;
+       }else{
+               b[l]=0x80;
+       }
+       /* insert length value */
+       if(l+sizeof(uint64_t) >= 512/8){
+               md5_nextBlock(state, b);
+               state->counter--;
+               memset(b, 0, 64-8);
+       }
+       *((uint64_t*)&b[64-sizeof(uint64_t)]) = (state->counter * 512) + length_b;
+       md5_nextBlock(state, b);
+}
+
+void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state){
+       memcpy(dest, state->a, MD5_HASH_BYTES);
+}
+
+void md5(md5_hash_t* dest, const void* msg, uint32_t length_b){
+       md5_ctx_t ctx;
+       md5_init(&ctx);
+       while(length_b>=MD5_BLOCK_BITS){
+               md5_nextBlock(&ctx, msg);
+               msg = (uint8_t*)msg + MD5_BLOCK_BYTES;
+               length_b -= MD5_BLOCK_BITS;
+       }
+       md5_lastBlock(&ctx, msg, length_b);
+       md5_ctx2hash(dest, &ctx);
+}
+
diff --git a/md5/md5.h b/md5/md5.h
new file mode 100644 (file)
index 0000000..6b65c4a
--- /dev/null
+++ b/md5/md5.h
@@ -0,0 +1,55 @@
+/* md5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * 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_
+
+#include <stdint.h>
+
+
+#define MD5_HASH_BITS  128
+#define MD5_HASH_BYTES (MD5_HASH_BITS/8)
+#define MD5_BLOCK_BITS 512
+#define MD5_BLOCK_BYTES (MD5_BLOCK_BITS/8)
+
+
+typedef struct md5_ctx_st {
+       uint32_t a[4];
+       uint32_t counter;
+} md5_ctx_t;
+
+typedef uint8_t md5_hash_t[MD5_HASH_BYTES];
+
+void md5_init(md5_ctx_t *s);
+void md5_nextBlock(md5_ctx_t *state, const void* block);
+void md5_lastBlock(md5_ctx_t *state, const void* block, uint16_t length);
+void md5_ctx2hash(md5_hash_t* dest, const md5_ctx_t* state);
+void md5(md5_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*MD5_H_*/
diff --git a/md5/md5_sbox.h b/md5/md5_sbox.h
new file mode 100644 (file)
index 0000000..597b3db
--- /dev/null
@@ -0,0 +1,40 @@
+/* md5_sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef MD5_SBOX_H_
+#define MD5_SBOX_H_
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+uint32_t md5_T[] PROGMEM = {
+       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 
+       0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 
+       0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 
+       0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 
+       0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 
+       0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
+       0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 
+       0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 
+       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 
+       0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 
+       0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 
+       0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 
+       0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
+
+#endif /*MD5_SBOX_H_*/
diff --git a/md5_sbox.h b/md5_sbox.h
deleted file mode 100644 (file)
index 597b3db..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* md5_sbox.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef MD5_SBOX_H_
-#define MD5_SBOX_H_
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-
-uint32_t md5_T[] PROGMEM = {
-       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 
-       0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 
-       0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 
-       0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 
-       0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 
-       0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
-       0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 
-       0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 
-       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 
-       0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 
-       0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 
-       0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 
-       0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
-
-#endif /*MD5_SBOX_H_*/
diff --git a/mickey128.c b/mickey128.c
deleted file mode 100644 (file)
index d33571e..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * 
- * author: Daniel Otte
- * email:  daniel.otte@rub.de
- * license: GPLv3
- * 
- * */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "mickey128.h"
-#include "cli.h"
-/*
-RTAPS = { 0,4,5,  8,10,11,14  ,16,20,  25,30,  32,35,36,38,
-         42,43,46,  50,51,53,54,55,  56,57,60,61,62,63,  
-         65,66,69,  73,74,76,79,  80,81,82,85,86,  90,91,92,95,  
-         97,100,101,  105,106,107,108,109,111,  112,113,115,116,117,
-         127,  128,129,130,131,133,135,  136,137,140,142,  145,148,150,  
-         152,153,154,156,157 }
-         
-         0011.0001  0100.1101  0001.0001  0100.0010  0101.1001
-         0100.1100  1110.1100  1111.0011 
-         0010.0110  1001.0110  0110.0111  1001.1100 
-         0011.0010  1011.1110  0011.1011
-         1000.0000  1010.1111  0101.0011  0101.0010
-         0011.0111
-          
-         1000110010110010100010000100001010011010001100100011011111001111011001
-         0001101001111001100011100101001100011111011101110000000001111101011100
-         101001001010111011
-          
-         1000.1100 1011.0010 1000.1000 0100.0010 1001.1010 0011.0010 
-         0011.0111 1100.1111 0110.0100 0110.1001 1110.0110 0011.1001
-         0100.1100 0111.1101 1101.1100 0000.0001 1111.0101 1100.1010
-         0100.1010 1110.11
-*/
-
-uint8_t rtaps[] PROGMEM = {
-       0x31, 0x4D, 0x11, 0x42,
-       0x59, 0x4C, 0xEC, 0xF3,
-       0x26, 0x96, 0x67, 0x9C,
-       0x32, 0xBE, 0x3B, 0x80, 
-       0xAF, 0x53, 0x52, 0x37
-};
-       
-static 
-void memxor_P(void* d, PGM_VOID_P s, uint8_t length_B){
-       while(length_B--){
-               *((uint8_t*)d) ^= pgm_read_byte(s);
-               d = (uint8_t*)d +1;
-               s = (uint8_t*)s +1;
-       }
-}
-
-#define SHL0(a) c1=((a)>>7); (a)=(((a)<<1)|c0)
-#define SHL1(a) c0=((a)>>7); (a)=(((a)<<1)|c1)
-
-#define SHLX0(a) c1=((a)>>7); (a)^=(((a)<<1)|c0)
-#define SHLX1(a) c0=((a)>>7); (a)^=(((a)<<1)|c1)
-
-static
-void clock_r(uint8_t* r, uint8_t ibit, uint8_t cbit){
-       uint8_t i,c0=0,c1=0; /* carry */
-       ibit ^= ((r[159/8])>>(159%8))&1; /* ibit is now the same as feedback_bit */
-       if(cbit){
-               for(i=0; i<10; ++i){
-                       SHLX0(r[2*i+0]);
-                       SHLX1(r[2*i+1]);
-               }
-       } else {
-               for(i=0; i<10; ++i){
-                       SHL0(r[2*i+0]);
-                       SHL1(r[2*i+1]);
-               }
-       }
-       if(ibit){
-               memxor_P(r, rtaps, 20);
-       }
-}
-
-/* comp0 (filling spaces with zero) (one at each side)
- * 0101.1110 1111.0010 1101.0110 0101.1101 
- * 0101.0101 0000.1001 0010.0110 0111.1001
- * 0110.0010 0111.0000 0000.0000 0111.1001
- * 0011.0001 1101.1001 1010.1111 0011.0111
- * 1011.1110 0000.0110 1011.1110 0000.1111
- * --
- * 5E F2 D6 5D
- * 55 09 26 79
- * 62 70 00 79
- * 31 D9 AF 37
- * BE 06 BE 0F
- */ 
-uint8_t comp0[] PROGMEM = {
-       0x5E, 0xF2, 0xD6, 0x5D,
-       0x55, 0x09, 0x26, 0x79,
-       0x62, 0x70, 0x00, 0x79, 
-       0x31, 0xD9, 0xAF, 0x37, 
-       0xBE, 0x06, 0xBE, 0x0F
-};
-
-
-/* comp1 (shifting one bit right to make calculation easier, so inserting two zeros)
- * 0110.0000 0011.1110 0011.0010 1111.1010 
- * 0011.0000 0111.1001 0110.1100 1111.1101
- * 1100.0001 1000.0111 0000.0001 1111.1000
- * 1000.1010 1100.0110 1100.0001 1100.1100
- * 0110.1010 1011.0111 1110.1000 1111.1111
- * --
- * 60 3E 32 FA
- * 30 79 6C FD
- * C1 87 01 F8
- * 8A C6 C1 CC
- * 6A B7 E8 FF
-*/
-/*
-uint8_t comp1[] PROGMEM = {
-       0x60, 0x3E, 0x32, 0xFA, 0x30, 0x79, 0x6C, 0xFD, 0xC1, 0x87, 
-       0x01, 0xF8, 0x8A, 0xC6, 0xC1, 0xCC, 0x6A, 0xB7, 0xE8, 0xFF
-};
-*/
-/* comp1
- * 0000.1100 1111.1000 1001.1000 1011.1110
- * 0001.1001 0011.1100 0110.1101 0111.1111
- * 0000.0111 1100.0011 0000.0000 0011.1110
- * 1010.0010 1100.0111 0000.0110 0110.0110
- * 1010.1101 1101.1010 0010.1111 1111.1110
- * --
- * 0C F8 98 BE
- * 19 3C 6D 7F
- * 07 C3 00 3E
- * A2 C7 06 66
- * AD DA 2F FE
-*/
-/*
-uint8_t comp1[] PROGMEM = {
-       0x0C, 0xF8, 0x98, 0xBE, 0x19, 0x3C, 0x6D, 0x7F, 0x07, 0xC3,
-       0x00, 0x3E, 0xA2, 0xC7, 0x06, 0x66, 0xAD, 0xDA, 0x2F, 0xFE
-};
-*/
-/* comp1
- * 0011.0000 0001.1111 0001.1001 0111.1101
- * 1001.1000 0011.1100 1011.0110 1111.1110
- * 1110.0000 1100.0011 0000.0000 0111.1100
- * 0100.0101 1110.0011 0110.0000 0110.0110
- * 1011.0101 0101.1011 1111.0100 0111.1111
- * --
- * 30 1F 19 7D
- * 98 3C B6 FE
- * E0 C3 00 7C
- * 45 E3 60 66
- * B5 5B F4 7F
-*/
-
-uint8_t comp1[] PROGMEM = {
-       0x30, 0x1F, 0x19, 0x7D,
-       0x98, 0x3C, 0xB6, 0xFE, 
-       0xE0, 0xC3, 0x00, 0x7C, 
-       0x45, 0xE3, 0x60, 0x66, 
-       0xB5, 0x5B, 0xF4, 0x7F
-};
-
-/* fb0
- * 1010.1111 0001.1111 0011.1100 1100.0100
- * 0010.0010 1010.0011 0010.1111 0000.1110
- * 1000.0001 0100.1101 1110.0101 0110.0110
- * 1001.0001 0100.1011 0101.0100 1101.0100
- * 1100.0001 0000.1011 0110.0011 1000.0011
- * --
- * AF 1F 3C C4
- * 22 A3 2F 0E
- * 81 4D E5 66
- * 91 4B 54 D4
- * C1 0B 63 83
- */ 
-uint8_t fb0[] PROGMEM = {      
-       0xAF, 0x1F, 0x3C, 0xC4, 
-       0x22, 0xA3, 0x2F, 0x0E, 
-       0x81, 0x4D, 0xE5, 0x66, 
-       0x91, 0x4B, 0x54, 0xD4, 
-       0xC1, 0x0B, 0x63, 0x83
-};
-
-/* fb1
- * 1010.1011 0111.0111 1111.0100 1001.1011 
- * 1001.0000 1000.1100 0111.1001 0111.0000
- * 1011.0110 0001.1000 1001.1010 0110.1111
- * 1110.0111 0111.1110 0100.1011 0110.1100 
- * 1110.1111 1000.0000 1010.0111 0001.0001
- * --
- * AB 77 F4 9B
- * 90 8C 79 70
- * B6 18 9A 6F
- * E7 7E 4B 6C
- * EF 80 A7 11
- */ 
-uint8_t fb1[] PROGMEM = {
-       0xAB, 0x77, 0xF4, 0x9B, 
-       0x90, 0x8C, 0x79, 0x70, 
-       0xB6, 0x18, 0x9A, 0x6F, 
-       0xE7, 0x7E, 0x4B, 0x6C, 
-       0xEF, 0x80, 0xA7, 0x11
-};
-
-static
-void clock_s(uint8_t* s, uint8_t ibit, uint8_t cbit){
-       uint8_t s0[20], s1[20];
-       uint8_t i,c=0, c2=0;
-       ibit ^= (s[19])>>7;
-       memcpy(s0,s,20);
-       memxor_P(s0, comp0, 20);
-       for(i=0; i<20; ++i){
-               s1[19-i]= c|((s[19-i])>>1);
-               c = (s[19-i])<<7;
-       }
-       memxor_P(s1, comp1, 20);
-       c=0;
-       for(i=0; i<20; ++i){
-               c2=(s[i])>>7;
-               s[i]=((s[i])<<1) ^ ((s0[i])&(s1[i])) ^ c;
-               c=c2;
-       }
-       s[0] &= 0xFE;
-       if(ibit){
-               memxor_P(s, cbit?fb1:fb0, 20);
-       }
-}
-
-static
-void clock_kg(uint8_t* r, uint8_t* s, uint8_t mixing, uint8_t input){
-       uint8_t rb, sb;
-       rb = ((s[ 54/8])>>(( 54%8))) ^ ((r[106/8])>>(((106%8))));
-       sb = ((s[106/8])>>((106%8))) ^ ((r[ 53/8])>>((( 53%8))));
-       rb &= 1;
-       sb &= 1;
-       mixing = input ^ (mixing & ((s[80/8]>>((80%8))) & 1)); 
-       clock_r(r, mixing, rb);
-       clock_s(s, input, sb);
-}
-
-void mickey128_init(void* key, uint16_t keysize_b, 
-                    void* iv,  uint16_t ivsize_b, 
-                    mickey128_ctx_t* ctx){
-       uint16_t i;
-       memset(ctx->r, 0, 20);
-       memset(ctx->s, 0, 20);
-       for(i=0; i<ivsize_b; ++i){
-               clock_kg(ctx->r, ctx->s, 1, 1&((((uint8_t*)iv)[i/8])>>(7-(i%8))));
-       }
-       for(i=0; i<keysize_b; ++i){
-               clock_kg(ctx->r, ctx->s, 1, 1&((((uint8_t*)key)[i/8])>>(7-(i%8))));
-       }                  
-       for(i=0; i<160; ++i){
-               clock_kg(ctx->r, ctx->s, 1, 0);
-       }                  
-} 
-
-uint8_t mickey128_getbit(mickey128_ctx_t* ctx){
-       uint8_t ret;
-       ret = 1&(*(ctx->r) ^ *(ctx->s));
-       clock_kg(ctx->r, ctx->s, 0, 0);
-       return ret;
-}
-
-uint8_t mickey128_getbyte(mickey128_ctx_t* ctx){
-       uint8_t i,ret=0;
-       for(i=0; i<8; ++i){
-               ret<<=1;
-               ret |= 1&(((ctx->r)[0]) ^ ((ctx->s)[0]));
-               clock_kg(ctx->r, ctx->s, 0, 0);
-       }
-       return ret;
-}
-
-               
diff --git a/mickey128.h b/mickey128.h
deleted file mode 100644 (file)
index 9a125f4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef MICKEY128_H_
-#define MICKEY128_H_
-
-#include <stdint.h>
-
-typedef struct mickey128_ctx_st{
-       uint8_t r[20];
-       uint8_t s[20];
-} mickey128_ctx_t;
-
-void debug_clock_r(void);
-void debug_clock_s(void);
-void mickey128_init(void* key, uint16_t keysize_b, 
-                    void* iv,  uint16_t ivsize_b, 
-                    mickey128_ctx_t* ctx);
-uint8_t mickey128_getbit(mickey128_ctx_t* ctx);
-uint8_t mickey128_getbyte(mickey128_ctx_t* ctx);
-
-#endif /*MICKEY128_H_*/
diff --git a/mickey128/mickey128.c b/mickey128/mickey128.c
new file mode 100644 (file)
index 0000000..d33571e
--- /dev/null
@@ -0,0 +1,276 @@
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "mickey128.h"
+#include "cli.h"
+/*
+RTAPS = { 0,4,5,  8,10,11,14  ,16,20,  25,30,  32,35,36,38,
+         42,43,46,  50,51,53,54,55,  56,57,60,61,62,63,  
+         65,66,69,  73,74,76,79,  80,81,82,85,86,  90,91,92,95,  
+         97,100,101,  105,106,107,108,109,111,  112,113,115,116,117,
+         127,  128,129,130,131,133,135,  136,137,140,142,  145,148,150,  
+         152,153,154,156,157 }
+         
+         0011.0001  0100.1101  0001.0001  0100.0010  0101.1001
+         0100.1100  1110.1100  1111.0011 
+         0010.0110  1001.0110  0110.0111  1001.1100 
+         0011.0010  1011.1110  0011.1011
+         1000.0000  1010.1111  0101.0011  0101.0010
+         0011.0111
+          
+         1000110010110010100010000100001010011010001100100011011111001111011001
+         0001101001111001100011100101001100011111011101110000000001111101011100
+         101001001010111011
+          
+         1000.1100 1011.0010 1000.1000 0100.0010 1001.1010 0011.0010 
+         0011.0111 1100.1111 0110.0100 0110.1001 1110.0110 0011.1001
+         0100.1100 0111.1101 1101.1100 0000.0001 1111.0101 1100.1010
+         0100.1010 1110.11
+*/
+
+uint8_t rtaps[] PROGMEM = {
+       0x31, 0x4D, 0x11, 0x42,
+       0x59, 0x4C, 0xEC, 0xF3,
+       0x26, 0x96, 0x67, 0x9C,
+       0x32, 0xBE, 0x3B, 0x80, 
+       0xAF, 0x53, 0x52, 0x37
+};
+       
+static 
+void memxor_P(void* d, PGM_VOID_P s, uint8_t length_B){
+       while(length_B--){
+               *((uint8_t*)d) ^= pgm_read_byte(s);
+               d = (uint8_t*)d +1;
+               s = (uint8_t*)s +1;
+       }
+}
+
+#define SHL0(a) c1=((a)>>7); (a)=(((a)<<1)|c0)
+#define SHL1(a) c0=((a)>>7); (a)=(((a)<<1)|c1)
+
+#define SHLX0(a) c1=((a)>>7); (a)^=(((a)<<1)|c0)
+#define SHLX1(a) c0=((a)>>7); (a)^=(((a)<<1)|c1)
+
+static
+void clock_r(uint8_t* r, uint8_t ibit, uint8_t cbit){
+       uint8_t i,c0=0,c1=0; /* carry */
+       ibit ^= ((r[159/8])>>(159%8))&1; /* ibit is now the same as feedback_bit */
+       if(cbit){
+               for(i=0; i<10; ++i){
+                       SHLX0(r[2*i+0]);
+                       SHLX1(r[2*i+1]);
+               }
+       } else {
+               for(i=0; i<10; ++i){
+                       SHL0(r[2*i+0]);
+                       SHL1(r[2*i+1]);
+               }
+       }
+       if(ibit){
+               memxor_P(r, rtaps, 20);
+       }
+}
+
+/* comp0 (filling spaces with zero) (one at each side)
+ * 0101.1110 1111.0010 1101.0110 0101.1101 
+ * 0101.0101 0000.1001 0010.0110 0111.1001
+ * 0110.0010 0111.0000 0000.0000 0111.1001
+ * 0011.0001 1101.1001 1010.1111 0011.0111
+ * 1011.1110 0000.0110 1011.1110 0000.1111
+ * --
+ * 5E F2 D6 5D
+ * 55 09 26 79
+ * 62 70 00 79
+ * 31 D9 AF 37
+ * BE 06 BE 0F
+ */ 
+uint8_t comp0[] PROGMEM = {
+       0x5E, 0xF2, 0xD6, 0x5D,
+       0x55, 0x09, 0x26, 0x79,
+       0x62, 0x70, 0x00, 0x79, 
+       0x31, 0xD9, 0xAF, 0x37, 
+       0xBE, 0x06, 0xBE, 0x0F
+};
+
+
+/* comp1 (shifting one bit right to make calculation easier, so inserting two zeros)
+ * 0110.0000 0011.1110 0011.0010 1111.1010 
+ * 0011.0000 0111.1001 0110.1100 1111.1101
+ * 1100.0001 1000.0111 0000.0001 1111.1000
+ * 1000.1010 1100.0110 1100.0001 1100.1100
+ * 0110.1010 1011.0111 1110.1000 1111.1111
+ * --
+ * 60 3E 32 FA
+ * 30 79 6C FD
+ * C1 87 01 F8
+ * 8A C6 C1 CC
+ * 6A B7 E8 FF
+*/
+/*
+uint8_t comp1[] PROGMEM = {
+       0x60, 0x3E, 0x32, 0xFA, 0x30, 0x79, 0x6C, 0xFD, 0xC1, 0x87, 
+       0x01, 0xF8, 0x8A, 0xC6, 0xC1, 0xCC, 0x6A, 0xB7, 0xE8, 0xFF
+};
+*/
+/* comp1
+ * 0000.1100 1111.1000 1001.1000 1011.1110
+ * 0001.1001 0011.1100 0110.1101 0111.1111
+ * 0000.0111 1100.0011 0000.0000 0011.1110
+ * 1010.0010 1100.0111 0000.0110 0110.0110
+ * 1010.1101 1101.1010 0010.1111 1111.1110
+ * --
+ * 0C F8 98 BE
+ * 19 3C 6D 7F
+ * 07 C3 00 3E
+ * A2 C7 06 66
+ * AD DA 2F FE
+*/
+/*
+uint8_t comp1[] PROGMEM = {
+       0x0C, 0xF8, 0x98, 0xBE, 0x19, 0x3C, 0x6D, 0x7F, 0x07, 0xC3,
+       0x00, 0x3E, 0xA2, 0xC7, 0x06, 0x66, 0xAD, 0xDA, 0x2F, 0xFE
+};
+*/
+/* comp1
+ * 0011.0000 0001.1111 0001.1001 0111.1101
+ * 1001.1000 0011.1100 1011.0110 1111.1110
+ * 1110.0000 1100.0011 0000.0000 0111.1100
+ * 0100.0101 1110.0011 0110.0000 0110.0110
+ * 1011.0101 0101.1011 1111.0100 0111.1111
+ * --
+ * 30 1F 19 7D
+ * 98 3C B6 FE
+ * E0 C3 00 7C
+ * 45 E3 60 66
+ * B5 5B F4 7F
+*/
+
+uint8_t comp1[] PROGMEM = {
+       0x30, 0x1F, 0x19, 0x7D,
+       0x98, 0x3C, 0xB6, 0xFE, 
+       0xE0, 0xC3, 0x00, 0x7C, 
+       0x45, 0xE3, 0x60, 0x66, 
+       0xB5, 0x5B, 0xF4, 0x7F
+};
+
+/* fb0
+ * 1010.1111 0001.1111 0011.1100 1100.0100
+ * 0010.0010 1010.0011 0010.1111 0000.1110
+ * 1000.0001 0100.1101 1110.0101 0110.0110
+ * 1001.0001 0100.1011 0101.0100 1101.0100
+ * 1100.0001 0000.1011 0110.0011 1000.0011
+ * --
+ * AF 1F 3C C4
+ * 22 A3 2F 0E
+ * 81 4D E5 66
+ * 91 4B 54 D4
+ * C1 0B 63 83
+ */ 
+uint8_t fb0[] PROGMEM = {      
+       0xAF, 0x1F, 0x3C, 0xC4, 
+       0x22, 0xA3, 0x2F, 0x0E, 
+       0x81, 0x4D, 0xE5, 0x66, 
+       0x91, 0x4B, 0x54, 0xD4, 
+       0xC1, 0x0B, 0x63, 0x83
+};
+
+/* fb1
+ * 1010.1011 0111.0111 1111.0100 1001.1011 
+ * 1001.0000 1000.1100 0111.1001 0111.0000
+ * 1011.0110 0001.1000 1001.1010 0110.1111
+ * 1110.0111 0111.1110 0100.1011 0110.1100 
+ * 1110.1111 1000.0000 1010.0111 0001.0001
+ * --
+ * AB 77 F4 9B
+ * 90 8C 79 70
+ * B6 18 9A 6F
+ * E7 7E 4B 6C
+ * EF 80 A7 11
+ */ 
+uint8_t fb1[] PROGMEM = {
+       0xAB, 0x77, 0xF4, 0x9B, 
+       0x90, 0x8C, 0x79, 0x70, 
+       0xB6, 0x18, 0x9A, 0x6F, 
+       0xE7, 0x7E, 0x4B, 0x6C, 
+       0xEF, 0x80, 0xA7, 0x11
+};
+
+static
+void clock_s(uint8_t* s, uint8_t ibit, uint8_t cbit){
+       uint8_t s0[20], s1[20];
+       uint8_t i,c=0, c2=0;
+       ibit ^= (s[19])>>7;
+       memcpy(s0,s,20);
+       memxor_P(s0, comp0, 20);
+       for(i=0; i<20; ++i){
+               s1[19-i]= c|((s[19-i])>>1);
+               c = (s[19-i])<<7;
+       }
+       memxor_P(s1, comp1, 20);
+       c=0;
+       for(i=0; i<20; ++i){
+               c2=(s[i])>>7;
+               s[i]=((s[i])<<1) ^ ((s0[i])&(s1[i])) ^ c;
+               c=c2;
+       }
+       s[0] &= 0xFE;
+       if(ibit){
+               memxor_P(s, cbit?fb1:fb0, 20);
+       }
+}
+
+static
+void clock_kg(uint8_t* r, uint8_t* s, uint8_t mixing, uint8_t input){
+       uint8_t rb, sb;
+       rb = ((s[ 54/8])>>(( 54%8))) ^ ((r[106/8])>>(((106%8))));
+       sb = ((s[106/8])>>((106%8))) ^ ((r[ 53/8])>>((( 53%8))));
+       rb &= 1;
+       sb &= 1;
+       mixing = input ^ (mixing & ((s[80/8]>>((80%8))) & 1)); 
+       clock_r(r, mixing, rb);
+       clock_s(s, input, sb);
+}
+
+void mickey128_init(void* key, uint16_t keysize_b, 
+                    void* iv,  uint16_t ivsize_b, 
+                    mickey128_ctx_t* ctx){
+       uint16_t i;
+       memset(ctx->r, 0, 20);
+       memset(ctx->s, 0, 20);
+       for(i=0; i<ivsize_b; ++i){
+               clock_kg(ctx->r, ctx->s, 1, 1&((((uint8_t*)iv)[i/8])>>(7-(i%8))));
+       }
+       for(i=0; i<keysize_b; ++i){
+               clock_kg(ctx->r, ctx->s, 1, 1&((((uint8_t*)key)[i/8])>>(7-(i%8))));
+       }                  
+       for(i=0; i<160; ++i){
+               clock_kg(ctx->r, ctx->s, 1, 0);
+       }                  
+} 
+
+uint8_t mickey128_getbit(mickey128_ctx_t* ctx){
+       uint8_t ret;
+       ret = 1&(*(ctx->r) ^ *(ctx->s));
+       clock_kg(ctx->r, ctx->s, 0, 0);
+       return ret;
+}
+
+uint8_t mickey128_getbyte(mickey128_ctx_t* ctx){
+       uint8_t i,ret=0;
+       for(i=0; i<8; ++i){
+               ret<<=1;
+               ret |= 1&(((ctx->r)[0]) ^ ((ctx->s)[0]));
+               clock_kg(ctx->r, ctx->s, 0, 0);
+       }
+       return ret;
+}
+
+               
diff --git a/mickey128/mickey128.h b/mickey128/mickey128.h
new file mode 100644 (file)
index 0000000..9a125f4
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef MICKEY128_H_
+#define MICKEY128_H_
+
+#include <stdint.h>
+
+typedef struct mickey128_ctx_st{
+       uint8_t r[20];
+       uint8_t s[20];
+} mickey128_ctx_t;
+
+void debug_clock_r(void);
+void debug_clock_s(void);
+void mickey128_init(void* key, uint16_t keysize_b, 
+                    void* iv,  uint16_t ivsize_b, 
+                    mickey128_ctx_t* ctx);
+uint8_t mickey128_getbit(mickey128_ctx_t* ctx);
+uint8_t mickey128_getbyte(mickey128_ctx_t* ctx);
+
+#endif /*MICKEY128_H_*/
index d62c1446cbf0c2876dd813e4a7f4fef2f19b3c33..ebc6858e5638c111954843c0b6f03f9b371df605 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := ARCFOUR
 # comment out the following line for removement of ARCFOUR from the build process
 STREAM_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := arcfour/
 $(ALGO_NAME)_OBJ      := arcfour-asm.o
 $(ALGO_NAME)_TEST_BIN := main-arcfour-test.o $(CLI_STD)  \
                          nessie_stream_test.o nessie_common.o performance_test.o
index 40a3a846f0e0bfa3749d1c3892ccfa967637d32e..5bee9f06208fd9f86465758976d55b3d1f8a5f98 100644 (file)
@@ -4,10 +4,9 @@ ALGO_NAME := ARCFOUR_C
 # comment out the following line for removement of ARCFOUR from the build process
 STREAM_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := arcfour/
 $(ALGO_NAME)_OBJ      := arcfour.o
-$(ALGO_NAME)_TEST_BIN := main-arcfour-test.o $(CLI_STD)  \
-                         nessie_stream_test.o nessie_common.o \
-                         performance_test.o
+$(ALGO_NAME)_TEST_BIN := main-arcfour-test.o $(CLI_STD) nessie_stream_test.o nessie_common.o performance_test.o
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
 $(ALGO_NAME)_PERFORMANCE_TEST := "performance"
 
index 58883c3d4cff1849fb82a10a2db40d9d4e7dba0b..013b7ee05787ecb0b69510bf2b207026bf790808 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := BASE64
 # comment out the following line for removement of base64 from the build process
 ENCODINGS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := base64/
 $(ALGO_NAME)_OBJ      := base64_enc.o base64_dec.o
 $(ALGO_NAME)_TEST_BIN := main-base64-test.o $(CLI_STD)  \
                          performance_test.o noekeon_asm.o noekeon_prng.o memxor.o
index 63059321ad138ac9d8294538fbd1dae07f2d312b..585bbb2e12ffb1428a989e96d7e342458b166af9 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := BMW_C
 # comment out the following line for removement of BlueMidnightWish from the build process
 HASHES += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := bmw/
 $(ALGO_NAME)_OBJ      := bmw_small.o bmw_large.o
 $(ALGO_NAME)_TEST_BIN := main-bmw-test.o hfal_bmw_small.o hfal_bmw_large.o $(CLI_STD) $(HFAL_STD)
 $(ALGO_NAME)_NESSIE_TEST      := test nessie
index 08ead6e980e55bb3fa6dee28f33ce7ce5c2da281..318a0e57ba76d88911f1bb26ff6aae3d0e896f5b 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := CAST5
 # comment out the following line for removement of CAST5 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := cast5/
 $(ALGO_NAME)_OBJ      := cast5.o
 $(ALGO_NAME)_TEST_BIN := main-cast5-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 3f8539f66b748f613b4dfd896d93128894fb7d09..f28800ac8491b6ead4045cef5eff4c24b6b9a2ca 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := CAST6
 # comment out the following line for removement of CAST6 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := cast6/
 $(ALGO_NAME)_OBJ      := cast6.o
 $(ALGO_NAME)_TEST_BIN := main-cast6-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 5d9540dd027c054a565160f405bec3c46f630d9c..180d9e1ed54cd3f19e4d9ad423497b8cc0208a26 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := DES
 # comment out the following line for removement of DES from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := des/
 $(ALGO_NAME)_OBJ      := des.o
 $(ALGO_NAME)_TEST_BIN := main-des-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 02ad75b7503610af00a4d73c1077c0970135e452..e87b3de257f220a40dfc5bcbcdcc675e7a80fc39 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := ENTROPIUM
 # comment out the following line for removement of PRNG from the build process
 PRNGS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := entropium/
 $(ALGO_NAME)_OBJ      := entropium.o sha256-asm.o
 $(ALGO_NAME)_TEST_BIN := main-entropium-test.o $(CLI_STD) performance_test.o
                          
index 1b0da652aedf8a1290b61b5162455e123778b3f8..5e6638e3cfa83a24bb6e657d631cc6f36a51decb 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := GRAIN
 # comment out the following line for removement of Grain from the build process
 STREAM_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := grain/
 $(ALGO_NAME)_OBJ      := grain.o
 $(ALGO_NAME)_TEST_BIN := main-grain-test.o $(CLI_STD) \
                          nessie_stream_test.o nessie_common.o performance_test.o
index 7d3f64495c597a9d05aea6ba70c5dda4e075842f..fd23627a26793de2385563c258e23b619d4b8432 100644 (file)
@@ -4,9 +4,10 @@ ALGO_NAME := HMAC-MD5
 # comment out the following line for removement of HMAC-MD5 from the build process
 MACS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := hmac-md5/
 $(ALGO_NAME)_OBJ      := hmac-md5.o md5-asm.o
 $(ALGO_NAME)_TEST_BIN := main-hmac-md5-test.o $(CLI_STD) \
-                         nessie_mac_test.o nessie_common.o base64_enc.o base64_dec.o
+                         nessie_mac_test.o nessie_common.o
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
 $(ALGO_NAME)_PERFORMANCE_TEST := "performance"
 
index 90874002cca2886048a79be2c04605a599141329..40958a71fd05f68079b1452514eaccc0c8475360 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := HMAC-SHA1
 # comment out the following line for removement of HMAC-SHA1 from the build process
 MACS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := hmac-sha1/
 $(ALGO_NAME)_OBJ      := hmac-sha1.o sha1-asm.o
 $(ALGO_NAME)_TEST_BIN := main-hmac-sha1-test.o $(CLI_STD) \
                          nessie_mac_test.o nessie_common.o
index ba221ab87d5b16d4b4005b077108479342872ffb..4b25ea947d48dd10ce0e93dcdf400d82129e4089 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := HMAC-SHA256
 # comment out the following line for removement of HMAC-SHA256 from the build process
 MACS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := hmac-sha256/
 $(ALGO_NAME)_OBJ      := hmac-sha256.o sha256-asm.o
 $(ALGO_NAME)_TEST_BIN := main-hmac-sha256-test.o $(CLI_STD) \
                          nessie_mac_test.o nessie_common.o
index 025e9eb29206d6ea46da94e631dfe0e9263df67b..bebdaa393611970c1144b3f3b3fd99df43c2b58e 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := MD5
 # comment out the following line for removement of MD5 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := md5/
 $(ALGO_NAME)_OBJ      := md5-asm.o
 $(ALGO_NAME)_TEST_BIN := main-md5-test.o hfal_md5.o $(CLI_STD) $(HFAL_STD)
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
index 7b6bb1adebbf395818ca8d339b178d464f6a2282..d7421e71912bc5c39d9ca6f4ff927d5a4c3bce8c 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := MD5_C
 # comment out the following line for removement of MD5 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := md5/
 $(ALGO_NAME)_OBJ      := md5.o
 $(ALGO_NAME)_TEST_BIN := main-md5-test.o hfal_md5.o $(CLI_STD) $(HFAL_STD)
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
index 6c95c968d66f2d4e298893fc1bbf11af8e5531f8..c7bc17d7314ee6a35ceba5b552151a729276ee2b 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := MICKEY128
 # comment out the following line for removement of Mickey128 from the build process
 STREAM_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := mickey128/
 $(ALGO_NAME)_OBJ      := mickey128.o
 $(ALGO_NAME)_TEST_BIN := main-mickey128-test.o $(CLI_STD) \
                          nessie_stream_test.o nessie_common.o
index 3a4012c76fc500dce0cf570c8f3d5b0b1f658365..3c73f82763d99e66c243621e64849c3fdd9009f0 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := PRESENT
 # comment out the following line for removement of present from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := present/
 $(ALGO_NAME)_OBJ      := present.o
 $(ALGO_NAME)_TEST_BIN := main-present-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 3a5f1286698c1b25c2226431b6033156508b91eb..be821751b24e0c7bf83aa9278255813dd680081e 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := RC5
 # comment out the following line for removement of RC5 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := rc5/
 $(ALGO_NAME)_OBJ      := rc5.o
 $(ALGO_NAME)_TEST_BIN := main-rc5-test.o $(CLI_STD) nessie_bc_test.o \
                          nessie_common.o performance_test.o
index e0bc603e60640d431dac4ff597ffacadc6b25031..a58b1383b822f5ddefe5e937e1e11bdc37e786c7 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := RC6
 # comment out the following line for removement of RC6 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := rc6/
 $(ALGO_NAME)_OBJ      := rc6.o
 $(ALGO_NAME)_TEST_BIN := main-rc6-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 1c2b605802909d53c0b5334635ef3d2afca0adb9..07ceb3e71db424f168aef7ebd7c70cd5008936af 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SEED
 # comment out the following line for removement of SEED from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := seed/
 $(ALGO_NAME)_OBJ      := seed-asm.o
 $(ALGO_NAME)_TEST_BIN := main-seed-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 14aa8ac75bb14d2d0d3b8b61ca09a29b64633086..7c776668990858ee11fada235025e78cb7143f8d 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SEED_C
 # comment out the following line for removement of SEED from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := seed/
 $(ALGO_NAME)_OBJ      := seed_C.o
 $(ALGO_NAME)_TEST_BIN := main-seed-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 6a9b76a28a5b5712a51a04f9aea9a468fef7a1ed..571914320659327f67a5f25dee8796ee46a4d738 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := SERPENT_BITSLICE
 # comment out the following line for removement of serpent from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := serpent/
 $(ALGO_NAME)_OBJ      := serpent-asm.o serpent-sboxes-bitslice-asm.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-serpent-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index afd0868e7622d45da856ec8c070864e86aa037a4..a5956c38c9000b215cf8535b6f3cf5c385f2742e 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := SERPENT_ASM_BITSLICE
 # comment out the following line for removement of serpent from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := serpent/
 $(ALGO_NAME)_OBJ      := serpent-sboxes-bitslice-asm.o serpent-asm.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-serpent-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 3e3a4fb78297a1dbb9e23fb035b9166f1f33dc98..d9ff725fe07d2eba9a0f56eea91e5de6e7eeebf4 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := SERPENT_ASM_FAST
 # comment out the following line for removement of serpent from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := serpent/
 $(ALGO_NAME)_OBJ      := serpent-asm.o serpent-sboxes-fast.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-serpent-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 6dde94bd93c22fcc9af219c21b99c13516cfcb85..4d6750ebc1a0d17304387249a08f9a8936b70c17 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := SERPENT_ASM_SMALL
 # comment out the following line for removement of serpent from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := serpent/
 $(ALGO_NAME)_OBJ      := serpent-asm.o serpent-sboxes-small.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-serpent-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index dd3a69ba3309cf2037d2633c70d5deb9f41fb0a1..f52ced4a58d2fd8fd8c3e23377cbe08b4b3e4d27 100644 (file)
@@ -4,7 +4,7 @@ ALGO_NAME := SERPENT_C
 # comment out the following line for removement of serpent from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := serpent/
 $(ALGO_NAME)_OBJ      := serpent.o serpent-sboxes_c.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-serpent-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 45df051cacb76c2f3a2ac01f7bc59689762657bd..c986aeb00501147c0fe46722a7ad9f6fdb484143 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SHA1
 # comment out the following line for removement of SHA1 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := sha1/
 $(ALGO_NAME)_OBJ      := sha1-asm.o
 $(ALGO_NAME)_TEST_BIN := main-sha1-test.o hfal_sha1.o $(CLI_STD) $(HFAL_STD) dump-decl.o dump-asm.o 
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
index 4b0b7ae43bd18cf731f14f309330a3184743fa14..6998cbc84466397fbb3ce2390ec17ccd14380056 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SHA1_C
 # comment out the following line for removement of SHA1 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := sha1/
 $(ALGO_NAME)_OBJ      := sha1.o
 $(ALGO_NAME)_TEST_BIN := main-sha1-test.o hfal_sha1.o dump-asm.o dump-decl.o $(CLI_STD) $(HFAL_STD)
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
index 93ebdc7b64df8899c01fe44000ebbc7b93eb802c..9e56ed64456959c7559aa3e0e20296a22f3d2cd7 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SHA256
 # comment out the following line for removement of SHA256 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := sha256/
 $(ALGO_NAME)_OBJ      := sha256-asm.o
 $(ALGO_NAME)_TEST_BIN := main-sha256-test.o dump-asm.o dump-decl.o hfal_sha256.o $(CLI_STD) $(HFAL_STD)
                        
index d52fe8812b421f79661cea91cb20efef4ef5740d..6c58677d9a23c9af14fb3354d489c6c52af19bfa 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SHA256_C
 # comment out the following line for removement of SHA256 from the build process
 HASHES += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := sha256/
 $(ALGO_NAME)_OBJ      := sha256.o
 $(ALGO_NAME)_TEST_BIN := main-sha256-test.o $(CLI_STD) $(HFAL_STD) hfal_sha256.o dump-asm.o dump-decl.o
 $(ALGO_NAME)_NESSIE_TEST      := "nessie"
index e5f4a68dbc8cb3db399ac4f3116b429795fb448d..9c05cb3abf49d197f03d1979b3507216b95211d6 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SHABEA
 # comment out the following line for removement of SHABEA from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := shabea/
 $(ALGO_NAME)_OBJ      := shabea.o sha256-asm.o memxor.o
 $(ALGO_NAME)_TEST_BIN := main-shabea-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 63be6c8514365170e49453e9b3485fa96b54ae44..30036381ad29c287efa58c4d65172db3c8dd802c 100644 (file)
@@ -1,10 +1,10 @@
-# Makefile for present
+# Makefile for shacal1
 ALGO_NAME := SHACAL1ENC
 
-# comment out the following line for removement of present from the build process
+# comment out the following line for removement of shacal1 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := shacal1/
 $(ALGO_NAME)_OBJ      := shacal1_enc.o sha1-asm.o
 $(ALGO_NAME)_TEST_BIN := main-shacal1_enc-test.o $(CLI_STD)  \
                          nessie_bc_test.o nessie_common.o performance_test.o 
index e8a91a21dac33b1bc625716253a2ee38ef385427..d5f0d9d937d4d21b1d9c0ab622ae56e1ff9e81d2 100644 (file)
@@ -1,10 +1,10 @@
-# Makefile for present
+# Makefile for shacal2
 ALGO_NAME := SHACAL2ENC
 
-# comment out the following line for removement of present from the build process
+# comment out the following line for removement of shacal2 from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
-
+$(ALGO_NAME)_DIR      := shacal2/
 $(ALGO_NAME)_OBJ      := shacal2_enc.o sha256-asm.o
 $(ALGO_NAME)_TEST_BIN := main-shacal2_enc-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o 
index 56579b24c62e4d548b15c0c7d5d62428eb229682..ef859df9ac632210f125ad6657c31d3000551a79 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := SKIPJACK
 # comment out the following line for removement of skipjack from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := skipjack/
 $(ALGO_NAME)_OBJ      := skipjack.o
 $(ALGO_NAME)_TEST_BIN := main-skipjack-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index 7bdc41ec42a337f042923d9348d41706bebd9033..09bb96cb3e8b47da21620b963c741be8be4b99b8 100644 (file)
@@ -1,9 +1,10 @@
-# Makefile for DES
+# Makefile for Triple-DES
 ALGO_NAME := TDES
 
-# comment out the following line for removement of DES from the build process
+# comment out the following line for removement of Triple-DES from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := des/
 $(ALGO_NAME)_OBJ      := des.o
 $(ALGO_NAME)_TEST_BIN := main-tdes-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index bbfba3b70163974d99a97cc50c7089384f768b15..a668ee7d232fae2f2ee2577226db016f1a6eabb2 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := TRIVIUM
 # comment out the following line for removement of Trivium from the build process
 STREAM_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := trivium/
 $(ALGO_NAME)_OBJ      := trivium.o
 $(ALGO_NAME)_TEST_BIN := main-trivium-test.o $(CLI_STD) \
                          nessie_stream_test.o nessie_common.o performance_test.o
index 68adcfb64cf2eff73a3f9793c95794a3e4822a69..f2d1169cc66c94d445d5398218d25b01462bd2df 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := XTEA
 # comment out the following line for removement of XTEA from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := xtea/
 $(ALGO_NAME)_OBJ      := xtea-asm.o
 $(ALGO_NAME)_TEST_BIN := main-xtea-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
index dec8f8ce30105750b3f1322808143b8417cd25b4..5bbd680e88e00499372adcbe533bda05fb6fea99 100644 (file)
@@ -4,6 +4,7 @@ ALGO_NAME := XTEA_C
 # comment out the following line for removement of XTEA from the build process
 BLOCK_CIPHERS += $(ALGO_NAME)
 
+$(ALGO_NAME)_DIR      := xtea/
 $(ALGO_NAME)_OBJ      := xtea.o
 $(ALGO_NAME)_TEST_BIN := main-xtea-test.o $(CLI_STD) \
                          nessie_bc_test.o nessie_common.o performance_test.o
diff --git a/present.c b/present.c
deleted file mode 100644 (file)
index 03792c5..0000000
--- a/present.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* present.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * present.c
- * a implementation of the PRESENT block-cipher
- * author: Daniel Otte
- * email:  daniel.otte@rub.de
- * license: GPLv3
- * 
- * */
-#include <string.h>
-#include <stdint.h> 
-#include "present.h"
-
-static uint8_t sbox(uint8_t b){
-       uint8_t sb[]={0xC, 0x5, 0x6, 0xB, 
-                                 0x9, 0x0, 0xA, 0xD, 
-                                 0x3, 0xE, 0xF, 0x8, 
-                                 0x4, 0x7, 0x1, 0x2 };
-       return (((sb[b>>4])<<4)|(sb[b&0xf]));
-}
-
-static uint8_t sbox_inv(uint8_t b){
-       uint8_t sb[]={0x5, 0xE, 0xF, 0x8, 
-                                 0xC, 0x1, 0x2, 0xD, 
-                                 0xB, 0x4, 0x6, 0x3, 
-                                 0x0, 0x7, 0x9, 0xA };
-       return (((sb[b>>4])<<4)|(sb[b&0xf]));
-}
-
-#define SHR_O(a) c=(a)&1; (a)>>=1;
-#define SHR_I(a) (a)=(c?0x8000:0x0000) | ((a)>>1);
-
-static void p(uint16_t* o, uint8_t* i){
-       uint8_t c;
-       uint8_t m,n;
-       for(m=0; m<8; ++m){
-               for(n=0; n<2; ++n){
-                       SHR_O(i[m]);
-                       SHR_I(o[0]);
-                       SHR_O(i[m]);
-                       SHR_I(o[1]);
-                       SHR_O(i[m]);
-                       SHR_I(o[2]);
-                       SHR_O(i[m]);
-                       SHR_I(o[3]);
-               }
-       }
-}
-
-static void p_inv(uint8_t* o, uint8_t* i){
-       uint8_t tmp[8];
-       p((uint16_t*)tmp, i);
-       p((uint16_t*)o, tmp);
-}
-
-void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx){
-       uint8_t buffer[10], tmp[2];
-       uint8_t i;
-       memcpy(buffer, key, 10);
-       memcpy(&(ctx->k[0]), buffer+2, 8);
-       for(i=1; i<32; ++i){
-               /* rotate buffer 19 right */
-               memcpy(tmp, buffer, 2);
-               memmove(buffer, buffer+2, 8);
-               memcpy(buffer+8, tmp, 2);
-                /* three shifts to do*/
-               tmp[1]=buffer[0];
-               *((uint64_t*)buffer)>>=3;
-               *((uint16_t*)(buffer+8))>>=3;
-               buffer[9] |= tmp[1]<<5;
-               buffer[7] |= tmp[0]<<5;
-               /* rotating done now substitution */
-               buffer[9] = (sbox(buffer[9])&0xF0) | ((buffer[9])&0x0F);
-               /* xor with round counter */
-               *((uint16_t*)(buffer+1)) ^= (uint16_t)i<<7;
-               memcpy(&(ctx->k[i]), buffer+2, 8);
-       }
-}
-
-void present_enc(void* buffer, present_ctx_t* ctx){
-       uint8_t i,j,tmp[8];
-       for(i=0; i<31; ++i){
-               *((uint64_t*)buffer) ^= ctx->k[i];
-                for(j=0; j<8; ++j){
-                       tmp[j] = sbox(((uint8_t*)buffer)[j]);
-                }
-                p((uint16_t*)buffer, tmp);
-       }
-       *((uint64_t*)buffer) ^= ctx->k[31];
-}
-
-
-void present_dec(void* buffer, present_ctx_t* ctx){
-       uint8_t j,tmp[8];
-       int8_t i;
-       *((uint64_t*)buffer) ^= ctx->k[31];
-
-       for(i=30; i>=0; --i){ 
-               p_inv(tmp, (uint8_t*)buffer);
-               for(j=0; j<8; ++j){
-                       ((uint8_t*)buffer)[j] = sbox_inv(tmp[j]);
-               }
-               *((uint64_t*)buffer) ^= ctx->k[i];
-       }
-}
diff --git a/present.h b/present.h
deleted file mode 100644 (file)
index 320a1d8..0000000
--- a/present.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* present.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef PRESENT_H_
-#define PRESENT_H_
-
-#include <stdint.h>
-
-typedef struct present_ctx_st{
-       uint64_t k[32];
-} present_ctx_t;
-
-
-void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx);
-void present_enc(void* buffer, present_ctx_t* ctx);
-void present_dec(void* buffer, present_ctx_t* ctx);
-
-
-#endif /*PRESENT_H_*/
diff --git a/present/present.c b/present/present.c
new file mode 100644 (file)
index 0000000..03792c5
--- /dev/null
@@ -0,0 +1,123 @@
+/* present.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * present.c
+ * a implementation of the PRESENT block-cipher
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * */
+#include <string.h>
+#include <stdint.h> 
+#include "present.h"
+
+static uint8_t sbox(uint8_t b){
+       uint8_t sb[]={0xC, 0x5, 0x6, 0xB, 
+                                 0x9, 0x0, 0xA, 0xD, 
+                                 0x3, 0xE, 0xF, 0x8, 
+                                 0x4, 0x7, 0x1, 0x2 };
+       return (((sb[b>>4])<<4)|(sb[b&0xf]));
+}
+
+static uint8_t sbox_inv(uint8_t b){
+       uint8_t sb[]={0x5, 0xE, 0xF, 0x8, 
+                                 0xC, 0x1, 0x2, 0xD, 
+                                 0xB, 0x4, 0x6, 0x3, 
+                                 0x0, 0x7, 0x9, 0xA };
+       return (((sb[b>>4])<<4)|(sb[b&0xf]));
+}
+
+#define SHR_O(a) c=(a)&1; (a)>>=1;
+#define SHR_I(a) (a)=(c?0x8000:0x0000) | ((a)>>1);
+
+static void p(uint16_t* o, uint8_t* i){
+       uint8_t c;
+       uint8_t m,n;
+       for(m=0; m<8; ++m){
+               for(n=0; n<2; ++n){
+                       SHR_O(i[m]);
+                       SHR_I(o[0]);
+                       SHR_O(i[m]);
+                       SHR_I(o[1]);
+                       SHR_O(i[m]);
+                       SHR_I(o[2]);
+                       SHR_O(i[m]);
+                       SHR_I(o[3]);
+               }
+       }
+}
+
+static void p_inv(uint8_t* o, uint8_t* i){
+       uint8_t tmp[8];
+       p((uint16_t*)tmp, i);
+       p((uint16_t*)o, tmp);
+}
+
+void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx){
+       uint8_t buffer[10], tmp[2];
+       uint8_t i;
+       memcpy(buffer, key, 10);
+       memcpy(&(ctx->k[0]), buffer+2, 8);
+       for(i=1; i<32; ++i){
+               /* rotate buffer 19 right */
+               memcpy(tmp, buffer, 2);
+               memmove(buffer, buffer+2, 8);
+               memcpy(buffer+8, tmp, 2);
+                /* three shifts to do*/
+               tmp[1]=buffer[0];
+               *((uint64_t*)buffer)>>=3;
+               *((uint16_t*)(buffer+8))>>=3;
+               buffer[9] |= tmp[1]<<5;
+               buffer[7] |= tmp[0]<<5;
+               /* rotating done now substitution */
+               buffer[9] = (sbox(buffer[9])&0xF0) | ((buffer[9])&0x0F);
+               /* xor with round counter */
+               *((uint16_t*)(buffer+1)) ^= (uint16_t)i<<7;
+               memcpy(&(ctx->k[i]), buffer+2, 8);
+       }
+}
+
+void present_enc(void* buffer, present_ctx_t* ctx){
+       uint8_t i,j,tmp[8];
+       for(i=0; i<31; ++i){
+               *((uint64_t*)buffer) ^= ctx->k[i];
+                for(j=0; j<8; ++j){
+                       tmp[j] = sbox(((uint8_t*)buffer)[j]);
+                }
+                p((uint16_t*)buffer, tmp);
+       }
+       *((uint64_t*)buffer) ^= ctx->k[31];
+}
+
+
+void present_dec(void* buffer, present_ctx_t* ctx){
+       uint8_t j,tmp[8];
+       int8_t i;
+       *((uint64_t*)buffer) ^= ctx->k[31];
+
+       for(i=30; i>=0; --i){ 
+               p_inv(tmp, (uint8_t*)buffer);
+               for(j=0; j<8; ++j){
+                       ((uint8_t*)buffer)[j] = sbox_inv(tmp[j]);
+               }
+               *((uint64_t*)buffer) ^= ctx->k[i];
+       }
+}
diff --git a/present/present.h b/present/present.h
new file mode 100644 (file)
index 0000000..320a1d8
--- /dev/null
@@ -0,0 +1,34 @@
+/* present.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef PRESENT_H_
+#define PRESENT_H_
+
+#include <stdint.h>
+
+typedef struct present_ctx_st{
+       uint64_t k[32];
+} present_ctx_t;
+
+
+void present_init(const uint8_t* key, uint8_t keysize_b, present_ctx_t* ctx);
+void present_enc(void* buffer, present_ctx_t* ctx);
+void present_dec(void* buffer, present_ctx_t* ctx);
+
+
+#endif /*PRESENT_H_*/
diff --git a/rc5.c b/rc5.c
deleted file mode 100644 (file)
index 441f61d..0000000
--- a/rc5.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* rc5.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* rc5.c a C implementation of RC5 for AVR microcontrollers
- * 
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- * 
- * this implementation is limited to 64bit blocks and a maximum of 255 rounds
- * 
- */
-
-#include <stdint.h>
-#include <stdlib.h> /* malloc() & free() */
-#include <string.h> /* memset() & memcpy() */
-#include "rc5.h" 
-
-#define A (((uint32_t*)buffer)[0])
-#define B (((uint32_t*)buffer)[1])
-#define ROTL32(v,n) (((v)<<(n))|((v)>>(32-(n))))
-#define ROTR32(v,n) (((v)>>(n))|((v)<<(32-(n))))
-
-void rc5_enc(void* buffer, const rc5_ctx_t* ctx){
-       uint8_t i;
-       A += ctx->s[0];
-       B += ctx->s[1];
-       for(i=0; i<ctx->rounds; ++i){
-               A = ROTL32(A^B, B&31) + ctx->s[(i+1)*2+0];
-               B = ROTL32(A^B, A&31) + ctx->s[(i+1)*2+1];
-       } 
-}
-
-void rc5_dec(void* buffer, const rc5_ctx_t* ctx){
-       uint8_t i;
-       for(i=ctx->rounds; i>0; --i){
-               B = ROTR32(B - ctx->s[i*2+1], A&31) ^ A;
-               A = ROTR32(A - ctx->s[i*2+0], B&31) ^ B;
-       } 
-       B -= ctx->s[1];
-       A -= ctx->s[0];
-}
-/*
-P32 = 10110111111000010101000101100011 = b7e15163
-Q32 = 10011110001101110111100110111001 = 9e3779b9
-*/
-#define P32 0xb7e15163
-#define Q32 0x9e3779b9
-
-
-void rc5_init(void* key, uint16_t keysize_b, uint8_t rounds, rc5_ctx_t* ctx){
-       uint16_t c,n,m,j,i,t;
-       uint32_t a,b,l[(keysize_b+31)/32];
-       ctx->rounds = rounds;
-       t=2*(rounds+1);
-       c=(keysize_b+31)/32;
-       ctx->s = malloc(t*sizeof(uint32_t));
-       
-       memset(l, 0, sizeof(uint32_t)*c);
-       memcpy(l, key, (keysize_b+7)/8);
-       
-       ctx->s[0] = P32;
-       for(i=1; i<t; ++i){
-               ctx->s[i] = ctx->s[i-1] + Q32;
-       }
-       
-       m = ((t>c)?t:c)*3;
-       i=j=0;
-       a=b=0;
-       for(n=0; n<m; ++n){
-               a=ctx->s[i]=ROTL32(ctx->s[i]+a+b, 3);
-               b=l[j]=ROTL32(l[j]+a+b, (a+b)&31);
-               i=(i+1)%t;
-               j=(j+1)%c;
-       }
-}
-
-void rc5_free(rc5_ctx_t* ctx){
-       if(ctx->s)
-               free(ctx->s);
-}
-
diff --git a/rc5.h b/rc5.h
deleted file mode 100644 (file)
index 2a0182c..0000000
--- a/rc5.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* rc5.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* rc5.h a C implementation of RC5 for AVR microcontrollers
- * 
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- * 
- * this implementation is limited to 64bit blocks and a maximum of 255 rounds
- * 
- */
-#ifndef RC5_H_
-#define RC5_H_
-
-
-#include <stdint.h>
-#include <stdlib.h> /* malloc() & free() */
-#include <string.h> /* memset() & memcpy() */
-typedef struct rc5_ctx_st {
-       uint8_t rounds;
-       uint32_t *s;
-}rc5_ctx_t; 
-
-void rc5_enc(void* buffer, const rc5_ctx_t* ctx);
-void rc5_dec(void* buffer, const rc5_ctx_t* ctx);
-void rc5_init(void* key, uint16_t keysize_b, uint8_t rounds, rc5_ctx_t* ctx);
-void rc5_free(rc5_ctx_t* ctx);
-
-#endif /*RC5_H_*/
diff --git a/rc5/rc5.c b/rc5/rc5.c
new file mode 100644 (file)
index 0000000..441f61d
--- /dev/null
+++ b/rc5/rc5.c
@@ -0,0 +1,98 @@
+/* rc5.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* rc5.c a C implementation of RC5 for AVR microcontrollers
+ * 
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * this implementation is limited to 64bit blocks and a maximum of 255 rounds
+ * 
+ */
+
+#include <stdint.h>
+#include <stdlib.h> /* malloc() & free() */
+#include <string.h> /* memset() & memcpy() */
+#include "rc5.h" 
+
+#define A (((uint32_t*)buffer)[0])
+#define B (((uint32_t*)buffer)[1])
+#define ROTL32(v,n) (((v)<<(n))|((v)>>(32-(n))))
+#define ROTR32(v,n) (((v)>>(n))|((v)<<(32-(n))))
+
+void rc5_enc(void* buffer, const rc5_ctx_t* ctx){
+       uint8_t i;
+       A += ctx->s[0];
+       B += ctx->s[1];
+       for(i=0; i<ctx->rounds; ++i){
+               A = ROTL32(A^B, B&31) + ctx->s[(i+1)*2+0];
+               B = ROTL32(A^B, A&31) + ctx->s[(i+1)*2+1];
+       } 
+}
+
+void rc5_dec(void* buffer, const rc5_ctx_t* ctx){
+       uint8_t i;
+       for(i=ctx->rounds; i>0; --i){
+               B = ROTR32(B - ctx->s[i*2+1], A&31) ^ A;
+               A = ROTR32(A - ctx->s[i*2+0], B&31) ^ B;
+       } 
+       B -= ctx->s[1];
+       A -= ctx->s[0];
+}
+/*
+P32 = 10110111111000010101000101100011 = b7e15163
+Q32 = 10011110001101110111100110111001 = 9e3779b9
+*/
+#define P32 0xb7e15163
+#define Q32 0x9e3779b9
+
+
+void rc5_init(void* key, uint16_t keysize_b, uint8_t rounds, rc5_ctx_t* ctx){
+       uint16_t c,n,m,j,i,t;
+       uint32_t a,b,l[(keysize_b+31)/32];
+       ctx->rounds = rounds;
+       t=2*(rounds+1);
+       c=(keysize_b+31)/32;
+       ctx->s = malloc(t*sizeof(uint32_t));
+       
+       memset(l, 0, sizeof(uint32_t)*c);
+       memcpy(l, key, (keysize_b+7)/8);
+       
+       ctx->s[0] = P32;
+       for(i=1; i<t; ++i){
+               ctx->s[i] = ctx->s[i-1] + Q32;
+       }
+       
+       m = ((t>c)?t:c)*3;
+       i=j=0;
+       a=b=0;
+       for(n=0; n<m; ++n){
+               a=ctx->s[i]=ROTL32(ctx->s[i]+a+b, 3);
+               b=l[j]=ROTL32(l[j]+a+b, (a+b)&31);
+               i=(i+1)%t;
+               j=(j+1)%c;
+       }
+}
+
+void rc5_free(rc5_ctx_t* ctx){
+       if(ctx->s)
+               free(ctx->s);
+}
+
diff --git a/rc5/rc5.h b/rc5/rc5.h
new file mode 100644 (file)
index 0000000..2a0182c
--- /dev/null
+++ b/rc5/rc5.h
@@ -0,0 +1,46 @@
+/* rc5.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* rc5.h a C implementation of RC5 for AVR microcontrollers
+ * 
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ * this implementation is limited to 64bit blocks and a maximum of 255 rounds
+ * 
+ */
+#ifndef RC5_H_
+#define RC5_H_
+
+
+#include <stdint.h>
+#include <stdlib.h> /* malloc() & free() */
+#include <string.h> /* memset() & memcpy() */
+typedef struct rc5_ctx_st {
+       uint8_t rounds;
+       uint32_t *s;
+}rc5_ctx_t; 
+
+void rc5_enc(void* buffer, const rc5_ctx_t* ctx);
+void rc5_dec(void* buffer, const rc5_ctx_t* ctx);
+void rc5_init(void* key, uint16_t keysize_b, uint8_t rounds, rc5_ctx_t* ctx);
+void rc5_free(rc5_ctx_t* ctx);
+
+#endif /*RC5_H_*/
diff --git a/rc6.c b/rc6.c
deleted file mode 100644 (file)
index ea4d7bb..0000000
--- a/rc6.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* rc6.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * File:       rc6.c
- * Author:     Daniel Otte
- * Date:       06.08.2006
- * License: GPL
- * Description: Implementation of the RC6 cipher algorithm.
- *     This implementation is restricted to 32-bit words and to keys up to 65535 bit in length (but this is
- *  quite easy to expand), but free in the choice of number of rounds (0 to 125).
- *     so it is RC6-32/r/b
- * THIS ONLY WORKS FOR LITTEL ENDIAN!!!
- */
-#include <stdint.h>
-#include <stdlib.h>
-#include "rc6.h"
-#include "config.h"
-#define P32 0xB7E15163         /* e -2 */
-#define Q32 0x9E3779B9         /* Golden Ratio -1 */
-uint32_t rotl32(uint32_t a, uint8_t n){
-       n &= 0x1f; /* higher rotates would not bring anything */
-       return ( (a<<n)| (a>>(32-n)) );
-}
-
-uint32_t rotr32(uint32_t a, uint8_t n){
-       n &= 0x1f; /* higher rotates would not bring anything */
-       return ( (a>>n)| (a<<(32-n)) );
-}
-uint8_t rc6_init(void* key, uint16_t keylength_b, rc6_ctx_t *s){
-       return rc6_initl(key, keylength_b, 20, s);
-}
-uint8_t rc6_initl(void* key, uint16_t keylength_b, uint8_t rounds, rc6_ctx_t *s){
-       uint8_t i,j;
-       uint16_t v,p,c;
-       uint32_t a,b, l=0;
-       if (rounds>125)
-               return 2;
-       if(!(s->S=malloc((2*rounds+4)*sizeof(uint32_t))))
-               return 1;
-       
-       s->rounds=rounds;
-       
-       c = keylength_b/32;
-       if (keylength_b%32){ 
-               ++c;
-               j=(keylength_b%32)/8;
-               if(keylength_b%8)
-                       ++j;
-               for (i=0; i<j; ++i) 
-                       ((uint8_t*)&l)[i] = ((uint8_t*)key)[(c-1)*4 + i];
-       } else {
-               l = ((uint32_t*)key)[c-1];
-       }
-       
-       s->S[0] = P32;
-       for(i=1; i<2*rounds+4; ++i){
-               s->S[i] = s->S[i-1] + Q32;
-       }
-       
-       a=b=j=i=0;
-       v = 3 * ((c > 2*rounds+4)?c:(2*rounds+4));
-       for(p=1; p<=v; ++p){
-               a = s->S[i] = rotl32(s->S[i] + a + b, 3);
-               if (j==c-1){
-                       b = l = rotl32(l+a+b, a+b);
-               } else {
-                       b = ((uint32_t*)key)[j] = rotl32(((uint32_t*)key)[j]+a+b, a+b);
-               }
-               i = (i+1) % (2*rounds+4);
-               j = (j+1) % c;
-       }
-       return 0;
-}
-void rc6_free(rc6_ctx_t *s){
-       free(s->S);
-} 
-#define LG_W 5
-#define A (((uint32_t*)block)[0])
-#define B (((uint32_t*)block)[1])
-#define C (((uint32_t*)block)[2])
-#define D (((uint32_t*)block)[3])
-void rc6_enc(void* block, rc6_ctx_t *s){
-       uint8_t i;
-       uint32_t t,u,x; /* greetings to Linux? */
-       B += s->S[0];
-       D += s->S[1];
-       for (i=1; i<=s->rounds; ++i){
-               t = rotl32(B * (2*B+1), LG_W);
-               u = rotl32(D * (2*D+1), LG_W);
-               A = rotl32((A ^ t), u) + s->S[2*i];
-               C = rotl32((C ^ u), t) + s->S[2*i+1];
-               x = A;
-               A = B;
-               B = C;
-               C = D;
-               D = x;
-       }
-       A += s->S[2*s->rounds+2];
-       C += s->S[2*s->rounds+3];
-}
-void rc6_dec(void* block, rc6_ctx_t *s){
-       uint8_t i;
-       uint32_t t,u,x; /* greetings to Linux? */
-       C -= s->S[2*s->rounds+3];
-       A -= s->S[2*s->rounds+2];
-       
-       for (i=s->rounds; i>0; --i){
-               x=D;
-               D=C;
-               C=B;
-               B=A;
-               A=x;
-               u = rotl32(D * (2*D+1), LG_W);
-               t = rotl32(B * (2*B+1), LG_W);
-               C = rotr32(C - s->S[2*i+1], t) ^ u;
-               A = rotr32(A - s->S[2*i+0], u) ^ t;
-       }
-       D -= s->S[1];
-       B -= s->S[0];
-}
diff --git a/rc6.h b/rc6.h
deleted file mode 100644 (file)
index 429a1d3..0000000
--- a/rc6.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* rc6.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* 
- * File:       rc6.h
- * Author:     Daniel Otte
- * Date:       06.08.2006
- * License: GPL
- * Description: Implementation of the RC6 cipher algorithm.
- *     This implementation is restricted to 32-bit words, but free in the choice of number of rounds (0 to 255).
- *     so it is RC6-32/r/b
- */
-
-#ifndef RC6_H_
-#define RC6_H_
-
-#include <stdint.h>
-typedef struct rc6_ctx_st{
-       uint8_t         rounds;         /* specifys the number of rounds; default: 20 */
-       uint32_t*       S;                      /* the round-keys */
-} rc6_ctx_t;
-uint8_t rc6_init(void* key, uint16_t keylength_b, rc6_ctx_t *s);
-uint8_t rc6_initl(void* key, uint16_t keylength_b, uint8_t rounds, rc6_ctx_t *s);
-void rc6_enc(void* block, rc6_ctx_t *s);
-
-void rc6_dec(void* block, rc6_ctx_t *s);
-void rc6_free(rc6_ctx_t *s); 
-
-#endif /* RC6_H_ */
-
diff --git a/rc6/rc6.c b/rc6/rc6.c
new file mode 100644 (file)
index 0000000..ea4d7bb
--- /dev/null
+++ b/rc6/rc6.c
@@ -0,0 +1,148 @@
+/* rc6.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * File:       rc6.c
+ * Author:     Daniel Otte
+ * Date:       06.08.2006
+ * License: GPL
+ * Description: Implementation of the RC6 cipher algorithm.
+ *     This implementation is restricted to 32-bit words and to keys up to 65535 bit in length (but this is
+ *  quite easy to expand), but free in the choice of number of rounds (0 to 125).
+ *     so it is RC6-32/r/b
+ * THIS ONLY WORKS FOR LITTEL ENDIAN!!!
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include "rc6.h"
+#include "config.h"
+#define P32 0xB7E15163         /* e -2 */
+#define Q32 0x9E3779B9         /* Golden Ratio -1 */
+uint32_t rotl32(uint32_t a, uint8_t n){
+       n &= 0x1f; /* higher rotates would not bring anything */
+       return ( (a<<n)| (a>>(32-n)) );
+}
+
+uint32_t rotr32(uint32_t a, uint8_t n){
+       n &= 0x1f; /* higher rotates would not bring anything */
+       return ( (a>>n)| (a<<(32-n)) );
+}
+uint8_t rc6_init(void* key, uint16_t keylength_b, rc6_ctx_t *s){
+       return rc6_initl(key, keylength_b, 20, s);
+}
+uint8_t rc6_initl(void* key, uint16_t keylength_b, uint8_t rounds, rc6_ctx_t *s){
+       uint8_t i,j;
+       uint16_t v,p,c;
+       uint32_t a,b, l=0;
+       if (rounds>125)
+               return 2;
+       if(!(s->S=malloc((2*rounds+4)*sizeof(uint32_t))))
+               return 1;
+       
+       s->rounds=rounds;
+       
+       c = keylength_b/32;
+       if (keylength_b%32){ 
+               ++c;
+               j=(keylength_b%32)/8;
+               if(keylength_b%8)
+                       ++j;
+               for (i=0; i<j; ++i) 
+                       ((uint8_t*)&l)[i] = ((uint8_t*)key)[(c-1)*4 + i];
+       } else {
+               l = ((uint32_t*)key)[c-1];
+       }
+       
+       s->S[0] = P32;
+       for(i=1; i<2*rounds+4; ++i){
+               s->S[i] = s->S[i-1] + Q32;
+       }
+       
+       a=b=j=i=0;
+       v = 3 * ((c > 2*rounds+4)?c:(2*rounds+4));
+       for(p=1; p<=v; ++p){
+               a = s->S[i] = rotl32(s->S[i] + a + b, 3);
+               if (j==c-1){
+                       b = l = rotl32(l+a+b, a+b);
+               } else {
+                       b = ((uint32_t*)key)[j] = rotl32(((uint32_t*)key)[j]+a+b, a+b);
+               }
+               i = (i+1) % (2*rounds+4);
+               j = (j+1) % c;
+       }
+       return 0;
+}
+void rc6_free(rc6_ctx_t *s){
+       free(s->S);
+} 
+#define LG_W 5
+#define A (((uint32_t*)block)[0])
+#define B (((uint32_t*)block)[1])
+#define C (((uint32_t*)block)[2])
+#define D (((uint32_t*)block)[3])
+void rc6_enc(void* block, rc6_ctx_t *s){
+       uint8_t i;
+       uint32_t t,u,x; /* greetings to Linux? */
+       B += s->S[0];
+       D += s->S[1];
+       for (i=1; i<=s->rounds; ++i){
+               t = rotl32(B * (2*B+1), LG_W);
+               u = rotl32(D * (2*D+1), LG_W);
+               A = rotl32((A ^ t), u) + s->S[2*i];
+               C = rotl32((C ^ u), t) + s->S[2*i+1];
+               x = A;
+               A = B;
+               B = C;
+               C = D;
+               D = x;
+       }
+       A += s->S[2*s->rounds+2];
+       C += s->S[2*s->rounds+3];
+}
+void rc6_dec(void* block, rc6_ctx_t *s){
+       uint8_t i;
+       uint32_t t,u,x; /* greetings to Linux? */
+       C -= s->S[2*s->rounds+3];
+       A -= s->S[2*s->rounds+2];
+       
+       for (i=s->rounds; i>0; --i){
+               x=D;
+               D=C;
+               C=B;
+               B=A;
+               A=x;
+               u = rotl32(D * (2*D+1), LG_W);
+               t = rotl32(B * (2*B+1), LG_W);
+               C = rotr32(C - s->S[2*i+1], t) ^ u;
+               A = rotr32(A - s->S[2*i+0], u) ^ t;
+       }
+       D -= s->S[1];
+       B -= s->S[0];
+}
diff --git a/rc6/rc6.h b/rc6/rc6.h
new file mode 100644 (file)
index 0000000..429a1d3
--- /dev/null
+++ b/rc6/rc6.h
@@ -0,0 +1,52 @@
+/* rc6.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* 
+ * File:       rc6.h
+ * Author:     Daniel Otte
+ * Date:       06.08.2006
+ * License: GPL
+ * Description: Implementation of the RC6 cipher algorithm.
+ *     This implementation is restricted to 32-bit words, but free in the choice of number of rounds (0 to 255).
+ *     so it is RC6-32/r/b
+ */
+
+#ifndef RC6_H_
+#define RC6_H_
+
+#include <stdint.h>
+typedef struct rc6_ctx_st{
+       uint8_t         rounds;         /* specifys the number of rounds; default: 20 */
+       uint32_t*       S;                      /* the round-keys */
+} rc6_ctx_t;
+uint8_t rc6_init(void* key, uint16_t keylength_b, rc6_ctx_t *s);
+uint8_t rc6_initl(void* key, uint16_t keylength_b, uint8_t rounds, rc6_ctx_t *s);
+void rc6_enc(void* block, rc6_ctx_t *s);
+
+void rc6_dec(void* block, rc6_ctx_t *s);
+void rc6_free(rc6_ctx_t *s); 
+
+#endif /* RC6_H_ */
+
diff --git a/seed-asm.S b/seed-asm.S
deleted file mode 100644 (file)
index 84866c3..0000000
+++ /dev/null
@@ -1,957 +0,0 @@
-/* seed-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       seed-asm.S
- * \author     Daniel Otte 
- * \date       2007-06-1
- * \brief      SEED parts in assembler for AVR
- * \par License        
- * GPLv3 or later
- * 
- */
-#include "avr-asm-macros.S"
-
-/******************************************************************************/       
-/*
-#define M0 0xfc
-#define M1 0xf3
-#define M2 0xcf
-#define M3 0x3f
-
-#define X3 (((uint8_t*)(&x))[0])
-#define X2 (((uint8_t*)(&x))[1])
-#define X1 (((uint8_t*)(&x))[2])
-#define X0 (((uint8_t*)(&x))[3])
-
-#define Z3 (((uint8_t*)(&z))[0])
-#define Z2 (((uint8_t*)(&z))[1])
-#define Z1 (((uint8_t*)(&z))[2])
-#define Z0 (((uint8_t*)(&z))[3])
-
-uint32_t g_function(uint32_t x){
-       uint32_t z;
-       / * sbox substitution * /
-       X3 = pgm_read_byte(&(seed_sbox2[X3]));
-       X2 = pgm_read_byte(&(seed_sbox1[X2]));
-       X1 = pgm_read_byte(&(seed_sbox2[X1]));
-       X0 = pgm_read_byte(&(seed_sbox1[X0]));
-       / * now the permutation * /
-       Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
-       Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
-       Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
-       Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
-       return z;
-}
-*/
-M0 = 0xfc
-M1 = 0xf3
-M2 = 0xcf
-M3 = 0x3f
-X0 = 18
-X1 = 19
-X2 = 20
-X3 = 21
-Z0 = 25
-Z1 = 24
-Z2 = 23
-Z3 = 22
-T0 = X0
-T1 = 26
-T2 = 27
-T3 = X1
-/*
- *  param x: r22:r25
- *  X0 = R25
- *  X1 = R24
- *  X2 = R23
- *  X3 = R22
- */    
-seed_g_function:
-       ldi r30, lo8(seed_sbox1)
-       ldi r31, hi8(seed_sbox1)
-       movw r26, r30
-       add r30, Z2
-       adc r31, r1
-       lpm X2, Z
-       movw r30, r26
-       add r30, Z0
-       adc r31, r1
-       lpm X0, Z
-       inc r27 /* switch X to point to sbox2 */
-       movw r30, r26
-       add r30, Z3
-       adc r31, r1
-       lpm X3, Z
-       movw r30, r26
-       add r30, Z1
-       adc r31, r1
-       lpm X1, Z
-       /* now the secound part */
-       mov Z0, X0
-       mov Z1, X0
-       mov Z2, X0
-       mov Z3, X0
-       andi Z0, M0
-       andi Z1, M1
-       andi Z2, M2
-       andi Z3, M3     
-       mov T0, X1
-       mov T1, X1
-       mov T2, X1
-       ; mov T3, X1 /* T3 = X1 */
-       andi T0, M1
-       andi T1, M2
-       andi T2, M3
-       andi T3, M0
-       eor Z0, T0
-       eor Z1, T1
-       eor Z2, T2
-       eor Z3, T3
-       mov T0, X2
-       mov T1, X2
-       mov T2, X2
-       mov T3, X2
-       andi T0, M2
-       andi T1, M3
-       andi T2, M0
-       andi T3, M1
-       eor Z0, T0
-       eor Z1, T1
-       eor Z2, T2
-       eor Z3, T3
-       mov T0, X3
-       mov T1, X3
-       mov T2, X3
-       mov T3, X3
-       andi T0, M3
-       andi T1, M0
-       andi T2, M1
-       andi T3, M2
-       eor Z0, T0
-       eor Z1, T1
-       eor Z2, T2
-       eor Z3, T3
-       ret
-
-seed_sbox1:
-.byte   169,  133,  214,  211,   84,   29,  172,   37 
-.byte    93,   67,   24,   30,   81,  252,  202,   99 
-.byte    40,   68,   32,  157,  224,  226,  200,   23 
-.byte   165,  143,    3,  123,  187,   19,  210,  238 
-.byte   112,  140,   63,  168,   50,  221,  246,  116 
-.byte   236,  149,   11,   87,   92,   91,  189,    1 
-.byte    36,   28,  115,  152,   16,  204,  242,  217 
-.byte    44,   231, 114,  131,  155,  209,  134,  201 
-.byte    96,   80,  163,  235,   13,  182,  158,   79 
-.byte   183,   90,  198,  120,  166,   18,  175,  213 
-.byte    97,  195,  180,   65,   82,  125,  141,    8 
-.byte    31,  153,    0,   25,    4,   83,  247,  225 
-.byte   253,  118,   47,   39,  176,  139,   14,  171 
-.byte   162,  110,  147,   77,  105,  124,    9,   10 
-.byte   191,  239,  243,  197,  135,   20,  254,  100 
-.byte   222,   46,   75,   26,    6,   33,  107,  102 
-.byte     2,  245,  146,  138,   12,  179,  126,  208 
-.byte   122,   71,  150,  229,   38,  128,  173,  223 
-.byte   161,   48,   55,  174,   54,   21,   34,   56 
-.byte   244,  167,   69,   76,  129,  233,  132,  151 
-.byte    53,  203,  206,   60,  113,   17,  199,  137 
-.byte   117,  251,  218,  248,  148,   89,  130,  196 
-.byte   255,   73,   57,  103,  192,  207,  215,  184 
-.byte    15,  142,   66,   35,  145,  108,  219,  164 
-.byte    52,  241,   72,  194,  111,   61,   45,   64 
-.byte   190,   62,  188,  193,  170,  186,   78,   85 
-.byte    59,  220,  104,  127,  156,  216,   74,   86 
-.byte   119,  160,  237,   70,  181,   43,  101,  250 
-.byte   227,  185,  177,  159,   94,  249,  230,  178 
-.byte    49,  234,  109,   95,  228,  240,  205,  136 
-.byte    22,   58,   88,  212,   98,   41,    7,   51 
-.byte   232,   27,    5,  121,  144,  106,   42,  154
-
-
-seed_sbox2:
-.byte    56,  232,   45,  166,  207,  222,  179,  184 
-.byte   175,   96,   85,  199,   68,  111,  107,   91 
-.byte   195,   98,   51,  181,   41,  160,  226,  167 
-.byte   211,  145,   17,    6,   28,  188,   54,   75 
-.byte   239,  136,  108,  168,   23,  196,   22,  244 
-.byte   194,   69,  225,  214,   63,   61,  142,  152 
-.byte    40,   78,  246,   62,  165,  249,   13,  223 
-.byte   216,   43,  102,  122,   39,   47,  241,  114 
-.byte    66,  212,   65,  192,  115,  103,  172,  139 
-.byte   247,  173,  128,   31,  202,   44,  170,   52 
-.byte   210,   11,  238,  233,   93,  148,   24,  248 
-.byte    87,  174,    8,  197,   19,  205,  134,  185 
-.byte   255,  125,  193,   49,  245,  138,  106,  177 
-.byte   209,   32,  215,    2,   34,    4,  104,  113 
-.byte     7,  219,  157,  153,   97,  190,  230,   89 
-.byte   221,   81,  144,  220,  154,  163,  171,  208 
-.byte   129,   15,   71,   26,  227,  236,  141,  191 
-.byte   150,  123,   92,  162,  161,   99,   35,   77 
-.byte   200,  158,  156,   58,   12,   46,  186,  110 
-.byte   159,   90,  242,  146,  243,   73,  120,  204 
-.byte    21,  251,  112,  117,  127,   53,   16,    3 
-.byte   100,  109,  198,  116,  213,  180,  234,    9 
-.byte   118,   25,  254,   64,   18,  224,  189,    5 
-.byte   250,    1,  240,   42,   94,  169,   86,   67 
-.byte   133,   20,  137,  155,  176,  229,   72,  121 
-.byte   151,  252,   30,  130,   33,  140,   27,   95 
-.byte   119,   84,  178,   29,   37,   79,    0,   70 
-.byte   237,   88,   82,  235,  126,  218,  201,  253 
-.byte    48,  149,  101,   60,  182,  228,  187,  124 
-.byte    14,   80,   57,   38,   50,  132,  105,  147 
-.byte    55,  231,   36,  164,  203,   83,   10,  135 
-.byte   217,   76,  131,  143,  206,   59,   74,  183 
-
-/******************************************************************************/
-
-/*
-static
-uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
-       uint32_t c,d;
-
-       c = *a & 0x00000000FFFFFFFFLL;
-       d = (*a>>32) & 0x00000000FFFFFFFFLL;
-       
-       c ^= k0; d ^= k1;
-       d ^= c;
-       d = g_function(d);
-       c = bigendian_sum32(c,d);
-       c = g_function(c);
-       d = bigendian_sum32(c,d);
-       d = g_function(d);
-       c = bigendian_sum32(c,d);       
-       return ((uint64_t)d << 32) | c;
-}
-*/
-/*
- * param a   r24:r25
- * param k0  r20:r23
- * param k1  r16:r19
- */
-D0 = 10
-D1 = 11
-C0 = 12
-C1 = 13
-C2 = 14
-C3 = 15
-D2 = 16
-D3 = 17
-seed_f_function:
-       push_range 10, 17
-       movw r30, r24
-       ld C0, Z+
-       ld C1, Z+
-       ld C2, Z+
-       ld C3, Z+
-       eor C0, r20
-       eor C1, r21
-       eor C2, r22
-       eor C3, r23
-       ld r22, Z+
-       ld r23, Z+
-       ld r24, Z+
-       ld r25, Z+
-       eor r22, r16
-       eor r23, r17
-       eor r24, r18
-       eor r25, r19
-       eor r22, C0
-       eor r23, C1
-       eor r24, C2
-       eor r25, C3
-       rcall seed_g_function
-       mov D0, r22
-       mov D1, r23
-       mov D2, r24
-       mov D3, r25
-
-       add r25, C3
-       adc r24, C2
-       adc r23, C1
-       adc r22, C0
-       rcall seed_g_function
-       mov C0, r22
-       mov C1, r23
-       mov C2, r24
-       mov C3, r25
-
-       add r25, D3
-       adc r24, D2
-       adc r23, D1
-       adc r22, D0
-       rcall seed_g_function
-       mov D0, r22
-       mov D1, r23
-       mov D2, r24
-       mov D3, r25
-
-       add C3, r25
-       adc C2, r24
-       adc C1, r23
-       adc C0, r22
-
-       mov r18, C0
-       mov r19, C1
-       mov r20, C2
-       mov r21, C3
-       
-       pop_range 10, 17
-       ret
-
-/******************************************************************************/
-/*
-void seed_init(uint8_t * key, seed_ctx_t * ctx){
-       memcpy(ctx->k, key, 128/8);
-}
-*/
-
-.global seed_init
-seed_init:
-       movw r26, r24
-       movw r30, r22
-       ldi r22, 16
-1:
-       ld r0, X+
-       st Z+, r0
-       dec r22
-       brne 1b 
-       ret
-/******************************************************************************/
-/*
-typedef struct {
-       uint32_t k0, k1;
-} keypair_t;
-
-keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
-       keypair_t ret;
-       if (curround>15){
-               / * ERROR * /
-               ret.k0 = ret.k1 = 0;
-       } else {
-       / *     ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
-               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
-               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
-               ret.k0 = seed_g_function(ret.k0);
-               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
-               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = seed_g_function(ret.k1);
-               
-               if (curround & 1){
-                       / * odd round (1,3,5, ...) * /
-                       ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
-               } else {
-                       / * even round (0,2,4, ...) * /
-                       ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
-               }
-       }
-       return ret;
-}
-*/
-/*
- * param keystate: r24:r25
- * param curround: r22
- */
-XRC0 = 10
-XRC1 = 11
-XRC2 = 12
-XRC3 = 13
-D0 = 14
-D1 = 15
-D2 = 16
-D3 = 17
-
-compute_keys:
-       ldi r30, lo8(seed_kc)
-       ldi r31, hi8(seed_kc)
-       lsl r22
-       lsl r22
-       add r30, r22
-       adc r31, r1
-       lpm XRC0, Z+
-       lpm XRC1, Z+
-       lpm XRC2, Z+
-       lpm XRC3, Z+
-       movw r28, r24
-       ldd r25, Y+0*4+3
-       ldd r24, Y+0*4+2
-       ldd r23, Y+0*4+1
-       ldd r22, Y+0*4+0
-       
-       ldd r0, Y+2*4+3
-       add r25, r0
-       ldd r0, Y+2*4+2
-       adc r24, r0
-       ldd r0, Y+2*4+1
-       adc r23, r0
-       ldd r0, Y+2*4+0
-       adc r22, r0
-
-       sub r25, XRC3
-       sbc r24, XRC2
-       sbc r23, XRC1
-       sbc r22, XRC0
-       rcall seed_g_function
-       mov D0, r22
-       mov D1, r23
-       mov D2, r24
-       mov D3, r25
-       
-
-       ldd r25, Y+1*4+3
-       ldd r24, Y+1*4+2
-       ldd r23, Y+1*4+1
-       ldd r22, Y+1*4+0
-
-       ldd r0, Y+3*4+3
-       sub r25, r0
-       ldd r0, Y+3*4+2
-       sbc r24, r0
-       ldd r0, Y+3*4+1
-       sbc r23, r0
-       ldd r0, Y+3*4+0
-       sbc r22, r0
-
-       add r25, XRC3
-       adc r24, XRC2
-       adc r23, XRC1
-       adc r22, XRC0
-       rcall seed_g_function
-
-       mov r21, D3
-       mov r20, D2
-       mov r19, D1
-       mov r18, D0 
-       ret
-
-seed_getnextkeys:
-       push_range 10, 17
-       push r28
-       push r29
-;      andi r22, 0x0F
-       bst r22,0
-       rcall compute_keys              
-       brtc even_round
-odd_round:
-
-       adiw r28, 8
-       ld r26, Y
-       ldd r0, Y+1
-       std Y+0, r0
-       ldd r0, Y+2
-       std Y+1, r0
-       ldd r0, Y+3
-       std Y+2, r0
-       ldd r0, Y+4
-       std Y+3, r0
-       ldd r0, Y+5
-       std Y+4, r0
-       ldd r0, Y+6
-       std Y+5, r0
-       ldd r0, Y+7
-       std Y+6, r0
-       std Y+7, r26    
-/*
-       movw r30, r28
-       ld r26, Z+
-       ldi r27, 7
-1:
-       ld r0, Z+
-       st Y+, r0
-       dec r27
-       brne 1b
-       st Y, r26
-*/     
-       rjmp 4f
-
-even_round:
-
-       ldd r26, Y+7
-       ldd r0, Y+6
-       std Y+7, r0
-       ldd r0, Y+5
-       std Y+6, r0
-       ldd r0, Y+4
-       std Y+5, r0
-       ldd r0, Y+3
-       std Y+4, r0
-       ldd r0, Y+2
-       std Y+3, r0
-       ldd r0, Y+1
-       std Y+2, r0
-       ldd r0, Y+0
-       std Y+1, r0
-       std Y+0, r26
-/*
-       adiw r28, 7     
-       ld r26, Y
-       ldi r27, 7      
-1:
-       ld r0, -Y
-       std Y+1, r0
-       dec r27
-       brne 1b
-       st Y, r26
-*/
-4:     
-       pop r29
-       pop r28
-       pop_range 10, 17
-       ret
-
-/******************************************************************************/
-/*
-keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
-       keypair_t ret;
-       if (curround>15){
-               / * ERROR * /
-               ret.k0 = ret.k1 = 0;
-       } else {
-               if (curround & 1){
-                       / * odd round (1,3,5, ..., 15) * /
-                       ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
-               } else {
-                       / * even round (0,2,4, ..., 14) * /
-                       ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
-               }
-       / *     ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
-               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
-               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
-               ret.k0 = seed_g_function(ret.k0);
-               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
-               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = seed_g_function(ret.k1);
-               }
-       return ret;
-}
-*/
-/*
- * param keystate: r24:r25
- * param curround: r22
- */
-
-seed_getprevkeys:
-       push_range 10, 17
-       push r28
-       push r29
-       movw r28, r24   
-;      andi r22, 0x0F
-       bst r22, 0
-       brts r_odd_round
-r_even_round:
-       ldd r26, Y+0
-       ldd r0, Y+1
-       std Y+0, r0
-       ldd r0, Y+2
-       std Y+1, r0
-       ldd r0, Y+3
-       std Y+2, r0
-       ldd r0, Y+4
-       std Y+3, r0
-       ldd r0, Y+5
-       std Y+4, r0
-       ldd r0, Y+6
-       std Y+5, r0
-       ldd r0, Y+7
-       std Y+6, r0
-       std Y+7, r26    
-/*
-       movw r30, r28
-       ld r26, Z+
-       ldi r27, 7
-1:
-       ld r0, Z+
-       st Y+, r0
-       dec r27
-       brne 1b
-       st Y, r26
-*/     
-
-       rjmp 4f
-r_odd_round:
-       ldd r26, Y+8+7
-       ldd r0, Y+8+6
-       std Y+8+7, r0
-       ldd r0, Y+8+5
-       std Y+8+6, r0
-       ldd r0, Y+8+4
-       std Y+8+5, r0
-       ldd r0, Y+8+3
-       std Y+8+4, r0
-       ldd r0, Y+8+2
-       std Y+8+3, r0
-       ldd r0, Y+8+1
-       std Y+8+2, r0
-       ldd r0, Y+8+0
-       std Y+8+1, r0
-       std Y+8+0, r26
-/*
-       adiw r28, 7     
-       ld r26, Y
-       ldi r27, 7      
-1:
-       ld r0, -Y
-       std Y+1, r0
-       dec r27
-       brne 1b
-       st Y, r26
-*/
-4:
-       rcall compute_keys      
-
-       pop r29
-       pop r28
-       pop_range 10, 17
-       ret
-
-/******************************************************************************/
-
-seed_kc:
-.long   0xb979379e 
-.long   0x73f36e3c
-.long   0xe6e6dd78 
-.long   0xcccdbbf1 
-.long   0x999b77e3 
-.long   0x3337efc6 
-.long   0x676ede8d 
-.long   0xcfdcbc1b 
-.long   0x9eb97937
-.long   0x3c73f36e     
-.long   0x78e6e6dd
-.long   0xf1cccdbb
-.long   0xe3999b77
-.long   0xc63337ef
-.long   0x8d676ede
-.long   0x1bcfdcbc
-
-/******************************************************************************/
-/*
-#define L (((uint64_t*)buffer)[0])
-#define R (((uint64_t*)buffer)[1])
-
-void seed_enc(void * buffer, seed_ctx_t * ctx){
-       uint8_t r;
-       keypair_t k;
-       for(r=0; r<8; ++r){
-                       k = seed_getnextkeys(ctx->k, 2*r);
-/ *
-       DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L:   "); uart_hexdump((uint8_t*)buffer+0, 8);
-       DEBUG_S("\r\n\t DBG R:   "); uart_hexdump((uint8_t*)buffer+8, 8);
-* /
-                       L ^= seed_f_function(&R,k.k0,k.k1);
-                       
-                       k = seed_getnextkeys(ctx->k, 2*r+1);
-/ *
-       DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L:   "); uart_hexdump((uint8_t*)buffer+8, 8);
-       DEBUG_S("\r\n\t DBG R:   "); uart_hexdump((uint8_t*)buffer+0, 8);
-* /
-                       R ^= seed_f_function(&L,k.k0,k.k1);
-       }
-       / * just an exchange without temp. variable * /
-       L ^= R;
-       R ^= L;
-       L ^= R;
-}
-*/
-/*
- * param buffer: r24:r25
- * param ctx:    r22:r23
- */
-CTR  = 9
-xLPTR = 10
-xRPTR = 12
-CPTR = 14
-
-.global seed_enc
-seed_enc:
-       push_range 9, 17
-       push r28
-       push r29        
-       clr CTR
-       movw xLPTR, r24
-       adiw r24, 8
-       movw xRPTR, r24         
-       movw CPTR, r22
-1:
-       movw r28, xLPTR
-       movw r24, CPTR
-       mov r22, CTR
-       lsl r22
-       rcall seed_getnextkeys  
-
-       /* use pen & paper to understand the following permutation */
-       movw r16, r22
-       movw r22, r18
-       movw r18, r24
-       movw r24, r20
-       movw r20, r22
-       movw r22, r24
-       movw r24, xRPTR 
-
-       rcall seed_f_function
-
-       ld r0, Y
-       eor r0, r18
-       st Y+, r0
-       ld r0, Y
-       eor r0, r19
-       st Y+, r0
-       ld r0, Y
-       eor r0, r20
-       st Y+, r0
-       ld r0, Y
-       eor r0, r21
-       st Y+, r0
-       ld r0, Y
-       eor r0, r22
-       st Y+, r0
-       ld r0, Y
-       eor r0, r23
-       st Y+, r0
-       ld r0, Y
-       eor r0, r24
-       st Y+, r0
-       ld r0, Y
-       eor r0, r25
-       st Y+, r0
-       /* secound half */
-       movw r24, CPTR
-       mov r22, CTR
-       lsl r22
-       inc r22
-       rcall seed_getnextkeys  
-
-       movw r16, r22
-       movw r22, r18
-       movw r18, r24
-       movw r24, r20
-       movw r20, r22
-       movw r22, r24
-       movw r24, xLPTR 
-       
-       rcall seed_f_function
-
-       ld r0, Y
-       eor r0, r18
-       st Y+, r0
-       ld r0, Y
-       eor r0, r19
-       st Y+, r0
-       ld r0, Y
-       eor r0, r20
-       st Y+, r0
-       ld r0, Y
-       eor r0, r21
-       st Y+, r0
-       ld r0, Y
-       eor r0, r22
-       st Y+, r0
-       ld r0, Y
-       eor r0, r23
-       st Y+, r0
-       ld r0, Y
-       eor r0, r24
-       st Y+, r0
-       ld r0, Y
-       eor r0, r25
-       st Y+, r0
-       
-       inc CTR
-       bst CTR, 3
-       brts 3f
-       rjmp 1b
-3:
-       movw r28, xLPTR
-       movw r30, xRPTR
-       ldi r17, 8
-4:
-       ld r10, Y
-       ld r11, Z
-       st Z+, r10
-       st Y+, r11
-       dec r17
-       brne 4b
-5:
-       pop r29
-       pop r28
-       pop_range 9, 17
-       ret
-
-/******************************************************************************/
-/*
-#define L (((uint64_t*)buffer)[0])
-#define R (((uint64_t*)buffer)[1])
-
-void seed_dec(void * buffer, seed_ctx_t * ctx){
-       int8_t r;
-       keypair_t k;
-       for(r=7; r>=0; --r){
-                       k = seed_getprevkeys(ctx->k, 2*r+1);
-/ *
-       DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
-       DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
-* /
-                       L ^= seed_f_function(&R,k.k0,k.k1);
-                       
-                       k = seed_getprevkeys(ctx->k, 2*r+0);
-/ *
-       DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
-       DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
-* /
-                       R ^= seed_f_function(&L,k.k0,k.k1);
-       }
-       / * just an exchange without temp. variable * /
-       L ^= R;
-       R ^= L;
-       L ^= R;
-}
-*/
-/*
- * param buffer: r24:r25
- * param ctx:    r22:r23
- */
-CTR  = 9
-xLPTR = 10
-xRPTR = 12
-CPTR = 14
-
-.global seed_dec
-seed_dec:
-       push_range 9, 17
-       push r28
-       push r29        
-       ldi r16, 7
-       mov CTR, r16
-       movw xLPTR, r24
-       adiw r24, 8
-       movw xRPTR, r24         
-       movw CPTR, r22
-1:
-       movw r28, xLPTR
-       movw r24, CPTR
-       mov r22, CTR
-       lsl r22
-       inc r22
-       rcall seed_getprevkeys  
-
-       /* use pen & paper to understand the following permutation */
-       movw r16, r22
-       movw r22, r18
-       movw r18, r24
-       movw r24, r20
-       movw r20, r22
-       movw r22, r24
-       movw r24, xRPTR 
-
-       rcall seed_f_function
-
-       ld r0, Y
-       eor r0, r18
-       st Y+, r0
-       ld r0, Y
-       eor r0, r19
-       st Y+, r0
-       ld r0, Y
-       eor r0, r20
-       st Y+, r0
-       ld r0, Y
-       eor r0, r21
-       st Y+, r0
-       ld r0, Y
-       eor r0, r22
-       st Y+, r0
-       ld r0, Y
-       eor r0, r23
-       st Y+, r0
-       ld r0, Y
-       eor r0, r24
-       st Y+, r0
-       ld r0, Y
-       eor r0, r25
-       st Y+, r0
-       /* secound half */
-       movw r24, CPTR
-       mov r22, CTR
-       lsl r22
-       rcall seed_getprevkeys  
-
-       movw r16, r22
-       movw r22, r18
-       movw r18, r24
-       movw r24, r20
-       movw r20, r22
-       movw r22, r24
-       movw r24, xLPTR 
-       
-       rcall seed_f_function
-
-       ld r0, Y
-       eor r0, r18
-       st Y+, r0
-       ld r0, Y
-       eor r0, r19
-       st Y+, r0
-       ld r0, Y
-       eor r0, r20
-       st Y+, r0
-       ld r0, Y
-       eor r0, r21
-       st Y+, r0
-       ld r0, Y
-       eor r0, r22
-       st Y+, r0
-       ld r0, Y
-       eor r0, r23
-       st Y+, r0
-       ld r0, Y
-       eor r0, r24
-       st Y+, r0
-       ld r0, Y
-       eor r0, r25
-       st Y+, r0
-       
-       dec CTR
-       brmi 3f
-       rjmp 1b
-3:
-       movw r28, xLPTR
-       movw r30, xRPTR
-       ldi r17, 8
-4:
-       ld r10, Y
-       ld r11, Z
-       st Z+, r10
-       st Y+, r11
-       dec r17
-       brne 4b
-5:
-       pop r29
-       pop r28
-       pop_range 9, 17
-       ret
-
diff --git a/seed.h b/seed.h
deleted file mode 100644 (file)
index 78d7d59..0000000
--- a/seed.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* seed.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       seed.h
- * \author     Daniel Otte 
- * \date       2007-06-1
- * \brief      declarations for seed
- * \par License        
- * GPL
- * 
- */
-#ifndef SEED_H_
-#define SEED_H_
-
-#include <stdint.h>
-/** \typedef seed_ctx_t
- * \brief SEED context
- * 
- * A variable of this type may hold the key material for the SEED cipher. 
- * This context is regulary generated by the 
- * void seed_init(const void * key, seed_ctx_t * ctx) function.
- */
-typedef struct{
-       uint32_t k[4];
-} seed_ctx_t;
-
-/******************************************************************************/
-
-/** \fn void seed_init(const void * key, seed_ctx_t * ctx)
- * \brief initializes context for SEED operation
- * 
- * This function copys the key material into a context variable.
- * 
- * \param key  pointer to the key material (128 bit = 16 bytes)
- * \param ctx  pointer to the context (seed_ctx_t)
- */
-void seed_init(const void * key, seed_ctx_t * ctx);
-
-/** \fn void seed_enc(void * buffer,const seed_ctx_t * ctx)
- * \brief encrypt a block with SEED
- * 
- * This function encrypts a block of 64 bits (8 bytes) with the SEED algorithm.
- * The round keys are computed on demand, so the context is modifyed while
- * encrypting but the original stated is restored when the function exits.
- * 
- * \param buffer pointer to the block (64 bit = 8 byte) which will be encrypted
- * \param ctx    pointer to the key material (seed_ctx_t)
- */
-void seed_enc(void * buffer, const seed_ctx_t * ctx);
-
-
-/** \fn void seed_dec(void * buffer, const seed_ctx_t * ctx)
- * \brief decrypt a block with SEED
- * 
- * This function decrypts a block of 64 bits (8 bytes) with the SEED algorithm.
- * The round keys are computed on demand, so the context is modifyed while
- * decrypting but the original stated is restored when the function exits.
- * 
- * \param buffer pointer to the block (64 bit = 8 byte) which will be decrypted
- * \param ctx    pointer to the key material (seed_ctx_t)
- */
-void seed_dec(void * buffer, const seed_ctx_t * ctx);
-
-       
-#endif /*SEED_H_*/
diff --git a/seed/seed-asm.S b/seed/seed-asm.S
new file mode 100644 (file)
index 0000000..84866c3
--- /dev/null
@@ -0,0 +1,957 @@
+/* seed-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       seed-asm.S
+ * \author     Daniel Otte 
+ * \date       2007-06-1
+ * \brief      SEED parts in assembler for AVR
+ * \par License        
+ * GPLv3 or later
+ * 
+ */
+#include "avr-asm-macros.S"
+
+/******************************************************************************/       
+/*
+#define M0 0xfc
+#define M1 0xf3
+#define M2 0xcf
+#define M3 0x3f
+
+#define X3 (((uint8_t*)(&x))[0])
+#define X2 (((uint8_t*)(&x))[1])
+#define X1 (((uint8_t*)(&x))[2])
+#define X0 (((uint8_t*)(&x))[3])
+
+#define Z3 (((uint8_t*)(&z))[0])
+#define Z2 (((uint8_t*)(&z))[1])
+#define Z1 (((uint8_t*)(&z))[2])
+#define Z0 (((uint8_t*)(&z))[3])
+
+uint32_t g_function(uint32_t x){
+       uint32_t z;
+       / * sbox substitution * /
+       X3 = pgm_read_byte(&(seed_sbox2[X3]));
+       X2 = pgm_read_byte(&(seed_sbox1[X2]));
+       X1 = pgm_read_byte(&(seed_sbox2[X1]));
+       X0 = pgm_read_byte(&(seed_sbox1[X0]));
+       / * now the permutation * /
+       Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
+       Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
+       Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
+       Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
+       return z;
+}
+*/
+M0 = 0xfc
+M1 = 0xf3
+M2 = 0xcf
+M3 = 0x3f
+X0 = 18
+X1 = 19
+X2 = 20
+X3 = 21
+Z0 = 25
+Z1 = 24
+Z2 = 23
+Z3 = 22
+T0 = X0
+T1 = 26
+T2 = 27
+T3 = X1
+/*
+ *  param x: r22:r25
+ *  X0 = R25
+ *  X1 = R24
+ *  X2 = R23
+ *  X3 = R22
+ */    
+seed_g_function:
+       ldi r30, lo8(seed_sbox1)
+       ldi r31, hi8(seed_sbox1)
+       movw r26, r30
+       add r30, Z2
+       adc r31, r1
+       lpm X2, Z
+       movw r30, r26
+       add r30, Z0
+       adc r31, r1
+       lpm X0, Z
+       inc r27 /* switch X to point to sbox2 */
+       movw r30, r26
+       add r30, Z3
+       adc r31, r1
+       lpm X3, Z
+       movw r30, r26
+       add r30, Z1
+       adc r31, r1
+       lpm X1, Z
+       /* now the secound part */
+       mov Z0, X0
+       mov Z1, X0
+       mov Z2, X0
+       mov Z3, X0
+       andi Z0, M0
+       andi Z1, M1
+       andi Z2, M2
+       andi Z3, M3     
+       mov T0, X1
+       mov T1, X1
+       mov T2, X1
+       ; mov T3, X1 /* T3 = X1 */
+       andi T0, M1
+       andi T1, M2
+       andi T2, M3
+       andi T3, M0
+       eor Z0, T0
+       eor Z1, T1
+       eor Z2, T2
+       eor Z3, T3
+       mov T0, X2
+       mov T1, X2
+       mov T2, X2
+       mov T3, X2
+       andi T0, M2
+       andi T1, M3
+       andi T2, M0
+       andi T3, M1
+       eor Z0, T0
+       eor Z1, T1
+       eor Z2, T2
+       eor Z3, T3
+       mov T0, X3
+       mov T1, X3
+       mov T2, X3
+       mov T3, X3
+       andi T0, M3
+       andi T1, M0
+       andi T2, M1
+       andi T3, M2
+       eor Z0, T0
+       eor Z1, T1
+       eor Z2, T2
+       eor Z3, T3
+       ret
+
+seed_sbox1:
+.byte   169,  133,  214,  211,   84,   29,  172,   37 
+.byte    93,   67,   24,   30,   81,  252,  202,   99 
+.byte    40,   68,   32,  157,  224,  226,  200,   23 
+.byte   165,  143,    3,  123,  187,   19,  210,  238 
+.byte   112,  140,   63,  168,   50,  221,  246,  116 
+.byte   236,  149,   11,   87,   92,   91,  189,    1 
+.byte    36,   28,  115,  152,   16,  204,  242,  217 
+.byte    44,   231, 114,  131,  155,  209,  134,  201 
+.byte    96,   80,  163,  235,   13,  182,  158,   79 
+.byte   183,   90,  198,  120,  166,   18,  175,  213 
+.byte    97,  195,  180,   65,   82,  125,  141,    8 
+.byte    31,  153,    0,   25,    4,   83,  247,  225 
+.byte   253,  118,   47,   39,  176,  139,   14,  171 
+.byte   162,  110,  147,   77,  105,  124,    9,   10 
+.byte   191,  239,  243,  197,  135,   20,  254,  100 
+.byte   222,   46,   75,   26,    6,   33,  107,  102 
+.byte     2,  245,  146,  138,   12,  179,  126,  208 
+.byte   122,   71,  150,  229,   38,  128,  173,  223 
+.byte   161,   48,   55,  174,   54,   21,   34,   56 
+.byte   244,  167,   69,   76,  129,  233,  132,  151 
+.byte    53,  203,  206,   60,  113,   17,  199,  137 
+.byte   117,  251,  218,  248,  148,   89,  130,  196 
+.byte   255,   73,   57,  103,  192,  207,  215,  184 
+.byte    15,  142,   66,   35,  145,  108,  219,  164 
+.byte    52,  241,   72,  194,  111,   61,   45,   64 
+.byte   190,   62,  188,  193,  170,  186,   78,   85 
+.byte    59,  220,  104,  127,  156,  216,   74,   86 
+.byte   119,  160,  237,   70,  181,   43,  101,  250 
+.byte   227,  185,  177,  159,   94,  249,  230,  178 
+.byte    49,  234,  109,   95,  228,  240,  205,  136 
+.byte    22,   58,   88,  212,   98,   41,    7,   51 
+.byte   232,   27,    5,  121,  144,  106,   42,  154
+
+
+seed_sbox2:
+.byte    56,  232,   45,  166,  207,  222,  179,  184 
+.byte   175,   96,   85,  199,   68,  111,  107,   91 
+.byte   195,   98,   51,  181,   41,  160,  226,  167 
+.byte   211,  145,   17,    6,   28,  188,   54,   75 
+.byte   239,  136,  108,  168,   23,  196,   22,  244 
+.byte   194,   69,  225,  214,   63,   61,  142,  152 
+.byte    40,   78,  246,   62,  165,  249,   13,  223 
+.byte   216,   43,  102,  122,   39,   47,  241,  114 
+.byte    66,  212,   65,  192,  115,  103,  172,  139 
+.byte   247,  173,  128,   31,  202,   44,  170,   52 
+.byte   210,   11,  238,  233,   93,  148,   24,  248 
+.byte    87,  174,    8,  197,   19,  205,  134,  185 
+.byte   255,  125,  193,   49,  245,  138,  106,  177 
+.byte   209,   32,  215,    2,   34,    4,  104,  113 
+.byte     7,  219,  157,  153,   97,  190,  230,   89 
+.byte   221,   81,  144,  220,  154,  163,  171,  208 
+.byte   129,   15,   71,   26,  227,  236,  141,  191 
+.byte   150,  123,   92,  162,  161,   99,   35,   77 
+.byte   200,  158,  156,   58,   12,   46,  186,  110 
+.byte   159,   90,  242,  146,  243,   73,  120,  204 
+.byte    21,  251,  112,  117,  127,   53,   16,    3 
+.byte   100,  109,  198,  116,  213,  180,  234,    9 
+.byte   118,   25,  254,   64,   18,  224,  189,    5 
+.byte   250,    1,  240,   42,   94,  169,   86,   67 
+.byte   133,   20,  137,  155,  176,  229,   72,  121 
+.byte   151,  252,   30,  130,   33,  140,   27,   95 
+.byte   119,   84,  178,   29,   37,   79,    0,   70 
+.byte   237,   88,   82,  235,  126,  218,  201,  253 
+.byte    48,  149,  101,   60,  182,  228,  187,  124 
+.byte    14,   80,   57,   38,   50,  132,  105,  147 
+.byte    55,  231,   36,  164,  203,   83,   10,  135 
+.byte   217,   76,  131,  143,  206,   59,   74,  183 
+
+/******************************************************************************/
+
+/*
+static
+uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
+       uint32_t c,d;
+
+       c = *a & 0x00000000FFFFFFFFLL;
+       d = (*a>>32) & 0x00000000FFFFFFFFLL;
+       
+       c ^= k0; d ^= k1;
+       d ^= c;
+       d = g_function(d);
+       c = bigendian_sum32(c,d);
+       c = g_function(c);
+       d = bigendian_sum32(c,d);
+       d = g_function(d);
+       c = bigendian_sum32(c,d);       
+       return ((uint64_t)d << 32) | c;
+}
+*/
+/*
+ * param a   r24:r25
+ * param k0  r20:r23
+ * param k1  r16:r19
+ */
+D0 = 10
+D1 = 11
+C0 = 12
+C1 = 13
+C2 = 14
+C3 = 15
+D2 = 16
+D3 = 17
+seed_f_function:
+       push_range 10, 17
+       movw r30, r24
+       ld C0, Z+
+       ld C1, Z+
+       ld C2, Z+
+       ld C3, Z+
+       eor C0, r20
+       eor C1, r21
+       eor C2, r22
+       eor C3, r23
+       ld r22, Z+
+       ld r23, Z+
+       ld r24, Z+
+       ld r25, Z+
+       eor r22, r16
+       eor r23, r17
+       eor r24, r18
+       eor r25, r19
+       eor r22, C0
+       eor r23, C1
+       eor r24, C2
+       eor r25, C3
+       rcall seed_g_function
+       mov D0, r22
+       mov D1, r23
+       mov D2, r24
+       mov D3, r25
+
+       add r25, C3
+       adc r24, C2
+       adc r23, C1
+       adc r22, C0
+       rcall seed_g_function
+       mov C0, r22
+       mov C1, r23
+       mov C2, r24
+       mov C3, r25
+
+       add r25, D3
+       adc r24, D2
+       adc r23, D1
+       adc r22, D0
+       rcall seed_g_function
+       mov D0, r22
+       mov D1, r23
+       mov D2, r24
+       mov D3, r25
+
+       add C3, r25
+       adc C2, r24
+       adc C1, r23
+       adc C0, r22
+
+       mov r18, C0
+       mov r19, C1
+       mov r20, C2
+       mov r21, C3
+       
+       pop_range 10, 17
+       ret
+
+/******************************************************************************/
+/*
+void seed_init(uint8_t * key, seed_ctx_t * ctx){
+       memcpy(ctx->k, key, 128/8);
+}
+*/
+
+.global seed_init
+seed_init:
+       movw r26, r24
+       movw r30, r22
+       ldi r22, 16
+1:
+       ld r0, X+
+       st Z+, r0
+       dec r22
+       brne 1b 
+       ret
+/******************************************************************************/
+/*
+typedef struct {
+       uint32_t k0, k1;
+} keypair_t;
+
+keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
+       keypair_t ret;
+       if (curround>15){
+               / * ERROR * /
+               ret.k0 = ret.k1 = 0;
+       } else {
+       / *     ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
+               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
+               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
+               ret.k0 = seed_g_function(ret.k0);
+               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
+               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = seed_g_function(ret.k1);
+               
+               if (curround & 1){
+                       / * odd round (1,3,5, ...) * /
+                       ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
+               } else {
+                       / * even round (0,2,4, ...) * /
+                       ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
+               }
+       }
+       return ret;
+}
+*/
+/*
+ * param keystate: r24:r25
+ * param curround: r22
+ */
+XRC0 = 10
+XRC1 = 11
+XRC2 = 12
+XRC3 = 13
+D0 = 14
+D1 = 15
+D2 = 16
+D3 = 17
+
+compute_keys:
+       ldi r30, lo8(seed_kc)
+       ldi r31, hi8(seed_kc)
+       lsl r22
+       lsl r22
+       add r30, r22
+       adc r31, r1
+       lpm XRC0, Z+
+       lpm XRC1, Z+
+       lpm XRC2, Z+
+       lpm XRC3, Z+
+       movw r28, r24
+       ldd r25, Y+0*4+3
+       ldd r24, Y+0*4+2
+       ldd r23, Y+0*4+1
+       ldd r22, Y+0*4+0
+       
+       ldd r0, Y+2*4+3
+       add r25, r0
+       ldd r0, Y+2*4+2
+       adc r24, r0
+       ldd r0, Y+2*4+1
+       adc r23, r0
+       ldd r0, Y+2*4+0
+       adc r22, r0
+
+       sub r25, XRC3
+       sbc r24, XRC2
+       sbc r23, XRC1
+       sbc r22, XRC0
+       rcall seed_g_function
+       mov D0, r22
+       mov D1, r23
+       mov D2, r24
+       mov D3, r25
+       
+
+       ldd r25, Y+1*4+3
+       ldd r24, Y+1*4+2
+       ldd r23, Y+1*4+1
+       ldd r22, Y+1*4+0
+
+       ldd r0, Y+3*4+3
+       sub r25, r0
+       ldd r0, Y+3*4+2
+       sbc r24, r0
+       ldd r0, Y+3*4+1
+       sbc r23, r0
+       ldd r0, Y+3*4+0
+       sbc r22, r0
+
+       add r25, XRC3
+       adc r24, XRC2
+       adc r23, XRC1
+       adc r22, XRC0
+       rcall seed_g_function
+
+       mov r21, D3
+       mov r20, D2
+       mov r19, D1
+       mov r18, D0 
+       ret
+
+seed_getnextkeys:
+       push_range 10, 17
+       push r28
+       push r29
+;      andi r22, 0x0F
+       bst r22,0
+       rcall compute_keys              
+       brtc even_round
+odd_round:
+
+       adiw r28, 8
+       ld r26, Y
+       ldd r0, Y+1
+       std Y+0, r0
+       ldd r0, Y+2
+       std Y+1, r0
+       ldd r0, Y+3
+       std Y+2, r0
+       ldd r0, Y+4
+       std Y+3, r0
+       ldd r0, Y+5
+       std Y+4, r0
+       ldd r0, Y+6
+       std Y+5, r0
+       ldd r0, Y+7
+       std Y+6, r0
+       std Y+7, r26    
+/*
+       movw r30, r28
+       ld r26, Z+
+       ldi r27, 7
+1:
+       ld r0, Z+
+       st Y+, r0
+       dec r27
+       brne 1b
+       st Y, r26
+*/     
+       rjmp 4f
+
+even_round:
+
+       ldd r26, Y+7
+       ldd r0, Y+6
+       std Y+7, r0
+       ldd r0, Y+5
+       std Y+6, r0
+       ldd r0, Y+4
+       std Y+5, r0
+       ldd r0, Y+3
+       std Y+4, r0
+       ldd r0, Y+2
+       std Y+3, r0
+       ldd r0, Y+1
+       std Y+2, r0
+       ldd r0, Y+0
+       std Y+1, r0
+       std Y+0, r26
+/*
+       adiw r28, 7     
+       ld r26, Y
+       ldi r27, 7      
+1:
+       ld r0, -Y
+       std Y+1, r0
+       dec r27
+       brne 1b
+       st Y, r26
+*/
+4:     
+       pop r29
+       pop r28
+       pop_range 10, 17
+       ret
+
+/******************************************************************************/
+/*
+keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
+       keypair_t ret;
+       if (curround>15){
+               / * ERROR * /
+               ret.k0 = ret.k1 = 0;
+       } else {
+               if (curround & 1){
+                       / * odd round (1,3,5, ..., 15) * /
+                       ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
+               } else {
+                       / * even round (0,2,4, ..., 14) * /
+                       ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
+               }
+       / *     ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
+               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
+               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
+               ret.k0 = seed_g_function(ret.k0);
+               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
+               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = seed_g_function(ret.k1);
+               }
+       return ret;
+}
+*/
+/*
+ * param keystate: r24:r25
+ * param curround: r22
+ */
+
+seed_getprevkeys:
+       push_range 10, 17
+       push r28
+       push r29
+       movw r28, r24   
+;      andi r22, 0x0F
+       bst r22, 0
+       brts r_odd_round
+r_even_round:
+       ldd r26, Y+0
+       ldd r0, Y+1
+       std Y+0, r0
+       ldd r0, Y+2
+       std Y+1, r0
+       ldd r0, Y+3
+       std Y+2, r0
+       ldd r0, Y+4
+       std Y+3, r0
+       ldd r0, Y+5
+       std Y+4, r0
+       ldd r0, Y+6
+       std Y+5, r0
+       ldd r0, Y+7
+       std Y+6, r0
+       std Y+7, r26    
+/*
+       movw r30, r28
+       ld r26, Z+
+       ldi r27, 7
+1:
+       ld r0, Z+
+       st Y+, r0
+       dec r27
+       brne 1b
+       st Y, r26
+*/     
+
+       rjmp 4f
+r_odd_round:
+       ldd r26, Y+8+7
+       ldd r0, Y+8+6
+       std Y+8+7, r0
+       ldd r0, Y+8+5
+       std Y+8+6, r0
+       ldd r0, Y+8+4
+       std Y+8+5, r0
+       ldd r0, Y+8+3
+       std Y+8+4, r0
+       ldd r0, Y+8+2
+       std Y+8+3, r0
+       ldd r0, Y+8+1
+       std Y+8+2, r0
+       ldd r0, Y+8+0
+       std Y+8+1, r0
+       std Y+8+0, r26
+/*
+       adiw r28, 7     
+       ld r26, Y
+       ldi r27, 7      
+1:
+       ld r0, -Y
+       std Y+1, r0
+       dec r27
+       brne 1b
+       st Y, r26
+*/
+4:
+       rcall compute_keys      
+
+       pop r29
+       pop r28
+       pop_range 10, 17
+       ret
+
+/******************************************************************************/
+
+seed_kc:
+.long   0xb979379e 
+.long   0x73f36e3c
+.long   0xe6e6dd78 
+.long   0xcccdbbf1 
+.long   0x999b77e3 
+.long   0x3337efc6 
+.long   0x676ede8d 
+.long   0xcfdcbc1b 
+.long   0x9eb97937
+.long   0x3c73f36e     
+.long   0x78e6e6dd
+.long   0xf1cccdbb
+.long   0xe3999b77
+.long   0xc63337ef
+.long   0x8d676ede
+.long   0x1bcfdcbc
+
+/******************************************************************************/
+/*
+#define L (((uint64_t*)buffer)[0])
+#define R (((uint64_t*)buffer)[1])
+
+void seed_enc(void * buffer, seed_ctx_t * ctx){
+       uint8_t r;
+       keypair_t k;
+       for(r=0; r<8; ++r){
+                       k = seed_getnextkeys(ctx->k, 2*r);
+/ *
+       DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L:   "); uart_hexdump((uint8_t*)buffer+0, 8);
+       DEBUG_S("\r\n\t DBG R:   "); uart_hexdump((uint8_t*)buffer+8, 8);
+* /
+                       L ^= seed_f_function(&R,k.k0,k.k1);
+                       
+                       k = seed_getnextkeys(ctx->k, 2*r+1);
+/ *
+       DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L:   "); uart_hexdump((uint8_t*)buffer+8, 8);
+       DEBUG_S("\r\n\t DBG R:   "); uart_hexdump((uint8_t*)buffer+0, 8);
+* /
+                       R ^= seed_f_function(&L,k.k0,k.k1);
+       }
+       / * just an exchange without temp. variable * /
+       L ^= R;
+       R ^= L;
+       L ^= R;
+}
+*/
+/*
+ * param buffer: r24:r25
+ * param ctx:    r22:r23
+ */
+CTR  = 9
+xLPTR = 10
+xRPTR = 12
+CPTR = 14
+
+.global seed_enc
+seed_enc:
+       push_range 9, 17
+       push r28
+       push r29        
+       clr CTR
+       movw xLPTR, r24
+       adiw r24, 8
+       movw xRPTR, r24         
+       movw CPTR, r22
+1:
+       movw r28, xLPTR
+       movw r24, CPTR
+       mov r22, CTR
+       lsl r22
+       rcall seed_getnextkeys  
+
+       /* use pen & paper to understand the following permutation */
+       movw r16, r22
+       movw r22, r18
+       movw r18, r24
+       movw r24, r20
+       movw r20, r22
+       movw r22, r24
+       movw r24, xRPTR 
+
+       rcall seed_f_function
+
+       ld r0, Y
+       eor r0, r18
+       st Y+, r0
+       ld r0, Y
+       eor r0, r19
+       st Y+, r0
+       ld r0, Y
+       eor r0, r20
+       st Y+, r0
+       ld r0, Y
+       eor r0, r21
+       st Y+, r0
+       ld r0, Y
+       eor r0, r22
+       st Y+, r0
+       ld r0, Y
+       eor r0, r23
+       st Y+, r0
+       ld r0, Y
+       eor r0, r24
+       st Y+, r0
+       ld r0, Y
+       eor r0, r25
+       st Y+, r0
+       /* secound half */
+       movw r24, CPTR
+       mov r22, CTR
+       lsl r22
+       inc r22
+       rcall seed_getnextkeys  
+
+       movw r16, r22
+       movw r22, r18
+       movw r18, r24
+       movw r24, r20
+       movw r20, r22
+       movw r22, r24
+       movw r24, xLPTR 
+       
+       rcall seed_f_function
+
+       ld r0, Y
+       eor r0, r18
+       st Y+, r0
+       ld r0, Y
+       eor r0, r19
+       st Y+, r0
+       ld r0, Y
+       eor r0, r20
+       st Y+, r0
+       ld r0, Y
+       eor r0, r21
+       st Y+, r0
+       ld r0, Y
+       eor r0, r22
+       st Y+, r0
+       ld r0, Y
+       eor r0, r23
+       st Y+, r0
+       ld r0, Y
+       eor r0, r24
+       st Y+, r0
+       ld r0, Y
+       eor r0, r25
+       st Y+, r0
+       
+       inc CTR
+       bst CTR, 3
+       brts 3f
+       rjmp 1b
+3:
+       movw r28, xLPTR
+       movw r30, xRPTR
+       ldi r17, 8
+4:
+       ld r10, Y
+       ld r11, Z
+       st Z+, r10
+       st Y+, r11
+       dec r17
+       brne 4b
+5:
+       pop r29
+       pop r28
+       pop_range 9, 17
+       ret
+
+/******************************************************************************/
+/*
+#define L (((uint64_t*)buffer)[0])
+#define R (((uint64_t*)buffer)[1])
+
+void seed_dec(void * buffer, seed_ctx_t * ctx){
+       int8_t r;
+       keypair_t k;
+       for(r=7; r>=0; --r){
+                       k = seed_getprevkeys(ctx->k, 2*r+1);
+/ *
+       DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
+       DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
+* /
+                       L ^= seed_f_function(&R,k.k0,k.k1);
+                       
+                       k = seed_getprevkeys(ctx->k, 2*r+0);
+/ *
+       DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
+       DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
+* /
+                       R ^= seed_f_function(&L,k.k0,k.k1);
+       }
+       / * just an exchange without temp. variable * /
+       L ^= R;
+       R ^= L;
+       L ^= R;
+}
+*/
+/*
+ * param buffer: r24:r25
+ * param ctx:    r22:r23
+ */
+CTR  = 9
+xLPTR = 10
+xRPTR = 12
+CPTR = 14
+
+.global seed_dec
+seed_dec:
+       push_range 9, 17
+       push r28
+       push r29        
+       ldi r16, 7
+       mov CTR, r16
+       movw xLPTR, r24
+       adiw r24, 8
+       movw xRPTR, r24         
+       movw CPTR, r22
+1:
+       movw r28, xLPTR
+       movw r24, CPTR
+       mov r22, CTR
+       lsl r22
+       inc r22
+       rcall seed_getprevkeys  
+
+       /* use pen & paper to understand the following permutation */
+       movw r16, r22
+       movw r22, r18
+       movw r18, r24
+       movw r24, r20
+       movw r20, r22
+       movw r22, r24
+       movw r24, xRPTR 
+
+       rcall seed_f_function
+
+       ld r0, Y
+       eor r0, r18
+       st Y+, r0
+       ld r0, Y
+       eor r0, r19
+       st Y+, r0
+       ld r0, Y
+       eor r0, r20
+       st Y+, r0
+       ld r0, Y
+       eor r0, r21
+       st Y+, r0
+       ld r0, Y
+       eor r0, r22
+       st Y+, r0
+       ld r0, Y
+       eor r0, r23
+       st Y+, r0
+       ld r0, Y
+       eor r0, r24
+       st Y+, r0
+       ld r0, Y
+       eor r0, r25
+       st Y+, r0
+       /* secound half */
+       movw r24, CPTR
+       mov r22, CTR
+       lsl r22
+       rcall seed_getprevkeys  
+
+       movw r16, r22
+       movw r22, r18
+       movw r18, r24
+       movw r24, r20
+       movw r20, r22
+       movw r22, r24
+       movw r24, xLPTR 
+       
+       rcall seed_f_function
+
+       ld r0, Y
+       eor r0, r18
+       st Y+, r0
+       ld r0, Y
+       eor r0, r19
+       st Y+, r0
+       ld r0, Y
+       eor r0, r20
+       st Y+, r0
+       ld r0, Y
+       eor r0, r21
+       st Y+, r0
+       ld r0, Y
+       eor r0, r22
+       st Y+, r0
+       ld r0, Y
+       eor r0, r23
+       st Y+, r0
+       ld r0, Y
+       eor r0, r24
+       st Y+, r0
+       ld r0, Y
+       eor r0, r25
+       st Y+, r0
+       
+       dec CTR
+       brmi 3f
+       rjmp 1b
+3:
+       movw r28, xLPTR
+       movw r30, xRPTR
+       ldi r17, 8
+4:
+       ld r10, Y
+       ld r11, Z
+       st Z+, r10
+       st Y+, r11
+       dec r17
+       brne 4b
+5:
+       pop r29
+       pop r28
+       pop_range 9, 17
+       ret
+
diff --git a/seed/seed.h b/seed/seed.h
new file mode 100644 (file)
index 0000000..78d7d59
--- /dev/null
@@ -0,0 +1,81 @@
+/* seed.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       seed.h
+ * \author     Daniel Otte 
+ * \date       2007-06-1
+ * \brief      declarations for seed
+ * \par License        
+ * GPL
+ * 
+ */
+#ifndef SEED_H_
+#define SEED_H_
+
+#include <stdint.h>
+/** \typedef seed_ctx_t
+ * \brief SEED context
+ * 
+ * A variable of this type may hold the key material for the SEED cipher. 
+ * This context is regulary generated by the 
+ * void seed_init(const void * key, seed_ctx_t * ctx) function.
+ */
+typedef struct{
+       uint32_t k[4];
+} seed_ctx_t;
+
+/******************************************************************************/
+
+/** \fn void seed_init(const void * key, seed_ctx_t * ctx)
+ * \brief initializes context for SEED operation
+ * 
+ * This function copys the key material into a context variable.
+ * 
+ * \param key  pointer to the key material (128 bit = 16 bytes)
+ * \param ctx  pointer to the context (seed_ctx_t)
+ */
+void seed_init(const void * key, seed_ctx_t * ctx);
+
+/** \fn void seed_enc(void * buffer,const seed_ctx_t * ctx)
+ * \brief encrypt a block with SEED
+ * 
+ * This function encrypts a block of 64 bits (8 bytes) with the SEED algorithm.
+ * The round keys are computed on demand, so the context is modifyed while
+ * encrypting but the original stated is restored when the function exits.
+ * 
+ * \param buffer pointer to the block (64 bit = 8 byte) which will be encrypted
+ * \param ctx    pointer to the key material (seed_ctx_t)
+ */
+void seed_enc(void * buffer, const seed_ctx_t * ctx);
+
+
+/** \fn void seed_dec(void * buffer, const seed_ctx_t * ctx)
+ * \brief decrypt a block with SEED
+ * 
+ * This function decrypts a block of 64 bits (8 bytes) with the SEED algorithm.
+ * The round keys are computed on demand, so the context is modifyed while
+ * decrypting but the original stated is restored when the function exits.
+ * 
+ * \param buffer pointer to the block (64 bit = 8 byte) which will be decrypted
+ * \param ctx    pointer to the key material (seed_ctx_t)
+ */
+void seed_dec(void * buffer, const seed_ctx_t * ctx);
+
+       
+#endif /*SEED_H_*/
diff --git a/seed/seed_C.c b/seed/seed_C.c
new file mode 100644 (file)
index 0000000..7a9afc0
--- /dev/null
@@ -0,0 +1,288 @@
+/* seed_C.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+ /**
+ * \file       seed_C.c
+ * \author     Daniel Otte 
+ * \date       2007-06-1
+ * \brief      SEED parts in C for AVR
+ * \par License        
+ * GPL
+ * 
+ */
+#include <stdint.h>
+#include <avr/pgmspace.h>
+#include <string.h>
+#include "seed_sbox.h"
+#include "cli.h"
+#include "debug.h"
+
+
+static
+uint32_t g_function(uint32_t x);
+/******************************************************************************/
+
+static
+void changeendian32(uint32_t * a){
+       *a = (*a & 0x000000FF) << 24 |
+                (*a & 0x0000FF00) <<  8 |
+                (*a & 0x00FF0000) >>  8 |
+                (*a & 0xFF000000) >> 24;
+}
+
+/******************************************************************************/
+static
+uint32_t bigendian_sum32(uint32_t a, uint32_t b){
+       changeendian32(&a);
+       changeendian32(&b);
+       a += b;
+       changeendian32(&a);
+       return a;
+}
+
+/******************************************************************************/
+static 
+uint32_t bigendian_sub32(uint32_t a, uint32_t b){
+       changeendian32(&a);
+       changeendian32(&b);
+       a -= b;
+       changeendian32(&a);
+       return a;
+}
+
+/******************************************************************************/
+static inline
+uint64_t bigendian_rotl8_64(uint64_t a){
+       /*
+       changeendian64(&a);
+       a = (a<<8) | (a>>(64-8));
+       changeendian64(&a);
+       */
+       a = (a>>8) | (a<<(64-8));
+       return a;
+}
+
+/******************************************************************************/
+static inline
+uint64_t bigendian_rotr8_64(uint64_t a){
+       /*
+       changeendian64(&a);
+       a = (a>>8) | (a<<(64-8));
+       changeendian64(&a);
+       */
+       a = (a<<8) | (a>>(64-8));
+       return a;
+}
+
+/******************************************************************************/
+static
+uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
+       uint32_t c,d;
+
+       c = *a & 0x00000000FFFFFFFFLL;
+       d = (*a>>32) & 0x00000000FFFFFFFFLL;
+       
+       c ^= k0; d ^= k1;
+       d ^= c;
+       d = g_function(d);
+       c = bigendian_sum32(c,d);
+       c = g_function(c);
+       d = bigendian_sum32(c,d);
+       d = g_function(d);
+       c = bigendian_sum32(c,d);
+       return ((uint64_t)d << 32) | c;
+}
+
+/******************************************************************************/
+#define M0 0xfc
+#define M1 0xf3
+#define M2 0xcf
+#define M3 0x3f
+
+#define X3 (((uint8_t*)(&x))[0])
+#define X2 (((uint8_t*)(&x))[1])
+#define X1 (((uint8_t*)(&x))[2])
+#define X0 (((uint8_t*)(&x))[3])
+
+#define Z3 (((uint8_t*)(&z))[0])
+#define Z2 (((uint8_t*)(&z))[1])
+#define Z1 (((uint8_t*)(&z))[2])
+#define Z0 (((uint8_t*)(&z))[3])
+
+static
+uint32_t g_function(uint32_t x){
+       uint32_t z;
+       /* sbox substitution */
+       X3 = pgm_read_byte(&(seed_sbox2[X3]));
+       X2 = pgm_read_byte(&(seed_sbox1[X2]));
+       X1 = pgm_read_byte(&(seed_sbox2[X1]));
+       X0 = pgm_read_byte(&(seed_sbox1[X0]));
+       /* now the permutation */
+       Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
+       Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
+       Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
+       Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
+       return z;
+}
+/******************************************************************************/
+typedef struct {
+       uint32_t k0, k1;
+} keypair_t;
+
+keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
+       keypair_t ret;
+       if (curround>15){
+               /* ERROR */
+               ret.k0 = ret.k1 = 0;
+       } else {
+       /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
+               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
+               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
+               ret.k0 = g_function(ret.k0);
+               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
+               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = g_function(ret.k1);
+               
+               if (curround & 1){
+                       /* odd round (1,3,5, ...) */
+                       ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
+               } else {
+                       /* even round (0,2,4, ...) */
+                       ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
+               }
+       }
+       return ret;
+}
+
+
+/******************************************************************************/
+
+keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
+       keypair_t ret;
+       if (curround>15){
+               /* ERROR */
+               ret.k0 = ret.k1 = 0;
+       } else {
+               if (curround & 1){
+                       /* odd round (1,3,5, ..., 15) */
+                       ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
+               } else {
+                       /* even round (0,2,4, ..., 14) */
+                       ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
+               }
+       /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
+               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
+               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
+               ret.k0 = g_function(ret.k0);
+               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
+               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
+               ret.k1 = g_function(ret.k1);
+               }
+       return ret;
+}
+
+/******************************************************************************/
+
+typedef struct{
+       uint32_t k[4];
+} seed_ctx_t;
+
+/******************************************************************************/
+
+void seed_init(const void * key, seed_ctx_t * ctx){
+       memcpy(ctx->k, key, 128/8);
+}
+
+/******************************************************************************/
+
+#define L (((uint64_t*)buffer)[0])
+#define R (((uint64_t*)buffer)[1])
+
+void seed_enc(void * buffer, const seed_ctx_t * ctx){
+       uint8_t r;
+       keypair_t k;
+       for(r=0; r<8; ++r){
+                       k = getnextkeys(((seed_ctx_t*)ctx)->k, 2*r);
+/*
+       DEBUG_S("\r\n\tDBG ka,0: "); cli_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG ka,1: "); cli_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+0, 8);
+       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+8, 8);
+*/
+                       L ^= f_function(&R,k.k0,k.k1);
+                       
+                       k = getnextkeys(((seed_ctx_t*)ctx)->k, 2*r+1);
+/*
+       DEBUG_S("\r\n\tDBG kb,0: "); cli_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG kb,1: "); cli_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+8, 8);
+       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+0, 8);
+*/
+                       R ^= f_function(&L,k.k0,k.k1);
+       }
+       /* just an exchange without temp. variable */
+       L ^= R;
+       R ^= L;
+       L ^= R;
+}
+
+/******************************************************************************/
+
+#define L (((uint64_t*)buffer)[0])
+#define R (((uint64_t*)buffer)[1])
+
+void seed_dec(void * buffer, seed_ctx_t * ctx){
+       int8_t r;
+       keypair_t k;
+       for(r=7; r>=0; --r){
+                       k = getprevkeys(((seed_ctx_t*)ctx)->k, 2*r+1);
+/*
+       DEBUG_S("\r\n\tDBG ka,0: "); cli_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG ka,1: "); cli_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+0, 8);
+       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+8, 8);
+*/
+                       L ^= f_function(&R,k.k0,k.k1);
+                       
+                       k = getprevkeys(((seed_ctx_t*)ctx)->k, 2*r+0);
+/*
+       DEBUG_S("\r\n\tDBG kb,0: "); cli_hexdump(&k.k0, 4);
+       DEBUG_S("\r\n\tDBG kb,1: "); cli_hexdump(&k.k1, 4);
+       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+8, 8);
+       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+0, 8);
+*/
+                       R ^= f_function(&L,k.k0,k.k1);
+       }
+       /* just an exchange without temp. variable */
+       L ^= R;
+       R ^= L;
+       L ^= R;
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/seed/seed_sbox.h b/seed/seed_sbox.h
new file mode 100644 (file)
index 0000000..9937913
--- /dev/null
@@ -0,0 +1,125 @@
+/* seed_sbox.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       seed_sbox.h
+ * \author     Daniel Otte 
+ * \date       2007-06-1
+ * \brief      sboxes and constants for seed
+ * \par License        
+ * GPL
+ * 
+ */
+#ifndef SEED_SBOX_H_
+#define SEED_SBOX_H_
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+uint8_t seed_sbox1[256] PROGMEM ={
+       169,  133,  214,  211,   84,   29,  172,   37, 
+        93,   67,   24,   30,   81,  252,  202,   99, 
+        40,   68,   32,  157,  224,  226,  200,   23, 
+       165,  143,    3,  123,  187,   19,  210,  238, 
+       112,  140,   63,  168,   50,  221,  246,  116, 
+       236,  149,   11,   87,   92,   91,  189,    1, 
+        36,   28,  115,  152,   16,  204,  242,  217, 
+        44,   231, 114,  131,  155,  209,  134,  201, 
+        96,   80,  163,  235,   13,  182,  158,   79, 
+       183,   90,  198,  120,  166,   18,  175,  213, 
+        97,  195,  180,   65,   82,  125,  141,    8, 
+        31,  153,    0,   25,    4,   83,  247,  225, 
+       253,  118,   47,   39,  176,  139,   14,  171, 
+       162,  110,  147,   77,  105,  124,    9,   10, 
+       191,  239,  243,  197,  135,   20,  254,  100, 
+       222,   46,   75,   26,    6,   33,  107,  102, 
+         2,  245,  146,  138,   12,  179,  126,  208, 
+       122,   71,  150,  229,   38,  128,  173,  223, 
+       161,   48,   55,  174,   54,   21,   34,   56, 
+       244,  167,   69,   76,  129,  233,  132,  151, 
+        53,  203,  206,   60,  113,   17,  199,  137, 
+       117,  251,  218,  248,  148,   89,  130,  196, 
+       255,   73,   57,  103,  192,  207,  215,  184, 
+        15,  142,   66,   35,  145,  108,  219,  164, 
+        52,  241,   72,  194,  111,   61,   45,   64, 
+       190,   62,  188,  193,  170,  186,   78,   85, 
+        59,  220,  104,  127,  156,  216,   74,   86, 
+       119,  160,  237,   70,  181,   43,  101,  250, 
+       227,  185,  177,  159,   94,  249,  230,  178, 
+        49,  234,  109,   95,  228,  240,  205,  136, 
+        22,   58,   88,  212,   98,   41,    7,   51, 
+       232,   27,    5,  121,  144,  106,   42,  154
+};
+
+uint8_t seed_sbox2[256] PROGMEM ={
+        56,  232,   45,  166,  207,  222,  179,  184, 
+       175,   96,   85,  199,   68,  111,  107,   91, 
+       195,   98,   51,  181,   41,  160,  226,  167, 
+       211,  145,   17,    6,   28,  188,   54,   75, 
+       239,  136,  108,  168,   23,  196,   22,  244, 
+       194,   69,  225,  214,   63,   61,  142,  152, 
+        40,   78,  246,   62,  165,  249,   13,  223, 
+       216,   43,  102,  122,   39,   47,  241,  114, 
+        66,  212,   65,  192,  115,  103,  172,  139, 
+       247,  173,  128,   31,  202,   44,  170,   52, 
+       210,   11,  238,  233,   93,  148,   24,  248, 
+        87,  174,    8,  197,   19,  205,  134,  185, 
+       255,  125,  193,   49,  245,  138,  106,  177, 
+       209,   32,  215,    2,   34,    4,  104,  113, 
+         7,  219,  157,  153,   97,  190,  230,   89, 
+       221,   81,  144,  220,  154,  163,  171,  208, 
+       129,   15,   71,   26,  227,  236,  141,  191, 
+       150,  123,   92,  162,  161,   99,   35,   77, 
+       200,  158,  156,   58,   12,   46,  186,  110, 
+       159,   90,  242,  146,  243,   73,  120,  204, 
+        21,  251,  112,  117,  127,   53,   16,    3, 
+       100,  109,  198,  116,  213,  180,  234,    9, 
+       118,   25,  254,   64,   18,  224,  189,    5, 
+       250,    1,  240,   42,   94,  169,   86,   67, 
+       133,   20,  137,  155,  176,  229,   72,  121, 
+       151,  252,   30,  130,   33,  140,   27,   95, 
+       119,   84,  178,   29,   37,   79,    0,   70, 
+       237,   88,   82,  235,  126,  218,  201,  253, 
+        48,  149,  101,   60,  182,  228,  187,  124, 
+        14,   80,   57,   38,   50,  132,  105,  147, 
+        55,  231,   36,  164,  203,   83,   10,  135, 
+       217,   76,  131,  143,  206,   59,   74,  183 
+};
+
+/* key constants */
+uint32_t seed_kc[16] PROGMEM ={
+       0xb979379e, 
+       0x73f36e3c,
+       0xe6e6dd78, 
+       0xcccdbbf1, 
+       0x999b77e3, 
+       0x3337efc6, 
+       0x676ede8d, 
+       0xcfdcbc1b, 
+       0x9eb97937,
+       0x3c73f36e,     
+       0x78e6e6dd,
+       0xf1cccdbb,
+       0xe3999b77,
+       0xc63337ef,
+       0x8d676ede,
+       0x1bcfdcbc
+};
+
+#endif /*SEED_SBOX_H_*/
diff --git a/seed_C.c b/seed_C.c
deleted file mode 100644 (file)
index 7a9afc0..0000000
--- a/seed_C.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* seed_C.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
- /**
- * \file       seed_C.c
- * \author     Daniel Otte 
- * \date       2007-06-1
- * \brief      SEED parts in C for AVR
- * \par License        
- * GPL
- * 
- */
-#include <stdint.h>
-#include <avr/pgmspace.h>
-#include <string.h>
-#include "seed_sbox.h"
-#include "cli.h"
-#include "debug.h"
-
-
-static
-uint32_t g_function(uint32_t x);
-/******************************************************************************/
-
-static
-void changeendian32(uint32_t * a){
-       *a = (*a & 0x000000FF) << 24 |
-                (*a & 0x0000FF00) <<  8 |
-                (*a & 0x00FF0000) >>  8 |
-                (*a & 0xFF000000) >> 24;
-}
-
-/******************************************************************************/
-static
-uint32_t bigendian_sum32(uint32_t a, uint32_t b){
-       changeendian32(&a);
-       changeendian32(&b);
-       a += b;
-       changeendian32(&a);
-       return a;
-}
-
-/******************************************************************************/
-static 
-uint32_t bigendian_sub32(uint32_t a, uint32_t b){
-       changeendian32(&a);
-       changeendian32(&b);
-       a -= b;
-       changeendian32(&a);
-       return a;
-}
-
-/******************************************************************************/
-static inline
-uint64_t bigendian_rotl8_64(uint64_t a){
-       /*
-       changeendian64(&a);
-       a = (a<<8) | (a>>(64-8));
-       changeendian64(&a);
-       */
-       a = (a>>8) | (a<<(64-8));
-       return a;
-}
-
-/******************************************************************************/
-static inline
-uint64_t bigendian_rotr8_64(uint64_t a){
-       /*
-       changeendian64(&a);
-       a = (a>>8) | (a<<(64-8));
-       changeendian64(&a);
-       */
-       a = (a<<8) | (a>>(64-8));
-       return a;
-}
-
-/******************************************************************************/
-static
-uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
-       uint32_t c,d;
-
-       c = *a & 0x00000000FFFFFFFFLL;
-       d = (*a>>32) & 0x00000000FFFFFFFFLL;
-       
-       c ^= k0; d ^= k1;
-       d ^= c;
-       d = g_function(d);
-       c = bigendian_sum32(c,d);
-       c = g_function(c);
-       d = bigendian_sum32(c,d);
-       d = g_function(d);
-       c = bigendian_sum32(c,d);
-       return ((uint64_t)d << 32) | c;
-}
-
-/******************************************************************************/
-#define M0 0xfc
-#define M1 0xf3
-#define M2 0xcf
-#define M3 0x3f
-
-#define X3 (((uint8_t*)(&x))[0])
-#define X2 (((uint8_t*)(&x))[1])
-#define X1 (((uint8_t*)(&x))[2])
-#define X0 (((uint8_t*)(&x))[3])
-
-#define Z3 (((uint8_t*)(&z))[0])
-#define Z2 (((uint8_t*)(&z))[1])
-#define Z1 (((uint8_t*)(&z))[2])
-#define Z0 (((uint8_t*)(&z))[3])
-
-static
-uint32_t g_function(uint32_t x){
-       uint32_t z;
-       /* sbox substitution */
-       X3 = pgm_read_byte(&(seed_sbox2[X3]));
-       X2 = pgm_read_byte(&(seed_sbox1[X2]));
-       X1 = pgm_read_byte(&(seed_sbox2[X1]));
-       X0 = pgm_read_byte(&(seed_sbox1[X0]));
-       /* now the permutation */
-       Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
-       Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
-       Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
-       Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
-       return z;
-}
-/******************************************************************************/
-typedef struct {
-       uint32_t k0, k1;
-} keypair_t;
-
-keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
-       keypair_t ret;
-       if (curround>15){
-               /* ERROR */
-               ret.k0 = ret.k1 = 0;
-       } else {
-       /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
-               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
-               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
-               ret.k0 = g_function(ret.k0);
-               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
-               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = g_function(ret.k1);
-               
-               if (curround & 1){
-                       /* odd round (1,3,5, ...) */
-                       ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
-               } else {
-                       /* even round (0,2,4, ...) */
-                       ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
-               }
-       }
-       return ret;
-}
-
-
-/******************************************************************************/
-
-keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
-       keypair_t ret;
-       if (curround>15){
-               /* ERROR */
-               ret.k0 = ret.k1 = 0;
-       } else {
-               if (curround & 1){
-                       /* odd round (1,3,5, ..., 15) */
-                       ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
-               } else {
-                       /* even round (0,2,4, ..., 14) */
-                       ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
-               }
-       /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
-               ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
-               ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
-               ret.k0 = g_function(ret.k0);
-               ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
-               ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
-               ret.k1 = g_function(ret.k1);
-               }
-       return ret;
-}
-
-/******************************************************************************/
-
-typedef struct{
-       uint32_t k[4];
-} seed_ctx_t;
-
-/******************************************************************************/
-
-void seed_init(const void * key, seed_ctx_t * ctx){
-       memcpy(ctx->k, key, 128/8);
-}
-
-/******************************************************************************/
-
-#define L (((uint64_t*)buffer)[0])
-#define R (((uint64_t*)buffer)[1])
-
-void seed_enc(void * buffer, const seed_ctx_t * ctx){
-       uint8_t r;
-       keypair_t k;
-       for(r=0; r<8; ++r){
-                       k = getnextkeys(((seed_ctx_t*)ctx)->k, 2*r);
-/*
-       DEBUG_S("\r\n\tDBG ka,0: "); cli_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG ka,1: "); cli_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+0, 8);
-       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+8, 8);
-*/
-                       L ^= f_function(&R,k.k0,k.k1);
-                       
-                       k = getnextkeys(((seed_ctx_t*)ctx)->k, 2*r+1);
-/*
-       DEBUG_S("\r\n\tDBG kb,0: "); cli_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG kb,1: "); cli_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+8, 8);
-       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+0, 8);
-*/
-                       R ^= f_function(&L,k.k0,k.k1);
-       }
-       /* just an exchange without temp. variable */
-       L ^= R;
-       R ^= L;
-       L ^= R;
-}
-
-/******************************************************************************/
-
-#define L (((uint64_t*)buffer)[0])
-#define R (((uint64_t*)buffer)[1])
-
-void seed_dec(void * buffer, seed_ctx_t * ctx){
-       int8_t r;
-       keypair_t k;
-       for(r=7; r>=0; --r){
-                       k = getprevkeys(((seed_ctx_t*)ctx)->k, 2*r+1);
-/*
-       DEBUG_S("\r\n\tDBG ka,0: "); cli_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG ka,1: "); cli_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+0, 8);
-       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+8, 8);
-*/
-                       L ^= f_function(&R,k.k0,k.k1);
-                       
-                       k = getprevkeys(((seed_ctx_t*)ctx)->k, 2*r+0);
-/*
-       DEBUG_S("\r\n\tDBG kb,0: "); cli_hexdump(&k.k0, 4);
-       DEBUG_S("\r\n\tDBG kb,1: "); cli_hexdump(&k.k1, 4);
-       DEBUG_S("\r\n\t DBG L: "); cli_hexdump((uint8_t*)buffer+8, 8);
-       DEBUG_S("\r\n\t DBG R: "); cli_hexdump((uint8_t*)buffer+0, 8);
-*/
-                       R ^= f_function(&L,k.k0,k.k1);
-       }
-       /* just an exchange without temp. variable */
-       L ^= R;
-       R ^= L;
-       L ^= R;
-}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/seed_sbox.h b/seed_sbox.h
deleted file mode 100644 (file)
index 9937913..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* seed_sbox.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       seed_sbox.h
- * \author     Daniel Otte 
- * \date       2007-06-1
- * \brief      sboxes and constants for seed
- * \par License        
- * GPL
- * 
- */
-#ifndef SEED_SBOX_H_
-#define SEED_SBOX_H_
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-
-uint8_t seed_sbox1[256] PROGMEM ={
-       169,  133,  214,  211,   84,   29,  172,   37, 
-        93,   67,   24,   30,   81,  252,  202,   99, 
-        40,   68,   32,  157,  224,  226,  200,   23, 
-       165,  143,    3,  123,  187,   19,  210,  238, 
-       112,  140,   63,  168,   50,  221,  246,  116, 
-       236,  149,   11,   87,   92,   91,  189,    1, 
-        36,   28,  115,  152,   16,  204,  242,  217, 
-        44,   231, 114,  131,  155,  209,  134,  201, 
-        96,   80,  163,  235,   13,  182,  158,   79, 
-       183,   90,  198,  120,  166,   18,  175,  213, 
-        97,  195,  180,   65,   82,  125,  141,    8, 
-        31,  153,    0,   25,    4,   83,  247,  225, 
-       253,  118,   47,   39,  176,  139,   14,  171, 
-       162,  110,  147,   77,  105,  124,    9,   10, 
-       191,  239,  243,  197,  135,   20,  254,  100, 
-       222,   46,   75,   26,    6,   33,  107,  102, 
-         2,  245,  146,  138,   12,  179,  126,  208, 
-       122,   71,  150,  229,   38,  128,  173,  223, 
-       161,   48,   55,  174,   54,   21,   34,   56, 
-       244,  167,   69,   76,  129,  233,  132,  151, 
-        53,  203,  206,   60,  113,   17,  199,  137, 
-       117,  251,  218,  248,  148,   89,  130,  196, 
-       255,   73,   57,  103,  192,  207,  215,  184, 
-        15,  142,   66,   35,  145,  108,  219,  164, 
-        52,  241,   72,  194,  111,   61,   45,   64, 
-       190,   62,  188,  193,  170,  186,   78,   85, 
-        59,  220,  104,  127,  156,  216,   74,   86, 
-       119,  160,  237,   70,  181,   43,  101,  250, 
-       227,  185,  177,  159,   94,  249,  230,  178, 
-        49,  234,  109,   95,  228,  240,  205,  136, 
-        22,   58,   88,  212,   98,   41,    7,   51, 
-       232,   27,    5,  121,  144,  106,   42,  154
-};
-
-uint8_t seed_sbox2[256] PROGMEM ={
-        56,  232,   45,  166,  207,  222,  179,  184, 
-       175,   96,   85,  199,   68,  111,  107,   91, 
-       195,   98,   51,  181,   41,  160,  226,  167, 
-       211,  145,   17,    6,   28,  188,   54,   75, 
-       239,  136,  108,  168,   23,  196,   22,  244, 
-       194,   69,  225,  214,   63,   61,  142,  152, 
-        40,   78,  246,   62,  165,  249,   13,  223, 
-       216,   43,  102,  122,   39,   47,  241,  114, 
-        66,  212,   65,  192,  115,  103,  172,  139, 
-       247,  173,  128,   31,  202,   44,  170,   52, 
-       210,   11,  238,  233,   93,  148,   24,  248, 
-        87,  174,    8,  197,   19,  205,  134,  185, 
-       255,  125,  193,   49,  245,  138,  106,  177, 
-       209,   32,  215,    2,   34,    4,  104,  113, 
-         7,  219,  157,  153,   97,  190,  230,   89, 
-       221,   81,  144,  220,  154,  163,  171,  208, 
-       129,   15,   71,   26,  227,  236,  141,  191, 
-       150,  123,   92,  162,  161,   99,   35,   77, 
-       200,  158,  156,   58,   12,   46,  186,  110, 
-       159,   90,  242,  146,  243,   73,  120,  204, 
-        21,  251,  112,  117,  127,   53,   16,    3, 
-       100,  109,  198,  116,  213,  180,  234,    9, 
-       118,   25,  254,   64,   18,  224,  189,    5, 
-       250,    1,  240,   42,   94,  169,   86,   67, 
-       133,   20,  137,  155,  176,  229,   72,  121, 
-       151,  252,   30,  130,   33,  140,   27,   95, 
-       119,   84,  178,   29,   37,   79,    0,   70, 
-       237,   88,   82,  235,  126,  218,  201,  253, 
-        48,  149,  101,   60,  182,  228,  187,  124, 
-        14,   80,   57,   38,   50,  132,  105,  147, 
-        55,  231,   36,  164,  203,   83,   10,  135, 
-       217,   76,  131,  143,  206,   59,   74,  183 
-};
-
-/* key constants */
-uint32_t seed_kc[16] PROGMEM ={
-       0xb979379e, 
-       0x73f36e3c,
-       0xe6e6dd78, 
-       0xcccdbbf1, 
-       0x999b77e3, 
-       0x3337efc6, 
-       0x676ede8d, 
-       0xcfdcbc1b, 
-       0x9eb97937,
-       0x3c73f36e,     
-       0x78e6e6dd,
-       0xf1cccdbb,
-       0xe3999b77,
-       0xc63337ef,
-       0x8d676ede,
-       0x1bcfdcbc
-};
-
-#endif /*SEED_SBOX_H_*/
diff --git a/serpent-asm.S b/serpent-asm.S
deleted file mode 100644 (file)
index f5f7cc5..0000000
+++ /dev/null
@@ -1,754 +0,0 @@
-/* serpent_asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* 
- * File:        serpent_sboxes.S
- * Author:      Daniel Otte
- * Date:        2008-08-07
- * License:     GPLv3 or later
- * Description: Implementation of the serpent sbox function.
- * 
- */
-#include <avr/io.h>
-#include "avr-asm-macros.S"
-
-/*
-static void serpent_lt(uint8_t *b){
-       X0 = rotl32(X0, 13);
-       X2 = rotl32(X2,  3);
-       X1 ^= X0 ^ X2;
-       X3 ^= X2 ^ (X0 << 3);
-       X1 = rotl32(X1, 1);
-       X3 = rotl32(X3, 7);
-       X0 ^= X1 ^ X3;
-       X2 ^= X3 ^ (X1 << 7);
-       X0 = rotl32(X0, 5);
-       X2 = rotr32(X2, 10);
-}
-*/
-
-#if 0
-A0 =  4
-A1 =  5
-A2 =  6
-A3 =  7
-B0 =  8
-B1 =  9
-B2 = 10
-B3 = 11
-C0 = 12
-C1 = 13
-C2 = 14
-C3 = 15
-D0 = 16
-D1 = 17
-D2 = 18
-D3 = 19
-T0 = 20
-T1 = 21
-T2 = 22
-T3 = 23
-
-serpent_lt:
-       push_range 4, 17
-       movw r26, r24
-       ld A2, X+
-       ld A3, X+
-       ld A0, X+
-       ld A1, X+
-       ldi r20, 3
-       mov r0, A0
-1:     
-       lsr r0
-       ror A3
-       ror A2
-       ror A1
-       ror A0
-       dec r20
-       brne 1b
-       ld B0, X+
-       ld B1, X+
-       ld B2, X+
-       ld B3, X+
-       
-       ld C2, X+
-       ld C3, X+
-       ld C0, X+
-       ld C1, X+
-       ldi r20, 3
-       mov r0, C0
-1:     
-       lsr r0
-       ror C3
-       ror C2
-       ror C1
-       ror C0
-       dec r20
-       brne 1b
-
-       ld D0, X+
-       ld D1, X+
-       ld D2, X+
-       ld D3, X+
-       /* X1 ^= X0 ^ X2; */
-       eor B0, A0
-       eor B0, C0
-       eor B1, A1
-       eor B1, C1
-       eor B2, A2
-       eor B2, C2
-       eor B3, A3
-       eor B3, C3
-       /* X3 ^= X2 ^ (X0 << 3); */
-       mov T0, A0
-       mov T1, A1
-       mov T2, A2
-       mov T3, A3
-       ldi r24, 3
-1:
-       lsl T0
-       rol T1
-       rol T2
-       rol T3
-       dec r24
-       brne 1b
-       eor C0, B0
-       eor C0, T0
-       eor C1, B1
-       eor C1, T1
-       eor C2, B2
-       eor C2, T2
-       eor C3, B3
-       eor C3, T3
-       /*      X1 = rotl32(X1, 1); */
-       mov r0, B3
-       lsl r0
-       rol B0
-       rol B1
-       rol B2
-       rol B3
-       /* X3 = rotl32(X3, 7); */
-       mov r0, D3
-       mov D3, D2
-       mov D2, D1
-       mov D1, D0
-       mov D0, r0
-       lsr r0
-       ror D3
-       ror D2
-       ror D1
-       ror D0
-       /*      X0 ^= X1 ^ X3; */
-       eor A0, B0
-       eor A0, D0
-       eor A1, B1
-       eor A1, D1
-       eor A2, B2
-       eor A2, D2
-       eor A3, B3
-       eor A3, D3
-       /*  X2 ^= X3 ^ (X1 << 7); */
-       mov T1, B0
-       mov T2, B1
-       mov T3, B2
-       clr T0
-       mov r0, B3
-       lsr r0
-       ror T2
-       ror T1
-       ror T0 
-       eor C0, D0
-       eor C0, T0
-       eor C1, D1
-       eor C1, T1
-       eor C2, D2
-       eor C2, T2
-       eor C3, D3
-       eor C3, T3
-       /*      X0 = rotl32(X0, 5); */
-       ldi r24, 5
-       mov r0, A3
-1:     
-       lsl r0
-       rol A0
-       rol A1
-       rol A2
-       rol A3
-       dec r24
-       brne 1b
-       /* X2 = rotr32(X2, 10); */
-       mov r0, C0
-       mov C0, C1
-       mov C1, C2
-       mov C2, C3      
-       mov C3, r0
-       ldi r24, 2
-1:
-       lsr r0
-       ror C2
-       ror C1
-       ror C0
-       ror C3  
-       dec r24
-       brne 1b
-       
-       clr r31
-       ldi r30, D3+1
-       ldi r24, 16
-1:
-       ld r0, -Z
-       st -X, r0       
-       dec r24
-       brne 1b
-       
-       pop_range 4, 17
-       ret
-#endif
-
-T0 = 22
-T1 = 23
-T2 = 24
-T3 = 25
-TT = 21
-/* rotate the data word (4 byte) pointed to by X by r20 bits to the right */
-memrotr32:
-       ld T0, X+
-       ld T1, X+
-       ld T2, X+
-       ld T3, X+
-       mov TT, T0
-1:
-       lsr TT
-       ror T3
-       ror T2
-       ror T1
-       ror T0
-       dec r20
-       brne 1b
-       st -X, T3
-       st -X, T2
-       st -X, T1
-       st -X, T0
-       ret
-       
-/* rotate the data word (4 byte) pointed to by X by r20 bits to the left */
-memrotl32:
-       ld T0, X+
-       ld T1, X+
-       ld T2, X+
-       ld T3, X+
-       mov TT, T3
-1:
-       lsl TT
-       rol T0
-       rol T1
-       rol T2
-       rol T3
-       dec r20
-       brne 1b
-       st -X, T3
-       st -X, T2
-       st -X, T1
-       st -X, T0
-       ret
-
-/* xor the dataword (4 byte) pointed by Z into X */    
-memeor32:
-  ldi T2, 4
-1:  
-  ld T0, X             
-  ld T1, Z+
-  eor T0, T1
-  st X+, T0
-  dec T2
-  brne 1b
-  ret
-
-serpent_lt:
-        /* X0 := X0 <<< 13 */
-       movw r26, r24
-       ldi r20, 7
-       rcall memrotl32
-       ldi r20, 6
-       rcall memrotl32
-       /* X2 := X2 <<< 3 */
-       adiw r26, 8
-       ldi r20, 3
-       rcall memrotl32
-       /* X1 ^= X2 */
-       movw r30, r26
-       sbiw r26, 4
-       rcall memeor32
-       /* X1 ^= X0 */
-       sbiw r26, 4
-       sbiw r30, 12
-       rcall memeor32
-       /* X3 ^= X2 */
-       movw r30, r26
-       adiw r26, 4
-       rcall memeor32
-       /* T := X0 */
-       sbiw r26, 16
-       ld r18, X+
-       ld r19, X+
-       ld r20, X+
-       ld r21, X+
-       /* T := T<<3 */
-       ldi r22, 3
-1:
-       lsl r18
-       rol r19
-       rol r20
-       rol r21
-       dec r22
-       brne 1b
-       clr r31 
-       /* X3 ^= T */
-       adiw r26, 8
-       ldi r30, 18
-       rcall memeor32
-       /* X1 := X1<<<1 */
-       sbiw r26, 12
-       ldi r20, 1
-       rcall memrotl32
-       /* X3 := X3<<<7 */
-       adiw r26, 8
-       ldi r20, 7
-       rcall memrotl32
-       /* X0 ^= X3 */
-       movw r30, r26
-       sbiw r26, 12
-       rcall memeor32
-       /* X0 ^= X1 */
-       movw r30, r26
-       sbiw r26, 4
-       rcall memeor32
-       /* X2 ^= X3 */
-       adiw r26, 4
-       adiw r30, 4
-       rcall memeor32
-       /* T := X1<<<8 */
-       sbiw r26, 8
-       ld r19, X+
-       ld r20, X+
-       ld r21, X+
-       ld r18, X+
-       /* T := T>>>1; T&=0xfffffff8 */
-       lsr r18
-       ror r21
-       ror r20
-       ror r19
-       clr r18
-       ror r18
-       clr r31
-       ldi r30, 18
-       /* X2 ^= T */
-       rcall memeor32
-       /* X0 := X0 <<< 5 */
-       sbiw r26, 12
-       ldi r20, 5
-       rcall memrotl32
-       /* X3 := X3 >>> 10 */
-       adiw r26, 8
-       ldi r20, 7
-       rcall memrotr32
-       ldi r20, 3
-       rcall memrotr32
-       ret
-
-serpent_inv_lt:
-        /* X0 := X0 >>> 5 */
-       movw r26, r24
-       ldi r20, 5
-       rcall memrotr32
-       /* X2 := X2 <<< 10 */
-       adiw r26, 8
-       ldi r20, 7
-       rcall memrotl32
-       ldi r20, 3
-       rcall memrotl32
-       /* X2 ^= X3 */
-       movw r30, r26
-       adiw r30, 4
-       rcall memeor32
-       sbiw r26, 4
-       sbiw r30, 12
-       /* T := X1<<7 */
-       ld r19, Z+
-       ld r20, Z+
-       ld r21, Z+
-       ld r18, Z+
-       lsr r18
-       ror r21
-       ror r20
-       ror r19
-       clr r18
-       ror r18
-    clr r31
-    /* X2 ^= T */
-    ldi r30, 18
-    rcall memeor32
-    /* X0 ^= X1 */
-    sbiw r26, 12
-    movw r30, r26
-    adiw r30, 4
-    rcall memeor32
-    /* X0 ^= X3 */
-    sbiw r26, 4
-    adiw r30, 4
-    rcall memeor32
-    /* X1 := X1>>>1 */
-    ldi r20, 1
-       rcall memrotr32
-       /* X3 := X3>>>7 */
-       adiw r26, 8
-       ldi r20, 7
-       rcall memrotr32
-       /* X3 ^= X2 */
-       sbiw r30, 8
-       rcall memeor32
-       sbiw r26, 4
-       /* T:= X0<<3 */
-       sbiw r30, 12
-       ld r18, Z+
-       ld r19, Z+
-       ld r20, Z+
-       ld r21, Z+
-       ldi r24, 3
-1:
-       lsl r18
-       rol r19
-       rol r20
-       rol r21
-       dec r24
-       brne 1b
-       /* X3 ^= T */
-       clr r31
-       ldi r30, 18
-       rcall memeor32
-       /* X1 ^= X0 */
-       sbiw r26, 12
-       movw r30, r26
-       sbiw r30, 4
-       rcall memeor32
-       /* X1 ^= X2 */
-       movw r26, r30
-       adiw r30, 4
-       rcall memeor32
-       /* X2 := X2 >>> 3 */
-       ldi r20, 3
-       rcall memrotr32
-       /* X0 := X0 >>> 13 */
-       sbiw r26, 8
-       ldi r20, 7
-       rcall memrotr32
-       ldi r20, 6
-       rcall memrotr32
-       ret
-
-/*
-#define GOLDEN_RATIO 0x9e3779b9l
-
-static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
-       uint32_t ret;
-       ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
-       ret = rotl32(ret, 11);
-       return ret;
-}
-*/
-/*
- * param b is passed in r24:r25
- * param i is passed in r22
- * return value is returned in r22.r23.r24.r25
- */
- /* trashes:
-  *  r20-r25, r30-r31
-  */
-serpent_gen_w:
-       movw r30, r24
-       /* ^i^b[0]*/
-    ld r21, Z+
-    eor r22, r21
-    ld r23, Z+
-    ld r24, Z+
-    ld r25, Z+
-    /* ^b[3]^b[5]^[b7] */
-    adiw r30, 4
-    ldi r20, 3
-1:    
-    adiw r30, 4
-    ld r21, Z+
-    eor r22, r21
-    ld r21, Z+
-    eor r23, r21
-    ld r21, Z+
-    eor r24, r21
-    ld r21, Z+
-    eor r25, r21
-       dec r20
-       brne 1b
-       /* ^0x9e3779b9l */
-       ldi r21, 0xb9
-       eor r22, r21
-       ldi r21, 0x79
-       eor r23, r21
-       ldi r21, 0x37
-       eor r24, r21
-       ldi r21, 0x9e
-       eor r25, r21
-       /* <<<11 */
-       mov r21, r25
-       mov r25, r24
-       mov r24, r23
-       mov r23, r22
-       mov r22, r21
-       mov r21, r25
-       ldi r20, 3
-1:
-       lsl r21
-       rol r22
-       rol r23
-       rol r24
-       rol r25
-       dec r20
-       brne 1b
-       ret
-
-/*
- * void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx)
- */
-/*
- * param key     is passed in r24:r25
- * param keysize is passed in r22:r23
- * param ctx     is passed in r20:r21
- */
-.global serpent_init
-serpent_init:
-    stack_alloc 32
-    adiw r30, 1
-       push_ r30, r31
-    movw r26, r22
-    adiw r26, 7
-    tst r27
-    breq 1f
-       ldi r26, 32
-       rjmp 2f
-1:
-       lsr r26
-       lsr r26
-       lsr r26
-2:     
-       mov r22, r26
-       bst r22, 5 /* store in T if we have to do the "append 1 thing"*/
-       ldi r27, 32
-3:     /* set buffer to zero */
-       st Z+, r1
-       dec r27
-       brne 3b
-       
-       movw r26, r24 /* X points to the key */
-       sbiw r30, 32
-       tst r22
-       breq 5f /* if keylength_b==0 */
-4:     /* copy keybytes to buffer */
-       ld r19, X+
-       st Z+, r19
-       dec r22
-       brne 4b
-5:
-       brts 7f /* if keylength_b == 256 */
-       ldi r18, 0x01
-       andi r22, 0x07
-       brne 6f
-       st Z, r18
-       rjmp 7f
-6:     /* shift the one to the right position */
-       lsl r18
-       dec r22
-       brne 6b
-       or r18, r19
-       st -Z, r18
-7: /* post "appending 1 thing" buffer is ready for subkey generation */
-       movw r26, r20  /* X points to the context */
-       
-       pop_ r19, r18 /* r18:r19 points to the buffer */
-       push r16
-       clr r16
-8:
-       movw r24, r18
-       mov  r22, r16
-       rcall serpent_gen_w
-       movw r30, r18
-       ldi r20, 7*4
-1: /* the memmove */
-       ldd r0, Z+4
-       st Z+, r0
-       dec r20
-       brne 1b
-  /* store new word in buffer and context */   
-       st Z+, r22
-       st Z+, r23
-       st Z+, r24
-       st Z+, r25
-       st X+, r22
-       st X+, r23
-       st X+, r24
-       st X+, r25
-       
-       inc r16
-       cpi r16, 132
-       brne 8b 
-       
-       push_ r28, r29
-       movw r28, r26
-       subi r28, lo8(132*4)
-       sbci r29, hi8(132*4)
-       ldi r16, 33
-2:
-       movw r24, r28
-       adiw r28, 16
-       ldi r22, 2
-       add r22, r16
-       rcall sbox128
-       dec r16
-       brne 2b
-       pop_ r29, r28, r16
-       stack_free 32
-       ret
-
-/*
- * void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
- */
-/*
- * param buffer is passed in r24:r25
- * param ctx    is passed in r22:r23
- */
-.global serpent_enc
-serpent_enc:
-
-       push_ r12, r13, r14, r15, r16 
-       clr r16
-       movw r14, r24
-       movw r12, r22
-1:
-       movw r24, r14
-       movw r22, r12
-       ldi r20, 16
-       add r12, r20
-       adc r13, r1
-       clr r21
-       rcall memxor
-       movw r24, r14
-       mov r22, r16
-       rcall sbox128
-       movw r24, r14
-       rcall serpent_lt
-       
-       inc r16
-       cpi r16, 31
-       brne 1b
-       
-       movw r24, r14
-       movw r22, r12
-       ldi r20, 16
-       add r12, r20
-       adc r13, r1
-       clr r21
-       rcall memxor
-       movw r24, r14
-       mov r22, r16
-       rcall sbox128
-       
-       inc r16
-       movw r24, r14
-       movw r22, r12
-       ldi r20, 16
-       clr r21
-       pop_ r16, r15, r14, r13, r12
-       rjmp memxor
-
-/*
- * void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
- */
-/*
- * param buffer is passed in r24:r25
- * param ctx    is passed in r22:r23
- */
-.global serpent_dec
-serpent_dec:
-       push_ r12, r13, r14, r15, r16 
-       movw r14, r24
-//     ldi r16, lo8(32*16)
-//     add r22, r16
-       ldi r16, hi8(32*16)
-       add r23, r16
-       movw r12, r22
-       ldi r20, 16
-       clr r21
-       rcall memxor
-       
-       movw r24, r14
-       ldi r22, 31
-       call inv_sbox128
-       
-       movw r24, r14
-       ldi r20, 16
-       sub r12, r20
-       sbc r13, r1
-       movw r22, r12
-       clr r21
-       rcall memxor
-       ldi r16, 31
-1:
-       dec r16
-       movw r24, r14
-       rcall serpent_inv_lt
-       movw r24, r14
-       mov r22, r16
-       rcall inv_sbox128
-       movw r24, r14
-       ldi r20, 16
-       sub r12, r20
-       sbc r13, r1
-       movw r22, r12
-       clr r21
-       rcall memxor
-       
-       tst r16
-       brne 1b
-       pop_ r16, r15, r14, r13, r12
-       ret     
-       
-       
-       
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/serpent-sboxes-bitslice-asm.S b/serpent-sboxes-bitslice-asm.S
deleted file mode 100644 (file)
index 4e0d7db..0000000
+++ /dev/null
@@ -1,854 +0,0 @@
-/* serpent-sboxes-bitslice.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* serpent-sboxes.c
- * a bitsliced implementation of the serpent sboxes
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- */
-
-#include "avr-asm-macros.S"
-IN0  = 22
-IN1  = 23
-IN2  = 24
-IN3  = 25
-OUT0 = 18
-OUT1 = 19
-OUT2 = 20
-OUT3 = 21
-T00 =  2
-T00 =  3
-T01 =  4
-T02 =  5
-T03 =  6
-T04 =  7
-T05 =  8
-T06 =  9
-T07 = 10
-T08 = 11
-T09 = 12
-T10 = 13
-T11 = 14
-T12 = 15
-T13 = 16
-T14 = 17
-T15 = 26
-T16 = 27
-T17 =  0
-
-/* S0:   3  8 15  1 10  6  5 11 14 13  4  2  7  0  9 12 */
-
-/* depth = 5,7,4,2, Total gates=18 */
-sb0:
-    mov T00, IN1
-    eor T00, IN2
-    mov T01, IN0
-    or  T01, IN3
-    mov T02, IN0
-    eor T02, IN1
-    mov OUT3, T01
-    eor OUT3, T00
-    mov T04, IN2
-    or  T04, OUT3
-    mov T05, IN0
-    eor T05, IN3
-    mov T06, IN1
-    or  T06, IN2
-    mov T07, IN3
-    and T07, T04
-    mov T08, T02
-    and T08, T06
-    mov OUT2, T08
-    eor OUT2, T07
-    mov T10, T08
-    and T10, OUT2
-    mov T11, IN2
-    eor T11, IN3
-    mov T12, T06
-    eor T12, T10
-    mov T13, IN1
-    and T13, T05
-    mov T14, T05
-    eor T14, T12
-       mov OUT0, T14
-       com OUT0
-       mov T16, OUT0
-    eor T16, T13
-    mov OUT1, T11
-    eor OUT1, T16
-       ret
-
-       
-/* InvS0:  13  3 11  0 10  6  5 12  1 14  4  7 15  9  8  2 */
-
-/* depth = 8,4,3,6, Total gates=19 */
-sb0_inv:
-    mov T00, IN2
-    eor T00, IN3
-    mov T01, IN0
-    or  T01, IN1
-    mov T02, IN1
-    or  T02, IN2
-    mov T03, IN2
-    and T03, T00
-    mov T04, T01
-    eor T04, T00
-    mov T05, IN0
-    or  T05, T03
-       mov OUT2, T04
-       com OUT2
-    mov T07, IN1
-    eor T07, IN3
-    mov T08, T02
-    and T08, T07
-    mov T09, IN3
-    or  T09, OUT2
-    mov OUT1, T08
-    eor OUT1, T05
-    mov T11, IN0
-    or  T11, T04
-    mov T12, OUT1
-    eor T12, T11
-    mov T13, T02
-    eor T13, T09
-    mov T14, IN0
-    eor T14, IN2
-    mov OUT3, T13
-    eor OUT3, T12
-    mov T16, T04
-    and T16, T12
-    mov T17, T13
-    or  T17, T16
-    mov OUT0, T14
-    eor OUT0, T17
-       ret
-
-
-/* S1:  15 12  2  7  9  0  5 10  1 11 14  8  6 13  3  4 */
-
-/* depth = 10,7,3,5, Total gates=18 */
-sb1:
-    mov T00, IN0
-    or  T00, IN3
-    mov T01, IN2
-    eor T01, IN3
-       mov T02, IN1
-       com T02
-    mov T03, IN0
-    eor T03, IN2
-    mov T04, IN0
-    or  T04, T02
-    mov T05, IN3
-    and T05, T03
-    mov T06, T00
-    and T06, T01
-    mov T07, IN1
-    or  T07, T05
-    mov OUT2, T01
-    eor OUT2, T04
-    mov T09, T06
-    eor T09, T07
-    mov T10, T00
-    eor T10, T09
-    mov T11, OUT2
-    eor T11, T10
-    mov T12, IN1
-    and T12, IN3
-       mov OUT3, T09
-       com OUT3
-    mov OUT1, T12
-    eor OUT1, T11
-    mov T15, T09
-    or  T15, OUT1
-    mov T16, T04
-    and T16, T15
-    mov OUT0, IN2
-    eor OUT0, T16
-       ret
-
-
-/* InvS1:   5  8  2 14 15  6 12  3 11  4  7  9  1 13 10  0 */
-
-/* depth = 7,4,5,3, Total gates=18 */
-sb1_inv:
-    mov T00, IN0
-    eor T00, IN1
-    mov T01, IN1
-    or  T01, IN3
-    mov T02, IN0
-    and T02, IN2
-    mov T03, IN2
-    eor T03, T01
-    mov T04, IN0
-    or  T04, T03
-    mov T05, T00
-    and T05, T04
-    mov T06, IN3
-    or  T06, T02
-    mov T07, IN1
-    eor T07, T05
-    mov T08, T06
-    eor T08, T05
-    mov T09, T03
-    or  T09, T02
-    mov T10, IN3
-    and T10, T07
-    mov OUT2, T08
-    com OUT2
-       mov OUT1, T09
-    eor OUT1, T10
-    mov T13, IN0
-    or  T13, OUT2
-    mov T14, T05
-    eor T14, OUT1
-    mov OUT3, T00
-    eor OUT3, T03
-    mov T16, IN2
-    eor T16, T14
-    mov OUT0, T13
-    eor OUT0, T16
-       ret
-
-/* S2:   8  6  7  9  3 12 10 15 13  1 14  4  0 11  5  2 */
-
-/* depth = 3,8,11,7, Total gates=16 */
-sb2:
-    mov T00, IN0
-    or  T00, IN2
-    mov T01, IN0
-    eor T01, IN1
-    mov T02, IN3
-    eor T02, T00
-    mov OUT0, T01
-    eor OUT0, T02
-    mov T04, IN2
-    eor T04, OUT0
-    mov T05, IN1
-    eor T05, T04
-    mov T06, IN1
-    or  T06, T04
-    mov T07, T00
-    and T07, T05
-    mov T08, T02
-    eor T08, T06
-    mov T09, T01
-    or  T09, T08
-    mov OUT1, T09
-    eor OUT1, T07
-    mov T11, IN0
-    or  T11, IN3
-    mov T12, T08
-    eor T12, OUT1
-    mov T13, IN1
-    eor T13, T12
-       mov OUT3, T08
-       com OUT3
-    mov OUT2, T11
-    eor OUT2, T13
-       ret
-
-/* InvS2:  12  9 15  4 11 14  1  2  0  3  6 13  5  8 10  7 */
-
-/* depth = 3,6,8,3, Total gates=18 */
-sb2_inv:
-    mov T00, IN0
-    eor T00, IN3
-    mov T01, IN2
-    eor T01, IN3
-    mov T02, IN0
-    and T02, IN2
-    mov T03, IN1
-    or  T03, T01
-    mov OUT0, T00
-    eor OUT0, T03
-    mov T05, IN0
-    or  T05, IN2
-    mov T06, IN3
-    or  T06, OUT0
-       mov T07, IN3
-       com T07
-    mov T08, IN1
-    and T08, T05
-    mov T09, T07
-    or  T09, T02
-    mov T10, IN1
-    and T10, T06
-    mov T11, T05
-    and T11, T01
-    mov OUT3, T08
-    eor OUT3, T09
-    mov OUT1, T11
-    eor OUT1, T10
-    mov T14, IN2
-    and T14, OUT3
-    mov T15, OUT0
-    eor T15, OUT1
-    mov T16, T09
-    eor T16, T14
-    mov OUT2, T15
-    eor OUT2, T16
-       ret
-
-/* S3:   0 15 11  8 12  9  6  3 13  1  2  4 10  7  5 14 */
-
-/* depth = 8,3,5,5, Total gates=18 */
-sb3:
-    mov T00, IN0
-    eor T00, IN2
-    mov T01, IN0
-    or  T01, IN3
-    mov T02, IN0
-    and T02, IN3
-    mov T03, T00
-    and T03, T01
-    mov T04, IN1
-    or  T04, T02
-    mov T05, IN0
-    and T05, IN1
-    mov T06, IN3
-    eor T06, T03
-    mov T07, IN2
-    or  T07, T05
-    mov T08, IN1
-    eor T08, T06
-    mov T09, IN3
-    and T09, T04
-    mov T10, T01
-    eor T10, T09
-    mov OUT3, T07
-    eor OUT3, T08
-    mov T12, IN3
-    or  T12, OUT3
-    mov T13, IN0
-    or  T13, T06
-    mov T14, IN1
-    and T14, T12
-    mov OUT2, T07
-    eor OUT2, T10
-    mov OUT0, T13
-    eor OUT0, T14
-    mov OUT1, T04
-    eor OUT1, T03
-       ret
-
-/* InvS3:   0  9 10  7 11 14  6 13  3  5 12  2  4  8 15  1 */
-
-/* depth = 3,6,4,4, Total gates=17 */
-sb3_inv:
-    mov T00, IN2
-    or  T00, IN3
-    mov T01, IN0
-    or  T01, IN3
-    mov T02, IN2
-    eor T02, T01
-    mov T03, IN1
-    eor T03, T01
-    mov T04, IN0
-    eor T04, IN3
-    mov T05, T03
-    and T05, T02
-    mov T06, IN1
-    and T06, T00
-    mov OUT2, T04
-    eor OUT2, T05
-    mov T08, IN0
-    eor T08, T02
-    mov OUT0, T06
-    eor OUT0, T02
-    mov T10, OUT0
-    or  T10, T04
-    mov T11, T08
-    and T11, T10
-    mov T12, IN0
-    and T12, OUT2
-    mov T13, T00
-    eor T13, T04
-    mov OUT1, IN1
-    eor OUT1, T11
-    mov T15, IN1
-    or  T15, T12
-    mov OUT3, T13
-    eor OUT3, T15
-       ret
-
-/* S4:   1 15  8  3 12  0 11  6  2  5  4 10  9 14  7 13 */
-
-/* depth = 6,7,5,3, Total gates=19 */
-sb4:
-    mov T00, IN0
-    or  T00, IN1
-    mov T01, IN1
-    or  T01, IN2
-    mov T02, IN0
-    eor T02, T01
-    mov T03, IN1
-    eor T03, IN3
-    mov T04, IN3
-    or  T04, T02
-    mov T05, IN3
-    and T05, T00
-    mov OUT3, T02
-    eor OUT3, T05
-    mov T07, OUT3
-    and T07, T03
-    mov T08, T03
-    and T08, T04
-    mov T09, IN2
-    eor T09, T05
-    mov T10, IN1
-    and T10, IN2
-    mov T11, T03
-    eor T11, T07
-    mov T12, T10
-    or  T12, T02
-    mov T13, T09
-    eor T13, T08
-    mov T14, IN0
-    and T14, T04
-    mov T15, T10
-    or  T15, T11
-    mov OUT2, T12
-    eor OUT2, T07
-    mov OUT1, T14
-    eor OUT1, T15
-       mov OUT0, T13
-       com OUT0
-       ret
-
-/* InvS4:   5  0  8  3 10  9  7 14  2 12 11  6  4 15 13  1 */
-
-/* depth = 6,4,7,3, Total gates=17 */
-sb4_inv:
-    mov T00, IN1
-    or  T00, IN3
-    mov T01, IN2
-    or  T01, IN3
-    mov T02, IN0
-    and T02, T00
-    mov T03, IN1
-    eor T03, T01
-    mov T04, IN2
-    eor T04, IN3
-       mov T05, T02
-       com T05
-    mov T06, IN0
-    and T06, T03
-    mov OUT1, T04
-    eor OUT1, T06
-    mov T08, OUT1
-    or  T08, T05
-    mov T09, IN0
-    eor T09, T06
-    mov T10, T00
-    eor T10, T08
-    mov T11, IN3
-    eor T11, T03
-    mov T12, IN2
-    or  T12, T09
-    mov OUT3, T02
-    eor OUT3, T11
-    mov T14, IN0
-    eor T14, T03
-    mov OUT2, T10
-    eor OUT2, T12
-    mov OUT0, T14
-    eor OUT0, T08
-       ret
-
-/* S5:  15  5  2 11  4 10  9 12  0  3 14  8 13  6  7  1 */
-
-/* depth = 4,6,8,6, Total gates=17 */
-sb5:
-    mov T00, IN1
-    eor T00, IN3
-    mov T01, IN1
-    or  T01, IN3
-    mov T02, IN0
-    and T02, T00
-    mov T03, IN2
-    eor T03, T01
-    mov T04, T02
-    eor T04, T03
-       mov OUT0, T04
-       com OUT0
-    mov T06, IN0
-    eor T06, T00
-    mov T07, IN3
-    or  T07, OUT0
-    mov T08, IN1
-    or  T08, T04
-    mov T09, IN3
-    eor T09, T07
-    mov T10, IN1
-    or  T10, T06
-    mov T11, T02
-    or  T11, OUT0
-    mov T12, T06
-    or  T12, T09
-    mov T13, T00
-    eor T13, T10
-    mov OUT2, T08
-    eor OUT2, T12
-    mov OUT1, T06
-    eor OUT1, T07
-    mov OUT3, T11
-    eor OUT3, T13
-       ret
-
-/* InvS5:   8 15  2  9  4  1 13 14 11  6  5  3  7 12 10  0 */
-
-/* depth = 4,6,9,7, Total gates=17 */
-sb5_inv:
-    mov T00, IN0
-    and T00, IN3
-    mov T01, IN2
-    eor T01, T00
-    mov T02, IN0
-    eor T02, IN3
-    mov T03, IN1
-    and T03, T01
-    mov T04, IN0
-    and T04, IN2
-    mov OUT0, T02
-    eor OUT0, T03
-    mov T06, IN0
-    and T06, OUT0
-    mov T07, T00
-    eor T07, OUT0
-    mov T08, IN1
-    or  T08, T04
-       mov T09, IN1
-       com T09
-    mov OUT1, T07
-    eor OUT1, T08
-    mov T11, T09
-    or  T11, T06
-    mov T12, OUT0
-    or  T12, OUT1
-    mov OUT3, T01
-    eor OUT3, T11
-    mov T14, T01
-    eor T14, T12
-    mov T15, IN1
-    eor T15, IN3
-    mov OUT2, T15
-    eor OUT2, T14
-       ret
-
-/* S6:   7  2 12  5  8  4  6 11 14  9  1 15 13  3 10  0 */
-
-/* depth = 8,3,6,3, Total gates=19 */
-sb6:
-    mov T00, IN0
-    and T00, IN3
-    mov T01, IN1
-    eor T01, IN2
-    mov T02, IN0
-    eor T02, IN3
-    mov T03, T00
-    eor T03, T01
-    mov T04, IN1
-    or  T04, IN2
-       mov OUT1, T03
-       com OUT1
-    mov T06, T02
-    and T06, T04
-    mov T07, IN1
-    and T07, OUT1
-    mov T08, IN0
-    or  T08, IN2
-    mov T09, T06
-    eor T09, T07
-    mov T10, IN1
-    or  T10, IN3
-    mov T11, IN2
-    eor T11, T10
-    mov T12, T08
-    eor T12, T09
-       mov OUT2, T12
-       com OUT2
-    mov T14, OUT1
-    and T14, T02
-    mov OUT3, T11
-    eor OUT3, T06
-    mov T16, IN0
-    eor T16, IN1
-    mov T17, OUT2
-    eor T17, T14
-    mov OUT0, T16
-    eor OUT0, T17
-       ret
-
-/* InvS6:  15 10  1 13  5  3  6  0  4  9 14  7  2 12  8 11 */
-
-/* depth = 5,3,8,6, Total gates=19 */
-sb6_inv:
-    mov T00, IN0
-    eor T00, IN2
-       mov T01, IN2
-       com T01
-    mov T02, IN1
-    and T02, T00
-    mov T03, IN1
-    or  T03, T01
-    mov T04, IN3
-    or  T04, T02
-    mov T05, IN1
-    eor T05, IN3
-    mov T06, IN0
-    and T06, T03
-    mov T07, IN0
-    or  T07, T01
-    mov T08, T06
-    eor T08, T04
-    mov OUT1, T05
-    eor OUT1, T07
-       mov OUT0, T08
-       com OUT0
-    mov T11, IN1
-    and T11, OUT0
-    mov T12, T00
-    and T12, T04
-    mov T13, T00
-    eor T13, T11
-    mov T14, T06
-    eor T14, T12
-    mov T15, IN3
-    or  T15, T01
-    mov T16, IN0
-    eor T16, OUT1
-    mov OUT3, T16
-    eor OUT3, T14
-    mov OUT2, T15
-    eor OUT2, T13
-       ret
-
-/* S7:   1 13 15  0 14  8  2 11  7  4 12 10  9  3  5  6 */
-
-/* depth = 10,7,10,4, Total gates=19 */
-sb7:
-    mov T00, IN0
-    and T00, IN2
-       mov T01, IN3
-       com T01
-    mov T02, IN0
-    and T02, T01
-    mov T03, IN1
-    or  T03, T00
-    mov T04, IN0
-    and T04, IN1
-    mov T05, IN2
-    eor T05, T03
-    mov OUT3, T02
-    eor OUT3, T05
-    mov T07, IN2
-    or  T07, OUT3
-    mov T08, IN3
-    or  T08, T04
-    mov T09, IN0
-    eor T09, T07
-    mov T10, T03
-    and T10, OUT3
-    mov OUT1, T08
-    eor OUT1, T09
-    mov T12, IN1
-    eor T12, OUT1
-    mov T13, T00
-    eor T13, OUT1
-    mov T14, IN2
-    eor T14, T04
-    mov T15, T10
-    or  T15, T12
-    mov T16, T01
-    or  T16, T13
-    mov OUT0, T14
-    eor OUT0, T16
-    mov OUT2, IN0
-    eor OUT2, T15
-       ret
-
-/* InvS7:   3  0  6 13  9 14 15  8  5 12 11  7 10  1  4  2 */
-
-/* depth = 9,7,3,3, Total gates=18 */
-sb7_inv:
-    mov T00, IN0
-    and T00, IN1
-    mov T01, IN0
-    or  T01, IN1
-    mov T02, IN2
-    or  T02, T00
-    mov T03, IN3
-    and T03, T01
-    mov OUT3, T02
-    eor OUT3, T03
-    mov T05, IN1
-    eor T05, T03
-    mov T06, IN3
-    eor T06, OUT3
-    mov T07, T06
-    com T07
-    mov T08, T05
-    or  T08, T07
-    mov T09, IN1
-    eor T09, IN3
-    mov T10, IN0
-    or  T10, IN3
-    mov OUT1, IN0
-    eor OUT1, T08
-    mov T12, IN2
-    eor T12, T05
-    mov T13, IN2
-    and T13, T10
-    mov T14, IN3
-    or  T14, OUT1
-    mov T15, T00
-    or  T15, T09
-    mov OUT0, T12
-    eor OUT0, T14
-    mov OUT2, T13
-    eor OUT2, T15
-       ret
-
-sf_tab:
-.word sb0, sb1, sb2, sb3
-.word sb4, sb5, sb6, sb7
-
-sinvf_tab:
-.word sb0_inv, sb1_inv, sb2_inv, sb3_inv
-.word sb4_inv, sb5_inv, sb6_inv, sb7_inv
-
-/*
-.byte pm_lo8(sb0), pm_hi8(sb0)
-.byte pm_lo8(sb1), pm_hi8(sb1)
-.byte pm_lo8(sb2), pm_hi8(sb2)
-.byte pm_lo8(sb3), pm_hi8(sb3)
-.byte pm_lo8(sb4), pm_hi8(sb4)
-.byte pm_lo8(sb5), pm_hi8(sb5)
-.byte pm_lo8(sb6), pm_hi8(sb6)
-.byte pm_lo8(sb7), pm_hi8(sb7)
-
-
-sinvf_tab:
-.byte pm_lo8(sb0_inv), pm_hi8(sb0_inv)
-.byte pm_lo8(sb1_inv), pm_hi8(sb1_inv)
-.byte pm_lo8(sb2_inv), pm_hi8(sb2_inv)
-.byte pm_lo8(sb3_inv), pm_hi8(sb3_inv)
-.byte pm_lo8(sb4_inv), pm_hi8(sb4_inv)
-.byte pm_lo8(sb5_inv), pm_hi8(sb5_inv)
-.byte pm_lo8(sb6_inv), pm_hi8(sb6_inv)
-.byte pm_lo8(sb7_inv), pm_hi8(sb7_inv)
-*/
-/*
-void sbox128(void * w, uint8_t box){
-       uint8_t i, buffer[16];
-       box &= 0x7;
-       
-       sb_fpt fp;
-       fp = (sb_fpt)pgm_read_word(&(sf_tab[box]));
-       for(i=0; i<4; ++i){
-               fp(buffer+i, (uint8_t*)w+i);
-       }
-       memcpy(w, buffer, 16);
-}
-*/
-.global sbox128
-sbox128:
-       ldi r30, lo8(sf_tab)
-       ldi r31, hi8(sf_tab)
-1:
-;      clr r1
-       andi r22, 0x07
-       lsl r22
-       add r30, r22
-       adc r31, r1
-       lpm r26, Z+
-       lpm r27, Z
-       lsr r27
-       ror r26
-       push r28
-       push r29
-       movw r30, r26
-       movw r28, r24
-       push_range 2, 17
-       ldd IN0, Y+0
-       ldd IN1, Y+4
-       ldd IN2, Y+8
-       ldd IN3, Y+12
-       icall 
-       std Y+0, OUT0
-       std Y+4, OUT1
-       std Y+8, OUT2
-       std Y+12, OUT3
-       ldd IN0, Y+0+1
-       ldd IN1, Y+4+1
-       ldd IN2, Y+8+1
-       ldd IN3, Y+12+1
-       icall
-       std Y+0+1, OUT0
-       std Y+4+1, OUT1
-       std Y+8+1, OUT2
-       std Y+12+1, OUT3
-       ldd IN0, Y+0+2
-       ldd IN1, Y+4+2
-       ldd IN2, Y+8+2
-       ldd IN3, Y+12+2
-       icall
-       std Y+0+2, OUT0
-       std Y+4+2, OUT1
-       std Y+8+2, OUT2
-       std Y+12+2, OUT3
-       ldd IN0, Y+0+3
-       ldd IN1, Y+4+3
-       ldd IN2, Y+8+3
-       ldd IN3, Y+12+3
-       icall
-       std Y+0+3, OUT0
-       std Y+4+3, OUT1
-       std Y+8+3, OUT2
-       std Y+12+3, OUT3
-       pop_range 2, 17
-       pop r29
-       pop r28
-       ret
-       
-.global        inv_sbox128
-inv_sbox128:
-       ldi r30, lo8(sinvf_tab)
-       ldi r31, hi8(sinvf_tab)
-       rjmp 1b 
-/*     
-void inv_sbox128(void * w, uint8_t box){
-       uint8_t i, buffer[16];
-       box &= 0x7;
-       
-       sb_fpt fp;
-       fp = (sb_fpt)pgm_read_word(&(sinvf_tab[box]));
-       for(i=0; i<4; ++i){
-               fp(buffer+i, (uint8_t*)w+i);
-       }
-       memcpy(w, buffer, 16);
-}
-*/
-
-
-
-
-
-
-
diff --git a/serpent-sboxes-bitslice.c b/serpent-sboxes-bitslice.c
deleted file mode 100644 (file)
index 96f9c68..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/* serpent-sboxes-bitslice.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* serpent-sboxes.c
- * a bitsliced implementation of the serpent sboxes
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "serpent-sboxes.h"
-
-
-
-
-/* S0:   3  8 15  1 10  6  5 11 14 13  4  2  7  0  9 12 */
-
-/* depth = 5,7,4,2, Total gates=18 */
-static
-void sb0(uint8_t* out, const uint8_t* in){
-// (a,b,c,d,w,x,y,z) 
-       uint8_t t01, t02, t03, t05, t06, t07, t08, t09, t11, t12, t13, t14, t15, t17;
-       t01          = in[4*1]  ^ in[4*2]; 
-       t02          = in[4*0]  | in[4*3]; 
-       t03          = in[4*0]  ^ in[4*1]; 
-       out[4*3]   = t02        ^ t01; 
-       t05          = in[4*2]  | out[4*3]; 
-       t06          = in[4*0]  ^ in[4*3]; 
-       t07          = in[4*1]  | in[4*2]; 
-       t08          = in[4*3]  & t05; 
-       t09          = t03        & t07; 
-       out[4*2]   = t09        ^ t08; 
-       t11          = t09        & out[4*2]; 
-       t12          = in[4*2]  ^ in[4*3]; 
-       t13          = t07        ^ t11; 
-       t14          = in[4*1]  & t06; 
-       t15          = t06        ^ t13; 
-       out[4*0]   =     ~ t15; 
-       t17          = out[4*0] ^ t14; 
-       out[4*1]   = t12        ^ t17; 
-}
-
-/* InvS0:  13  3 11  0 10  6  5 12  1 14  4  7 15  9  8  2 */
-
-/* depth = 8,4,3,6, Total gates=19 */
-static
-void sb0_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;
-       t01          = in[4*2] ^ in[4*3];
-       t02          = in[4*0] | in[4*1];
-       t03          = in[4*1] | in[4*2];
-       t04          = in[4*2] & t01;
-       t05          = t02       ^ t01;
-       t06          = in[4*0] | t04;
-       out[4*2]   =     ~ t05;
-       t08          = in[4*1]   ^ in[4*3];
-       t09          = t03       & t08;
-       t10          = in[4*3]   | out[4*2];
-       out[4*1]   = t09       ^ t06;
-       t12          = in[4*0]   | t05;
-       t13          = out[4*1]   ^ t12;
-       t14          = t03       ^ t10;
-       t15          = in[4*0]   ^ in[4*2];
-       out[4*3]   = t14       ^ t13;
-       t17          = t05       & t13;
-       t18          = t14       | t17;
-       out[4*0]   = t15       ^ t18; 
-}
-
-/* S1:  15 12  2  7  9  0  5 10  1 11 14  8  6 13  3  4 */
-
-/* depth = 10,7,3,5, Total gates=18 */
-static 
-void sb1(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t08, t10, t11, t12, t13, t16, t17, t01;
-       t01          = in[4*0]   | in[4*3];
-       t02          = in[4*2]   ^ in[4*3];
-       t03          =     ~ in[4*1];
-       t04          = in[4*0]   ^ in[4*2];
-       t05          = in[4*0]   | t03;
-       t06          = in[4*3]   & t04;
-       t07          = t01       & t02;
-       t08          = in[4*1]   | t06;
-       out[4*2]   = t02       ^ t05;
-       t10          = t07       ^ t08;
-       t11          = t01       ^ t10;
-       t12          = out[4*2]   ^ t11;
-       t13          = in[4*1]   & in[4*3];
-       out[4*3]   =     ~ t10;
-       out[4*1]   = t13       ^ t12;
-       t16          = t10       | out[4*1];
-       t17          = t05       & t16;
-       out[4*0]   = in[4*2]   ^ t17; 
-}
-
-/* InvS1:   5  8  2 14 15  6 12  3 11  4  7  9  1 13 10  0 */
-
-/* depth = 7,4,5,3, Total gates=18 */
-static void sb1_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;
-       t01          = in[4*0]   ^ in[4*1];
-       t02          = in[4*1]   | in[4*3];
-       t03          = in[4*0]   & in[4*2];
-       t04          = in[4*2]   ^ t02;
-       t05          = in[4*0]   | t04;
-       t06          = t01       & t05;
-       t07          = in[4*3]   | t03;
-       t08          = in[4*1]   ^ t06;
-       t09          = t07       ^ t06;
-       t10          = t04       | t03;
-       t11          = in[4*3]   & t08;
-       out[4*2]   =     ~ t09;
-       out[4*1]   = t10       ^ t11;
-       t14          = in[4*0]   | out[4*2];
-       t15          = t06       ^ out[4*1];
-       out[4*3]   = t01       ^ t04;
-       t17          = in[4*2]   ^ t15;
-       out[4*0]   = t14       ^ t17; 
-}
-
-/* S2:   8  6  7  9  3 12 10 15 13  1 14  4  0 11  5  2 */
-
-/* depth = 3,8,11,7, Total gates=16 */
-static void sb2(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t05, t06, t07, t08, t09, t10, t12, t13, t14, t01;
-       t01          = in[4*0]   | in[4*2];
-       t02          = in[4*0]   ^ in[4*1];
-       t03          = in[4*3]   ^ t01;
-       out[4*0]   = t02       ^ t03;
-       t05          = in[4*2]   ^ out[4*0];
-       t06          = in[4*1]   ^ t05;
-       t07          = in[4*1]   | t05;
-       t08          = t01       & t06;
-       t09          = t03       ^ t07;
-       t10          = t02       | t09;
-       out[4*1]   = t10       ^ t08;
-       t12          = in[4*0]   | in[4*3];
-       t13          = t09       ^ out[4*1];
-       t14          = in[4*1]   ^ t13;
-       out[4*3]   =     ~ t09;
-       out[4*2]   = t12       ^ t14; 
-}
-
-/* InvS2:  12  9 15  4 11 14  1  2  0  3  6 13  5  8 10  7 */
-
-/* depth = 3,6,8,3, Total gates=18 */
-static void sb2_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;
-       t01          = in[4*0]   ^ in[4*3];
-       t02          = in[4*2]   ^ in[4*3];
-       t03          = in[4*0]   & in[4*2];
-       t04          = in[4*1]   | t02;
-       out[4*0]   = t01       ^ t04;
-       t06          = in[4*0]   | in[4*2];
-       t07          = in[4*3]   | out[4*0];
-       t08          =     ~ in[4*3];
-       t09          = in[4*1]   & t06;
-       t10          = t08       | t03;
-       t11          = in[4*1]   & t07;
-       t12          = t06       & t02;
-       out[4*3]   = t09       ^ t10;
-       out[4*1]   = t12       ^ t11;
-       t15          = in[4*2]   & out[4*3];
-       t16          = out[4*0]   ^ out[4*1];
-       t17          = t10       ^ t15;
-       out[4*2]   = t16       ^ t17; 
-}
-
-/* S3:   0 15 11  8 12  9  6  3 13  1  2  4 10  7  5 14 */
-
-/* depth = 8,3,5,5, Total gates=18 */
-static void sb3(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t13, t14, t15, t01;
-       t01          = in[4*0]   ^ in[4*2];
-       t02          = in[4*0]   | in[4*3];
-       t03          = in[4*0]   & in[4*3];
-       t04          = t01       & t02;
-       t05          = in[4*1]   | t03;
-       t06          = in[4*0]   & in[4*1];
-       t07          = in[4*3]   ^ t04;
-       t08          = in[4*2]   | t06;
-       t09          = in[4*1]   ^ t07;
-       t10          = in[4*3]   & t05;
-       t11          = t02       ^ t10;
-       out[4*3]   = t08       ^ t09;
-       t13          = in[4*3]   | out[4*3];
-       t14          = in[4*0]   | t07;
-       t15          = in[4*1]   & t13;
-       out[4*2]   = t08       ^ t11;
-       out[4*0]   = t14       ^ t15;
-       out[4*1]   = t05       ^ t04; 
-}
-
-/* InvS3:   0  9 10  7 11 14  6 13  3  5 12  2  4  8 15  1 */
-
-/* depth = 3,6,4,4, Total gates=17 */
-static void sb3_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;
-       t01          = in[4*2]   | in[4*3];
-       t02          = in[4*0]   | in[4*3];
-       t03          = in[4*2]   ^ t02;
-       t04          = in[4*1]   ^ t02;
-       t05          = in[4*0]   ^ in[4*3];
-       t06          = t04       & t03;
-       t07          = in[4*1]   & t01;
-       out[4*2]   = t05       ^ t06;
-       t09          = in[4*0]   ^ t03;
-       out[4*0]   = t07       ^ t03;
-       t11          = out[4*0]   | t05;
-       t12          = t09       & t11;
-       t13          = in[4*0]   & out[4*2];
-       t14          = t01       ^ t05;
-       out[4*1]   = in[4*1]   ^ t12;
-       t16          = in[4*1]   | t13;
-       out[4*3]   = t14       ^ t16; 
-}
-
-/* S4:   1 15  8  3 12  0 11  6  2  5  4 10  9 14  7 13 */
-
-/* depth = 6,7,5,3, Total gates=19 */
-static void sb4(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t12, t13, t14, t15, t16, t01;
-       t01          = in[4*0]   | in[4*1];
-       t02          = in[4*1]   | in[4*2];
-       t03          = in[4*0]   ^ t02;
-       t04          = in[4*1]   ^ in[4*3];
-       t05          = in[4*3]   | t03;
-       t06          = in[4*3]   & t01;
-       out[4*3]   = t03       ^ t06;
-       t08          = out[4*3]   & t04;
-       t09          = t04       & t05;
-       t10          = in[4*2]   ^ t06;
-       t11          = in[4*1]   & in[4*2];
-       t12          = t04       ^ t08;
-       t13          = t11       | t03;
-       t14          = t10       ^ t09;
-       t15          = in[4*0]   & t05;
-       t16          = t11       | t12;
-       out[4*2]   = t13       ^ t08;
-       out[4*1]   = t15       ^ t16;
-       out[4*0]   =     ~ t14; 
-}
-
-/* InvS4:   5  0  8  3 10  9  7 14  2 12 11  6  4 15 13  1 */
-
-/* depth = 6,4,7,3, Total gates=17 */
-static void sb4_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;
-       t01          = in[4*1]   | in[4*3];
-       t02          = in[4*2]   | in[4*3];
-       t03          = in[4*0]   & t01;
-       t04          = in[4*1]   ^ t02;
-       t05          = in[4*2]   ^ in[4*3];
-       t06          =     ~ t03;
-       t07          = in[4*0]   & t04;
-       out[4*1]   = t05       ^ t07;
-       t09          = out[4*1]   | t06;
-       t10          = in[4*0]   ^ t07;
-       t11          = t01       ^ t09;
-       t12          = in[4*3]   ^ t04;
-       t13          = in[4*2]   | t10;
-       out[4*3]   = t03       ^ t12;
-       t15          = in[4*0]   ^ t04;
-       out[4*2]   = t11       ^ t13;
-       out[4*0]   = t15       ^ t09; 
-}
-
-/* S5:  15  5  2 11  4 10  9 12  0  3 14  8 13  6  7  1 */
-
-/* depth = 4,6,8,6, Total gates=17 */
-static void sb5(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t14, t01;
-       t01          = in[4*1]   ^ in[4*3];
-       t02          = in[4*1]   | in[4*3];
-       t03          = in[4*0]   & t01;
-       t04          = in[4*2]   ^ t02;
-       t05          = t03       ^ t04;
-       out[4*0]   =     ~ t05;
-       t07          = in[4*0]   ^ t01;
-       t08          = in[4*3]   | out[4*0];
-       t09          = in[4*1]   | t05;
-       t10          = in[4*3]   ^ t08;
-       t11          = in[4*1]   | t07;
-       t12          = t03       | out[4*0];
-       t13          = t07       | t10;
-       t14          = t01       ^ t11;
-       out[4*2]   = t09       ^ t13;
-       out[4*1]   = t07       ^ t08;
-       out[4*3]   = t12       ^ t14; 
-}
-
-/* InvS5:   8 15  2  9  4  1 13 14 11  6  5  3  7 12 10  0 */
-
-/* depth = 4,6,9,7, Total gates=17 */
-static void sb5_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;
-       t01          = in[4*0]   & in[4*3];
-       t02          = in[4*2]   ^ t01;
-       t03          = in[4*0]   ^ in[4*3];
-       t04          = in[4*1]   & t02;
-       t05          = in[4*0]   & in[4*2];
-       out[4*0]   = t03       ^ t04;
-       t07          = in[4*0]   & out[4*0];
-       t08          = t01       ^ out[4*0];
-       t09          = in[4*1]   | t05;
-       t10          =     ~ in[4*1];
-       out[4*1]   = t08       ^ t09;
-       t12          = t10       | t07;
-       t13          = out[4*0]   | out[4*1];
-       out[4*3]   = t02       ^ t12;
-       t15          = t02       ^ t13;
-       t16          = in[4*1]   ^ in[4*3];
-       out[4*2]   = t16       ^ t15; 
-}
-
-/* S6:   7  2 12  5  8  4  6 11 14  9  1 15 13  3 10  0 */
-
-/* depth = 8,3,6,3, Total gates=19 */
-static void sb6(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t15, t17, t18, t01;
-       t01          = in[4*0]   & in[4*3];
-       t02          = in[4*1]   ^ in[4*2];
-       t03          = in[4*0]   ^ in[4*3];
-       t04          = t01       ^ t02;
-       t05          = in[4*1]   | in[4*2];
-       out[4*1]   =     ~ t04;
-       t07          = t03       & t05;
-       t08          = in[4*1]   & out[4*1];
-       t09          = in[4*0]   | in[4*2];
-       t10          = t07       ^ t08;
-       t11          = in[4*1]   | in[4*3];
-       t12          = in[4*2]   ^ t11;
-       t13          = t09       ^ t10;
-       out[4*2]   =     ~ t13;
-       t15          = out[4*1]   & t03;
-       out[4*3]   = t12       ^ t07;
-       t17          = in[4*0]   ^ in[4*1];
-       t18          = out[4*2]   ^ t15;
-       out[4*0]   = t17       ^ t18; 
-}
-
-/* InvS6:  15 10  1 13  5  3  6  0  4  9 14  7  2 12  8 11 */
-
-/* depth = 5,3,8,6, Total gates=19 */
-static void sb6_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;
-       t01          = in[4*0]   ^ in[4*2];
-       t02          =     ~ in[4*2];
-       t03          = in[4*1]   & t01;
-       t04          = in[4*1]   | t02;
-       t05          = in[4*3]   | t03;
-       t06          = in[4*1]   ^ in[4*3];
-       t07          = in[4*0]   & t04;
-       t08          = in[4*0]   | t02;
-       t09          = t07       ^ t05;
-       out[4*1]   = t06       ^ t08;
-       out[4*0]   =     ~ t09;
-       t12          = in[4*1]   & out[4*0];
-       t13          = t01       & t05;
-       t14          = t01       ^ t12;
-       t15          = t07       ^ t13;
-       t16          = in[4*3]   | t02;
-       t17          = in[4*0]   ^ out[4*1];
-       out[4*3]   = t17       ^ t15;
-       out[4*2]   = t16       ^ t14; 
-}
-
-/* S7:   1 13 15  0 14  8  2 11  7  4 12 10  9  3  5  6 */
-
-/* depth = 10,7,10,4, Total gates=19 */
-static void sb7(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t13, t14, t15, t16, t17, t01;
-       t01          = in[4*0]   & in[4*2];
-       t02          =     ~ in[4*3];
-       t03          = in[4*0]   & t02;
-       t04          = in[4*1]   | t01;
-       t05          = in[4*0]   & in[4*1];
-       t06          = in[4*2]   ^ t04;
-       out[4*3]   = t03       ^ t06;
-       t08          = in[4*2]   | out[4*3];
-       t09          = in[4*3]   | t05;
-       t10          = in[4*0]   ^ t08;
-       t11          = t04       & out[4*3];
-       out[4*1]   = t09       ^ t10;
-       t13          = in[4*1]   ^ out[4*1];
-       t14          = t01       ^ out[4*1];
-       t15          = in[4*2]   ^ t05;
-       t16          = t11       | t13;
-       t17          = t02       | t14;
-       out[4*0]   = t15       ^ t17;
-       out[4*2]   = in[4*0]   ^ t16; 
-}
-
-/* InvS7:   3  0  6 13  9 14 15  8  5 12 11  7 10  1  4  2 */
-
-/* depth = 9,7,3,3, Total gates=18 */
-static void sb7_inv(uint8_t* out, const uint8_t* in){
-       uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;
-       t01          = in[4*0]   & in[4*1];
-       t02          = in[4*0]   | in[4*1];
-       t03          = in[4*2]   | t01;
-       t04          = in[4*3]   & t02;
-       out[4*3]   = t03       ^ t04;
-       t06          = in[4*1]   ^ t04;
-       t07          = in[4*3]   ^ out[4*3];
-       t08          =     ~ t07;
-       t09          = t06       | t08;
-       t10          = in[4*1]   ^ in[4*3];
-       t11          = in[4*0]   | in[4*3];
-       out[4*1]   = in[4*0]   ^ t09;
-       t13          = in[4*2]   ^ t06;
-       t14          = in[4*2]   & t11;
-       t15          = in[4*3]   | out[4*1];
-       t16          = t01       | t10;
-       out[4*0]   = t13       ^ t15;
-       out[4*2]   = t14       ^ t16; 
-}
-
-typedef void(*sb_fpt)(uint8_t*, const uint8_t*);
-
-sb_fpt sf_tab[] PROGMEM = {
-       sb0, sb1, sb2, sb3, 
-       sb4, sb5, sb6, sb7
-};
-
-sb_fpt sinvf_tab[] PROGMEM = {
-       sb0_inv, sb1_inv, sb2_inv, sb3_inv, 
-       sb4_inv, sb5_inv, sb6_inv, sb7_inv
-};
-
-void sbox128(void * w, uint8_t box){
-       uint8_t i, buffer[16];
-       box &= 0x7;
-       
-       sb_fpt fp;
-       fp = (sb_fpt)pgm_read_word(&(sf_tab[box]));
-       for(i=0; i<4; ++i){
-               fp(buffer+i, (uint8_t*)w+i);
-       }
-       memcpy(w, buffer, 16);
-}
-
-void inv_sbox128(void * w, uint8_t box){
-       uint8_t i, buffer[16];
-       box &= 0x7;
-       
-       sb_fpt fp;
-       fp = (sb_fpt)pgm_read_word(&(sinvf_tab[box]));
-       for(i=0; i<4; ++i){
-               fp(buffer+i, (uint8_t*)w+i);
-       }
-       memcpy(w, buffer, 16);
-}
-
-
-
-
-
-
-
-
diff --git a/serpent-sboxes-fast.S b/serpent-sboxes-fast.S
deleted file mode 100644 (file)
index 9242272..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/* serpent-sboxes-fast.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* 
- * File:        serpent-sboxes-fast.S
- * Author:      Daniel Otte
- * Date:        2008-08-07
- * License:     GPLv3 or later
- * Description: Implementation of the serpent sbox function.
- * 
- */
-#include <avr/io.h>
-#include "avr-asm-macros.S"
-
-
-serpent_sbox_fast:
- .byte 0x33, 0x88, 0xFF, 0x11, 0xAA, 0x66, 0x55, 0xBB 
- .byte 0xEE, 0xDD, 0x44, 0x22, 0x77, 0x00, 0x99, 0xCC
- .byte 0xFF, 0xCC, 0x22, 0x77, 0x99, 0x00, 0x55, 0xAA
- .byte 0x11, 0xBB, 0xEE, 0x88, 0x66, 0xDD, 0x33, 0x44 
- .byte 0x88, 0x66, 0x77, 0x99, 0x33, 0xCC, 0xAA, 0xFF 
- .byte 0xDD, 0x11, 0xEE, 0x44, 0x00, 0xBB, 0x55, 0x22
- .byte 0x00, 0xFF, 0xBB, 0x88, 0xCC, 0x99, 0x66, 0x33 
- .byte 0xDD, 0x11, 0x22, 0x44, 0xAA, 0x77, 0x55, 0xEE
- .byte 0x11, 0xFF, 0x88, 0x33, 0xCC, 0x00, 0xBB, 0x66 
- .byte 0x22, 0x55, 0x44, 0xAA, 0x99, 0xEE, 0x77, 0xDD
- .byte 0xFF, 0x55, 0x22, 0xBB, 0x44, 0xAA, 0x99, 0xCC 
- .byte 0x00, 0x33, 0xEE, 0x88, 0xDD, 0x66, 0x77, 0x11
- .byte 0x77, 0x22, 0xCC, 0x55, 0x88, 0x44, 0x66, 0xBB 
- .byte 0xEE, 0x99, 0x11, 0xFF, 0xDD, 0x33, 0xAA, 0x00
- .byte 0x11, 0xDD, 0xFF, 0x00, 0xEE, 0x88, 0x22, 0xBB 
- .byte 0x77, 0x44, 0xCC, 0xAA, 0x99, 0x33, 0x55, 0x66
-
-serpent_sbox_inv_fast:
- .byte 0xDD, 0x33, 0xBB, 0x00, 0xAA, 0x66, 0x55, 0xCC 
- .byte 0x11, 0xEE, 0x44, 0x77, 0xFF, 0x99, 0x88, 0x22
- .byte 0x55, 0x88, 0x22, 0xEE, 0xFF, 0x66, 0xCC, 0x33 
- .byte 0xBB, 0x44, 0x77, 0x99, 0x11, 0xDD, 0xAA, 0x00
- .byte 0xCC, 0x99, 0xFF, 0x44, 0xBB, 0xEE, 0x11, 0x22 
- .byte 0x00, 0x33, 0x66, 0xDD, 0x55, 0x88, 0xAA, 0x77
- .byte 0x00, 0x99, 0xAA, 0x77, 0xBB, 0xEE, 0x66, 0xDD 
- .byte 0x33, 0x55, 0xCC, 0x22, 0x44, 0x88, 0xFF, 0x11
- .byte 0x55, 0x00, 0x88, 0x33, 0xAA, 0x99, 0x77, 0xEE 
- .byte 0x22, 0xCC, 0xBB, 0x66, 0x44, 0xFF, 0xDD, 0x11
- .byte 0x88, 0xFF, 0x22, 0x99, 0x44, 0x11, 0xDD, 0xEE 
- .byte 0xBB, 0x66, 0x55, 0x33, 0x77, 0xCC, 0xAA, 0x00
- .byte 0xFF, 0xAA, 0x11, 0xDD, 0x55, 0x33, 0x66, 0x00 
- .byte 0x44, 0x99, 0xEE, 0x77, 0x22, 0xCC, 0x88, 0xBB
- .byte 0x33, 0x00, 0x66, 0xDD, 0x99, 0xEE, 0xFF, 0x88 
- .byte 0x55, 0xCC, 0xBB, 0x77, 0xAA, 0x11, 0x44, 0x22
-                  
-/*
- * void ip(uint32_t *i, uint8_t *o){
- */
-/* 
- * param i is given in r24:r25
- * parma o is given in r22:r23
- */
-.global serpent_ip
-serpent_ip:
-       push_range 2, 17        
-       movw r26, r24
-       ldi r24, 16
-       clr r31
-       ldi r30, 2
-1:
-       ld r25, X+
-       st Z+, r25
-       dec r24
-       brne 1b
-       /* now the whole input is loaded in r2-r18 */
-       movw r26, r22
-       ldi r21, 4
-4:
-       ldi r20, 8      
-2:     
-       lsr r2
-       ror r19
-       lsr r6
-       ror 19
-       lsr r10
-       ror r19
-       lsr r14
-       ror 19
-       sbrc r20, 0
-       st X+, r19
-       dec r20
-       brne 2b
-       
-       ldi r20, 15
-       ldi r30, 2
-3:
-       ldd r19, Z+1
-       st Z+, r19
-       dec r20
-       brne 3b
-       
-       dec r21
-       brne 4b
-       pop_range 2, 17 
-       ret
-
-/*
- * void serpent_fp(uint32_t *i, uint8_t *o){
- */
-/* 
- * param i is given in r24:r25
- * parma o is given in r22:r23
- */
-.global serpent_fp
-serpent_fp:
-       movw r26, r24
-       movw r30, r22
-       ldi r18, 4
-1:     
-       ldi r19, 8 
-2:
-       sbrs r19, 0
-       ld r24, X+
-3:
-       lsr r24
-       ror r20
-       lsr r24
-       ror r21
-       lsr r24
-       ror r22
-       lsr r24
-       ror r23
-       dec r19
-       brne 2b
-       
-       st Z+, r20
-       std Z+3, r21
-       std Z+7, r22
-       std Z+11, r23
-       
-       dec r18
-       brne 1b         
-       ret
-       
-
-/*
- * void inv_sbox128(void * w, uint8_t box)
- */
-.global inv_sbox128 
-inv_sbox128:
-       andi r22, 0x07
-       ori  r22, 0x08
-       rjmp sbox128x_fast
-/*     
- * void sbox128(void * w, uint8_t box);
- */
-/*
- * param w   is passed in r24:r25
- * param box is passed in r22
- */
-.global sbox128 
-sbox128:
-       andi r22, 0x07
-sbox128x_fast:
-       stack_alloc 16
-       adiw r30, 1
-       push_ r24, r25, r22, r30, r31
-       movw r22, r30   /* Z points to the stack buffer */
-       rcall serpent_ip
-       pop_ r27, r26, r22
-       ldi r25, hi8(serpent_sbox_fast)
-       ldi r24, lo8(serpent_sbox_fast)
-       swap r22 /* r22 *= 16 */
-       add r24, r22
-       adc r25, r1
-       /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
-       ldi r22, 16
-1:     
-       movw r30, r24
-       ld r18, X
-       mov r20, r18
-       andi r18, 0x0f
-       add r30, r18
-       adc r31, r1
-       lpm r19, Z
-2:     
-       swap r20
-       andi r20, 0x0f
-       movw r30, r24
-       add r30, r20
-       adc r31, r1
-       lpm r21, Z
-3:     
-       andi r19, 0x0F
-       andi r21, 0xF0
-       or r19, r21
-       st X+, r19
-       dec r22
-       brne 1b
-       
-       pop_ r23, r22
-       movw r24, r26
-       sbiw r24, 16
-
-       rcall serpent_fp
-       
-       stack_free 16   
-       ret
-
-
-
-
-
-
-
-
diff --git a/serpent-sboxes-small.S b/serpent-sboxes-small.S
deleted file mode 100644 (file)
index 028fd77..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* serpent_sboxes.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* 
- * File:        serpent_sboxes.S
- * Author:      Daniel Otte
- * Date:        2008-08-07
- * License:     GPLv3 or later
- * Description: Implementation of the serpent sbox function.
- * 
- */
-#include <avr/io.h>
-#include "avr-asm-macros.S"
-
-
-serpent_sbox:
- .byte 0x83, 0x1F, 0x6A, 0xB5, 0xDE, 0x24, 0x07, 0xC9
- .byte 0xCF, 0x72, 0x09, 0xA5, 0xB1, 0x8E, 0xD6, 0x43 
- .byte 0x68, 0x97, 0xC3, 0xFA, 0x1D, 0x4E, 0xB0, 0x25
- .byte 0xF0, 0x8B, 0x9C, 0x36, 0x1D, 0x42, 0x7A, 0xE5
- .byte 0xF1, 0x38, 0x0C, 0x6B, 0x52, 0xA4, 0xE9, 0xD7
- .byte 0x5F, 0xB2, 0xA4, 0xC9, 0x30, 0x8E, 0x6D, 0x17
- .byte 0x27, 0x5C, 0x48, 0xB6, 0x9E, 0xF1, 0x3D, 0x0A
- .byte 0xD1, 0x0F, 0x8E, 0xB2, 0x47, 0xAC, 0x39, 0x65
-
-serpent_sbox_inv:
- .byte 0x3D, 0x0B, 0x6A, 0xC5, 0xE1, 0x74, 0x9F, 0x28
- .byte 0x85, 0xE2, 0x6F, 0x3C, 0x4B, 0x97, 0xD1, 0x0A
- .byte 0x9C, 0x4F, 0xEB, 0x21, 0x30, 0xD6, 0x85, 0x7A
- .byte 0x90, 0x7A, 0xEB, 0xD6, 0x53, 0x2C, 0x84, 0x1F
- .byte 0x05, 0x38, 0x9A, 0xE7, 0xC2, 0x6B, 0xF4, 0x1D
- .byte 0xF8, 0x92, 0x14, 0xED, 0x6B, 0x35, 0xC7, 0x0A
- .byte 0xAF, 0xD1, 0x35, 0x06, 0x94, 0x7E, 0xC2, 0xB8
- .byte 0x03, 0xD6, 0xE9, 0x8F, 0xC5, 0x7B, 0x1A, 0x24                  
-/*
- * void ip(uint32_t *i, uint8_t *o){
- */
-/* 
- * param i is given in r24:r25
- * parma o is given in r22:r23
- */
-.global serpent_ip
-serpent_ip:
-       push_range 2, 17        
-       movw r26, r24
-       ldi r24, 16
-       clr r31
-       ldi r30, 2
-1:
-       ld r25, X+
-       st Z+, r25
-       dec r24
-       brne 1b
-       /* now the whole input is loaded in r2-r18 */
-       movw r26, r22
-       ldi r21, 4
-4:
-       ldi r20, 8      
-2:     
-       lsr r2
-       ror r19
-       lsr r6
-       ror 19
-       lsr r10
-       ror r19
-       lsr r14
-       ror 19
-       sbrc r20, 0
-       st X+, r19
-       dec r20
-       brne 2b
-       
-       ldi r20, 15
-       ldi r30, 2
-3:
-       ldd r19, Z+1
-       st Z+, r19
-       dec r20
-       brne 3b
-       
-       dec r21
-       brne 4b
-       pop_range 2, 17 
-       ret
-
-/*
- * void serpent_fp(uint32_t *i, uint8_t *o){
- */
-/* 
- * param i is given in r24:r25
- * parma o is given in r22:r23
- */
-.global serpent_fp
-serpent_fp:
-       movw r26, r24
-       movw r30, r22
-       ldi r18, 4
-1:     
-       ldi r19, 8 
-2:
-       sbrs r19, 0
-       ld r24, X+
-3:
-       lsr r24
-       ror r20
-       lsr r24
-       ror r21
-       lsr r24
-       ror r22
-       lsr r24
-       ror r23
-       dec r19
-       brne 2b
-       
-       st Z+, r20
-       std Z+3, r21
-       std Z+7, r22
-       std Z+11, r23
-       
-       dec r18
-       brne 1b 
-       
-       ret
-/*
- * void inv_sbox128(void * w, uint8_t box)
- */
-.global inv_sbox128 
-inv_sbox128:
-       andi r22, 0x07
-       ori  r22, 0x08
-       rjmp sbox128x
-/*     
- * void sbox128(void * w, uint8_t box);
- */
-/*
- * param w   is passed in r24:r25
- * param box is passed in r22
- */
-.global sbox128 
-sbox128:
-       andi r22, 0x07
-
-/*     
- * void sbox128x(void * w, uint8_t box);
- */
-/*
- * param w   is passed in r24:r25
- * param box is passed in r22
- */
-.global sbox128x
-sbox128x:
-       stack_alloc 16
-       adiw r30, 1
-       push_ r24, r25, r22, r30, r31
-       movw r22, r30   /* Z points to the stack buffer */
-       rcall serpent_ip
-       pop_ r27, r26, r22
-       ldi r25, hi8(serpent_sbox)
-       ldi r24, lo8(serpent_sbox)
-       swap r22
-       lsr  r22 /* r22 *= 8 */
-       add r24, r22
-       adc r25, r1
-       /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
-       ldi r22, 16
-1:     
-       movw r30, r24
-       ld r18, X
-       mov r20, r18
-       andi r18, 0x0f
-       bst r18, 0
-       lsr r18
-       add r30, r18
-       adc r31, r1
-       lpm r19, Z
-       brtc 2f
-       swap r19
-2:     
-       swap r20
-       andi r20, 0x0f
-       bst r20, 0
-       lsr r20
-       movw r30, r24
-       add r30, r20
-       adc r31, r1
-       lpm r21, Z
-       brts 3f
-       swap r21
-3:     
-       andi r19, 0x0F
-       andi r21, 0xF0
-       or r19, r21
-       st X+, r19
-       dec r22
-       brne 1b
-       
-       pop_ r23, r22
-       movw r24, r26
-       sbiw r24, 16
-
-       rcall serpent_fp
-       
-       stack_free 16   
-       ret
-
-
-
-
-
diff --git a/serpent-sboxes.h b/serpent-sboxes.h
deleted file mode 100644 (file)
index c391edc..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* serpent-sboxes.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef SERPENTSBOXES_H_
-#define SERPENTSBOXES_H_
-
-#include <stdint.h>
-
-void sbox128(void * w, uint8_t box);
-void inv_sbox128(void * w, uint8_t box);
-
-
-#endif /*SERPENTSBOXES_H_*/
diff --git a/serpent-sboxes_c.c b/serpent-sboxes_c.c
deleted file mode 100644 (file)
index 3a59969..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* serpent-sboxes.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* serpent-sboxes.c
- * a non-bitsliced implementation of the serpent sboxes
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- */
-
-#include <stdint.h>
-#include <string.h> /* memset() */
-#include <avr/pgmspace.h>
-#include "serpent-sboxes.h"
-
-uint8_t sbox[] PROGMEM = {
- 0x38, 0xF1, 0xA6, 0x5B, 0xED, 0x42, 0x70, 0x9C,
- 0xFC, 0x27, 0x90, 0x5A, 0x1B, 0xE8, 0x6D, 0x34, 
- 0x86, 0x79, 0x3C, 0xAF, 0xD1, 0xE4, 0x0B, 0x52,
- 0x0F, 0xB8, 0xC9, 0x63, 0xD1, 0x24, 0xA7, 0x5E,
- 0x1F, 0x83, 0xC0, 0xB6, 0x25, 0x4A, 0x9E, 0x7D,
- 0xF5, 0x2B, 0x4A, 0x9C, 0x03, 0xE8, 0xD6, 0x71,
- 0x72, 0xC5, 0x84, 0x6B, 0xE9, 0x1F, 0xD3, 0xA0,
- 0x1D, 0xF0, 0xE8, 0x2B, 0x74, 0xCA, 0x93, 0x56,
-/* now the inverted sboxes */
- 0xD3, 0xB0, 0xA6, 0x5C, 0x1E, 0x47, 0xF9, 0x82,
- 0x58, 0x2E, 0xF6, 0xC3, 0xB4, 0x79, 0x1D, 0xA0,
- 0xC9, 0xF4, 0xBE, 0x12, 0x03, 0x6D, 0x58, 0xA7,
- 0x09, 0xA7, 0xBE, 0x6D, 0x35, 0xC2, 0x48, 0xF1,
- 0x50, 0x83, 0xA9, 0x7E, 0x2C, 0xB6, 0x4F, 0xD1,
- 0x8F, 0x29, 0x41, 0xDE, 0xB6, 0x53, 0x7C, 0xA0,
- 0xFA, 0x1D, 0x53, 0x60, 0x49, 0xE7, 0x2C, 0x8B,
- 0x30, 0x6D, 0x9E, 0xF8, 0x5C, 0xB7, 0xA1, 0x42
-};        
-         
-
-#define SHR_O(a) c=(a)&1; ((a) = (a)>>1)
-#define SHR_I(a) ((a) = (c?0x80:0x00)| ((a)>>1))
-
-static void serpent_ip(uint32_t *i, uint8_t *o){
-       uint8_t c; // carry 
-       uint8_t n,m;
-       memset(o, 0, 16);
-       for(n=0; n<16; ++n){
-               for(m=0; m<2; ++m){
-               SHR_O(i[0]);
-               SHR_I(o[n]);
-               SHR_O(i[1]);
-               SHR_I(o[n]);
-               SHR_O(i[2]);
-               SHR_I(o[n]);
-               SHR_O(i[3]);
-               SHR_I(o[n]);
-               }
-       }
-}
-
-#undef SHR_I
-#define SHR_I(a) ((a) = (c?0x80000000L:0x00L)| ((a)>>1)) /* we use 32-bit words here */
-
-static void serpent_fp(uint32_t *i, uint32_t *o){
-       uint8_t c; // carry 
-       uint8_t n,m;
-       memset(o, 0, 16);
-       for(n=0; n<4; ++n){
-               for(m=0; m<8; ++m){
-               SHR_O(i[n]);
-               SHR_I(o[0]);
-               SHR_O(i[n]);
-               SHR_I(o[1]);
-               SHR_O(i[n]);
-               SHR_I(o[2]);
-               SHR_O(i[n]);
-               SHR_I(o[3]);
-               }
-       }
-}
-
-/******************************************************************************/
-static void sbox128x(uint8_t box, void* w){
-       uint8_t sb[16];
-       uint8_t i,t,x;
-       box &= 0x0f;
-       /* load sbox */
-       for(i=0; i<8; ++i){
-               t = pgm_read_byte(sbox + box*8 + i);
-               sb[2*i+0]=t>>4;
-               sb[2*i+1]=t&0xf;
-       }
-       uint8_t o[16];
-       serpent_ip(w,o);
-       
-       for(i=0; i<16; ++i){
-               t = ((uint8_t*)o)[i];
-               x = sb[t>>4];
-               x <<= 4;
-               x |= sb[t&0xf];
-               ((uint8_t*)o)[i] = x;
-       }
-       serpent_fp((uint32_t*)o, w);
-}
-
-void sbox128(void * w, uint8_t box){
-       sbox128x(box&0x7, w);
-}
-
-
-void inv_sbox128(void * w, uint8_t box){
-       sbox128x(((box&0x7)|0x8), w);
-}
-
-
-
diff --git a/serpent.c b/serpent.c
deleted file mode 100644 (file)
index 40ccecd..0000000
--- a/serpent.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* serpent.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* serpent.c
- * a bitsliced implementation of the serpent cipher for avr microcontrollers
- * author: Daniel Otte 
- * email:  daniel.otte@rub.de
- * license: GPLv3
- */
-
-#include <stdint.h>
-#include <string.h> /* memset() */
-#include <avr/pgmspace.h>
-#include "memxor.h"
-#include "serpent.h"
-#include "serpent-sboxes.h"
-
-/******************************************************************************/
-
-uint32_t rotl32(uint32_t a, uint8_t n){
-       return ((a<<n) | (a>>(32-n)));
-}
-
-
-uint32_t rotr32(uint32_t a, uint8_t n){
-       return ((a>>n) | (a<<(32-n)));
-}
-
-
-#define X0 (((uint32_t*)b)[0])
-#define X1 (((uint32_t*)b)[1])
-#define X2 (((uint32_t*)b)[2])
-#define X3 (((uint32_t*)b)[3])
-
-static void serpent_lt(uint8_t *b){
-       X0 = rotl32(X0, 13);
-       X2 = rotl32(X2,  3);
-       X1 ^= X0 ^ X2;
-       X3 ^= X2 ^ (X0 << 3);
-       X1 = rotl32(X1, 1);
-       X3 = rotl32(X3, 7);
-       X0 ^= X1 ^ X3;
-       X2 ^= X3 ^ (X1 << 7);
-       X0 = rotl32(X0, 5);
-       X2 = rotr32(X2, 10);
-}
-
-static void serpent_inv_lt(uint8_t *b){
-       X2 = rotl32(X2, 10);
-       X0 = rotr32(X0, 5);
-       X2 ^= X3 ^ (X1 << 7);
-       X0 ^= X1 ^ X3;
-       X3 = rotr32(X3, 7);
-       X1 = rotr32(X1, 1);
-       X3 ^= X2 ^ (X0 << 3);
-       X1 ^= X0 ^ X2;
-       X2 = rotr32(X2,  3);
-       X0 = rotr32(X0, 13);
-}
-
-#define GOLDEN_RATIO 0x9e3779b9l
-
-static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
-       uint32_t ret;
-       ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
-       ret = rotl32(ret, 11);
-       return ret;
-} 
-
-void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx){
-       uint32_t buffer[8];
-       uint8_t i,j;
-       if(keysize_b<256){
-               /* keysize is less than 256 bit, padding needed */
-               memset(buffer, 0, 32);
-               memcpy(buffer, key, (keysize_b+7)/8);
-               ((uint8_t*)buffer)[keysize_b/8] |= 1<<(keysize_b%8);
-       } else {
-               /* keysize is 256 bit */
-               memcpy(buffer, key, 32); 
-       }
-       for(i=0; i<33; ++i){
-               for(j=0; j<4; ++j){
-                       ctx->k[i][j] = serpent_gen_w(buffer, i*4+j);
-                       memmove(buffer, &(buffer[1]), 7*4); /* shift buffer one to the "left" */
-                       buffer[7] = ctx->k[i][j];
-               }
-       }
-       for(i=0; i<33; ++i){
-               sbox128(ctx->k[i],3-i);
-       }
-}
-
-void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
-       uint8_t i;
-       for(i=0; i<31; ++i){
-               memxor(buffer, ctx->k[i], 16);
-               sbox128(buffer, i);
-               serpent_lt((uint8_t*)buffer);
-       }
-       memxor(buffer, ctx->k[i], 16);
-       sbox128(buffer, i);
-       ++i;
-       memxor(buffer, ctx->k[i], 16);
-}
-
-void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
-       int8_t i=32;
-       
-       memxor(buffer, ctx->k[i], 16);
-       --i;
-       inv_sbox128(buffer, i);
-       memxor((uint8_t*)buffer, ctx->k[i], 16);
-       --i;
-       for(; i>=0; --i){
-               serpent_inv_lt(buffer);
-               inv_sbox128(buffer, i);
-               memxor(buffer, ctx->k[i], 16);
-       }
-}
-
-
-
-
-
diff --git a/serpent.h b/serpent.h
deleted file mode 100644 (file)
index 84e4a87..0000000
--- a/serpent.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* serpent.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** \file   serpent.h
- * \author  Daniel Otte
- * \license GPLv3
- * \brief a implementation of the serpent cipher for avr microcontrollers
- */
-
-#ifndef SERPENT_H_
-#define SERPENT_H_
-
-#include <stdint.h>
-
-typedef uint32_t serpent_subkey_t[4];
-
-typedef struct serpent_ctx_st {
-       serpent_subkey_t k[33];
-}  serpent_ctx_t;
-
-#define SERPENT_KEY128 128
-#define SERPENT_KEY192 192
-#define SERPENT_KEY256 256
-
-
-/* key must be 256bit (32 byte) large! */
-void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx);
-void serpent_enc(void* buffer, const serpent_ctx_t* ctx);
-void serpent_dec(void* buffer, const serpent_ctx_t* ctx);
-
-
-#endif /*SERPENT_H_*/
diff --git a/serpent/memxor.S b/serpent/memxor.S
new file mode 100644 (file)
index 0000000..a32058b
--- /dev/null
@@ -0,0 +1,66 @@
+/* memxor.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File:        memxor.S
+ * Author:      Daniel Otte
+ * Date:        2008-08-07
+ * License:     GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+  * param dest is passed in r24:r25
+  * param src  is passed in r22:r23
+  * param n    is passed in r20:r21
+  */
+.global memxor
+memxor:
+       movw r30, r24
+       movw r26, r22
+       movw r24, r20
+       adiw r24, 0
+       breq 2f
+1:
+       ld r20, X+
+       ld r21, Z
+       eor r20, r21
+       st Z+, r20
+       sbiw r24, 1
+       brne 1b
+2:
+       ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/serpent/memxor.h b/serpent/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/serpent/serpent-asm.S b/serpent/serpent-asm.S
new file mode 100644 (file)
index 0000000..f5f7cc5
--- /dev/null
@@ -0,0 +1,754 @@
+/* serpent_asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* 
+ * File:        serpent_sboxes.S
+ * Author:      Daniel Otte
+ * Date:        2008-08-07
+ * License:     GPLv3 or later
+ * Description: Implementation of the serpent sbox function.
+ * 
+ */
+#include <avr/io.h>
+#include "avr-asm-macros.S"
+
+/*
+static void serpent_lt(uint8_t *b){
+       X0 = rotl32(X0, 13);
+       X2 = rotl32(X2,  3);
+       X1 ^= X0 ^ X2;
+       X3 ^= X2 ^ (X0 << 3);
+       X1 = rotl32(X1, 1);
+       X3 = rotl32(X3, 7);
+       X0 ^= X1 ^ X3;
+       X2 ^= X3 ^ (X1 << 7);
+       X0 = rotl32(X0, 5);
+       X2 = rotr32(X2, 10);
+}
+*/
+
+#if 0
+A0 =  4
+A1 =  5
+A2 =  6
+A3 =  7
+B0 =  8
+B1 =  9
+B2 = 10
+B3 = 11
+C0 = 12
+C1 = 13
+C2 = 14
+C3 = 15
+D0 = 16
+D1 = 17
+D2 = 18
+D3 = 19
+T0 = 20
+T1 = 21
+T2 = 22
+T3 = 23
+
+serpent_lt:
+       push_range 4, 17
+       movw r26, r24
+       ld A2, X+
+       ld A3, X+
+       ld A0, X+
+       ld A1, X+
+       ldi r20, 3
+       mov r0, A0
+1:     
+       lsr r0
+       ror A3
+       ror A2
+       ror A1
+       ror A0
+       dec r20
+       brne 1b
+       ld B0, X+
+       ld B1, X+
+       ld B2, X+
+       ld B3, X+
+       
+       ld C2, X+
+       ld C3, X+
+       ld C0, X+
+       ld C1, X+
+       ldi r20, 3
+       mov r0, C0
+1:     
+       lsr r0
+       ror C3
+       ror C2
+       ror C1
+       ror C0
+       dec r20
+       brne 1b
+
+       ld D0, X+
+       ld D1, X+
+       ld D2, X+
+       ld D3, X+
+       /* X1 ^= X0 ^ X2; */
+       eor B0, A0
+       eor B0, C0
+       eor B1, A1
+       eor B1, C1
+       eor B2, A2
+       eor B2, C2
+       eor B3, A3
+       eor B3, C3
+       /* X3 ^= X2 ^ (X0 << 3); */
+       mov T0, A0
+       mov T1, A1
+       mov T2, A2
+       mov T3, A3
+       ldi r24, 3
+1:
+       lsl T0
+       rol T1
+       rol T2
+       rol T3
+       dec r24
+       brne 1b
+       eor C0, B0
+       eor C0, T0
+       eor C1, B1
+       eor C1, T1
+       eor C2, B2
+       eor C2, T2
+       eor C3, B3
+       eor C3, T3
+       /*      X1 = rotl32(X1, 1); */
+       mov r0, B3
+       lsl r0
+       rol B0
+       rol B1
+       rol B2
+       rol B3
+       /* X3 = rotl32(X3, 7); */
+       mov r0, D3
+       mov D3, D2
+       mov D2, D1
+       mov D1, D0
+       mov D0, r0
+       lsr r0
+       ror D3
+       ror D2
+       ror D1
+       ror D0
+       /*      X0 ^= X1 ^ X3; */
+       eor A0, B0
+       eor A0, D0
+       eor A1, B1
+       eor A1, D1
+       eor A2, B2
+       eor A2, D2
+       eor A3, B3
+       eor A3, D3
+       /*  X2 ^= X3 ^ (X1 << 7); */
+       mov T1, B0
+       mov T2, B1
+       mov T3, B2
+       clr T0
+       mov r0, B3
+       lsr r0
+       ror T2
+       ror T1
+       ror T0 
+       eor C0, D0
+       eor C0, T0
+       eor C1, D1
+       eor C1, T1
+       eor C2, D2
+       eor C2, T2
+       eor C3, D3
+       eor C3, T3
+       /*      X0 = rotl32(X0, 5); */
+       ldi r24, 5
+       mov r0, A3
+1:     
+       lsl r0
+       rol A0
+       rol A1
+       rol A2
+       rol A3
+       dec r24
+       brne 1b
+       /* X2 = rotr32(X2, 10); */
+       mov r0, C0
+       mov C0, C1
+       mov C1, C2
+       mov C2, C3      
+       mov C3, r0
+       ldi r24, 2
+1:
+       lsr r0
+       ror C2
+       ror C1
+       ror C0
+       ror C3  
+       dec r24
+       brne 1b
+       
+       clr r31
+       ldi r30, D3+1
+       ldi r24, 16
+1:
+       ld r0, -Z
+       st -X, r0       
+       dec r24
+       brne 1b
+       
+       pop_range 4, 17
+       ret
+#endif
+
+T0 = 22
+T1 = 23
+T2 = 24
+T3 = 25
+TT = 21
+/* rotate the data word (4 byte) pointed to by X by r20 bits to the right */
+memrotr32:
+       ld T0, X+
+       ld T1, X+
+       ld T2, X+
+       ld T3, X+
+       mov TT, T0
+1:
+       lsr TT
+       ror T3
+       ror T2
+       ror T1
+       ror T0
+       dec r20
+       brne 1b
+       st -X, T3
+       st -X, T2
+       st -X, T1
+       st -X, T0
+       ret
+       
+/* rotate the data word (4 byte) pointed to by X by r20 bits to the left */
+memrotl32:
+       ld T0, X+
+       ld T1, X+
+       ld T2, X+
+       ld T3, X+
+       mov TT, T3
+1:
+       lsl TT
+       rol T0
+       rol T1
+       rol T2
+       rol T3
+       dec r20
+       brne 1b
+       st -X, T3
+       st -X, T2
+       st -X, T1
+       st -X, T0
+       ret
+
+/* xor the dataword (4 byte) pointed by Z into X */    
+memeor32:
+  ldi T2, 4
+1:  
+  ld T0, X             
+  ld T1, Z+
+  eor T0, T1
+  st X+, T0
+  dec T2
+  brne 1b
+  ret
+
+serpent_lt:
+        /* X0 := X0 <<< 13 */
+       movw r26, r24
+       ldi r20, 7
+       rcall memrotl32
+       ldi r20, 6
+       rcall memrotl32
+       /* X2 := X2 <<< 3 */
+       adiw r26, 8
+       ldi r20, 3
+       rcall memrotl32
+       /* X1 ^= X2 */
+       movw r30, r26
+       sbiw r26, 4
+       rcall memeor32
+       /* X1 ^= X0 */
+       sbiw r26, 4
+       sbiw r30, 12
+       rcall memeor32
+       /* X3 ^= X2 */
+       movw r30, r26
+       adiw r26, 4
+       rcall memeor32
+       /* T := X0 */
+       sbiw r26, 16
+       ld r18, X+
+       ld r19, X+
+       ld r20, X+
+       ld r21, X+
+       /* T := T<<3 */
+       ldi r22, 3
+1:
+       lsl r18
+       rol r19
+       rol r20
+       rol r21
+       dec r22
+       brne 1b
+       clr r31 
+       /* X3 ^= T */
+       adiw r26, 8
+       ldi r30, 18
+       rcall memeor32
+       /* X1 := X1<<<1 */
+       sbiw r26, 12
+       ldi r20, 1
+       rcall memrotl32
+       /* X3 := X3<<<7 */
+       adiw r26, 8
+       ldi r20, 7
+       rcall memrotl32
+       /* X0 ^= X3 */
+       movw r30, r26
+       sbiw r26, 12
+       rcall memeor32
+       /* X0 ^= X1 */
+       movw r30, r26
+       sbiw r26, 4
+       rcall memeor32
+       /* X2 ^= X3 */
+       adiw r26, 4
+       adiw r30, 4
+       rcall memeor32
+       /* T := X1<<<8 */
+       sbiw r26, 8
+       ld r19, X+
+       ld r20, X+
+       ld r21, X+
+       ld r18, X+
+       /* T := T>>>1; T&=0xfffffff8 */
+       lsr r18
+       ror r21
+       ror r20
+       ror r19
+       clr r18
+       ror r18
+       clr r31
+       ldi r30, 18
+       /* X2 ^= T */
+       rcall memeor32
+       /* X0 := X0 <<< 5 */
+       sbiw r26, 12
+       ldi r20, 5
+       rcall memrotl32
+       /* X3 := X3 >>> 10 */
+       adiw r26, 8
+       ldi r20, 7
+       rcall memrotr32
+       ldi r20, 3
+       rcall memrotr32
+       ret
+
+serpent_inv_lt:
+        /* X0 := X0 >>> 5 */
+       movw r26, r24
+       ldi r20, 5
+       rcall memrotr32
+       /* X2 := X2 <<< 10 */
+       adiw r26, 8
+       ldi r20, 7
+       rcall memrotl32
+       ldi r20, 3
+       rcall memrotl32
+       /* X2 ^= X3 */
+       movw r30, r26
+       adiw r30, 4
+       rcall memeor32
+       sbiw r26, 4
+       sbiw r30, 12
+       /* T := X1<<7 */
+       ld r19, Z+
+       ld r20, Z+
+       ld r21, Z+
+       ld r18, Z+
+       lsr r18
+       ror r21
+       ror r20
+       ror r19
+       clr r18
+       ror r18
+    clr r31
+    /* X2 ^= T */
+    ldi r30, 18
+    rcall memeor32
+    /* X0 ^= X1 */
+    sbiw r26, 12
+    movw r30, r26
+    adiw r30, 4
+    rcall memeor32
+    /* X0 ^= X3 */
+    sbiw r26, 4
+    adiw r30, 4
+    rcall memeor32
+    /* X1 := X1>>>1 */
+    ldi r20, 1
+       rcall memrotr32
+       /* X3 := X3>>>7 */
+       adiw r26, 8
+       ldi r20, 7
+       rcall memrotr32
+       /* X3 ^= X2 */
+       sbiw r30, 8
+       rcall memeor32
+       sbiw r26, 4
+       /* T:= X0<<3 */
+       sbiw r30, 12
+       ld r18, Z+
+       ld r19, Z+
+       ld r20, Z+
+       ld r21, Z+
+       ldi r24, 3
+1:
+       lsl r18
+       rol r19
+       rol r20
+       rol r21
+       dec r24
+       brne 1b
+       /* X3 ^= T */
+       clr r31
+       ldi r30, 18
+       rcall memeor32
+       /* X1 ^= X0 */
+       sbiw r26, 12
+       movw r30, r26
+       sbiw r30, 4
+       rcall memeor32
+       /* X1 ^= X2 */
+       movw r26, r30
+       adiw r30, 4
+       rcall memeor32
+       /* X2 := X2 >>> 3 */
+       ldi r20, 3
+       rcall memrotr32
+       /* X0 := X0 >>> 13 */
+       sbiw r26, 8
+       ldi r20, 7
+       rcall memrotr32
+       ldi r20, 6
+       rcall memrotr32
+       ret
+
+/*
+#define GOLDEN_RATIO 0x9e3779b9l
+
+static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
+       uint32_t ret;
+       ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
+       ret = rotl32(ret, 11);
+       return ret;
+}
+*/
+/*
+ * param b is passed in r24:r25
+ * param i is passed in r22
+ * return value is returned in r22.r23.r24.r25
+ */
+ /* trashes:
+  *  r20-r25, r30-r31
+  */
+serpent_gen_w:
+       movw r30, r24
+       /* ^i^b[0]*/
+    ld r21, Z+
+    eor r22, r21
+    ld r23, Z+
+    ld r24, Z+
+    ld r25, Z+
+    /* ^b[3]^b[5]^[b7] */
+    adiw r30, 4
+    ldi r20, 3
+1:    
+    adiw r30, 4
+    ld r21, Z+
+    eor r22, r21
+    ld r21, Z+
+    eor r23, r21
+    ld r21, Z+
+    eor r24, r21
+    ld r21, Z+
+    eor r25, r21
+       dec r20
+       brne 1b
+       /* ^0x9e3779b9l */
+       ldi r21, 0xb9
+       eor r22, r21
+       ldi r21, 0x79
+       eor r23, r21
+       ldi r21, 0x37
+       eor r24, r21
+       ldi r21, 0x9e
+       eor r25, r21
+       /* <<<11 */
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       mov r21, r25
+       ldi r20, 3
+1:
+       lsl r21
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       dec r20
+       brne 1b
+       ret
+
+/*
+ * void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx)
+ */
+/*
+ * param key     is passed in r24:r25
+ * param keysize is passed in r22:r23
+ * param ctx     is passed in r20:r21
+ */
+.global serpent_init
+serpent_init:
+    stack_alloc 32
+    adiw r30, 1
+       push_ r30, r31
+    movw r26, r22
+    adiw r26, 7
+    tst r27
+    breq 1f
+       ldi r26, 32
+       rjmp 2f
+1:
+       lsr r26
+       lsr r26
+       lsr r26
+2:     
+       mov r22, r26
+       bst r22, 5 /* store in T if we have to do the "append 1 thing"*/
+       ldi r27, 32
+3:     /* set buffer to zero */
+       st Z+, r1
+       dec r27
+       brne 3b
+       
+       movw r26, r24 /* X points to the key */
+       sbiw r30, 32
+       tst r22
+       breq 5f /* if keylength_b==0 */
+4:     /* copy keybytes to buffer */
+       ld r19, X+
+       st Z+, r19
+       dec r22
+       brne 4b
+5:
+       brts 7f /* if keylength_b == 256 */
+       ldi r18, 0x01
+       andi r22, 0x07
+       brne 6f
+       st Z, r18
+       rjmp 7f
+6:     /* shift the one to the right position */
+       lsl r18
+       dec r22
+       brne 6b
+       or r18, r19
+       st -Z, r18
+7: /* post "appending 1 thing" buffer is ready for subkey generation */
+       movw r26, r20  /* X points to the context */
+       
+       pop_ r19, r18 /* r18:r19 points to the buffer */
+       push r16
+       clr r16
+8:
+       movw r24, r18
+       mov  r22, r16
+       rcall serpent_gen_w
+       movw r30, r18
+       ldi r20, 7*4
+1: /* the memmove */
+       ldd r0, Z+4
+       st Z+, r0
+       dec r20
+       brne 1b
+  /* store new word in buffer and context */   
+       st Z+, r22
+       st Z+, r23
+       st Z+, r24
+       st Z+, r25
+       st X+, r22
+       st X+, r23
+       st X+, r24
+       st X+, r25
+       
+       inc r16
+       cpi r16, 132
+       brne 8b 
+       
+       push_ r28, r29
+       movw r28, r26
+       subi r28, lo8(132*4)
+       sbci r29, hi8(132*4)
+       ldi r16, 33
+2:
+       movw r24, r28
+       adiw r28, 16
+       ldi r22, 2
+       add r22, r16
+       rcall sbox128
+       dec r16
+       brne 2b
+       pop_ r29, r28, r16
+       stack_free 32
+       ret
+
+/*
+ * void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
+ */
+/*
+ * param buffer is passed in r24:r25
+ * param ctx    is passed in r22:r23
+ */
+.global serpent_enc
+serpent_enc:
+
+       push_ r12, r13, r14, r15, r16 
+       clr r16
+       movw r14, r24
+       movw r12, r22
+1:
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       add r12, r20
+       adc r13, r1
+       clr r21
+       rcall memxor
+       movw r24, r14
+       mov r22, r16
+       rcall sbox128
+       movw r24, r14
+       rcall serpent_lt
+       
+       inc r16
+       cpi r16, 31
+       brne 1b
+       
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       add r12, r20
+       adc r13, r1
+       clr r21
+       rcall memxor
+       movw r24, r14
+       mov r22, r16
+       rcall sbox128
+       
+       inc r16
+       movw r24, r14
+       movw r22, r12
+       ldi r20, 16
+       clr r21
+       pop_ r16, r15, r14, r13, r12
+       rjmp memxor
+
+/*
+ * void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
+ */
+/*
+ * param buffer is passed in r24:r25
+ * param ctx    is passed in r22:r23
+ */
+.global serpent_dec
+serpent_dec:
+       push_ r12, r13, r14, r15, r16 
+       movw r14, r24
+//     ldi r16, lo8(32*16)
+//     add r22, r16
+       ldi r16, hi8(32*16)
+       add r23, r16
+       movw r12, r22
+       ldi r20, 16
+       clr r21
+       rcall memxor
+       
+       movw r24, r14
+       ldi r22, 31
+       call inv_sbox128
+       
+       movw r24, r14
+       ldi r20, 16
+       sub r12, r20
+       sbc r13, r1
+       movw r22, r12
+       clr r21
+       rcall memxor
+       ldi r16, 31
+1:
+       dec r16
+       movw r24, r14
+       rcall serpent_inv_lt
+       movw r24, r14
+       mov r22, r16
+       rcall inv_sbox128
+       movw r24, r14
+       ldi r20, 16
+       sub r12, r20
+       sbc r13, r1
+       movw r22, r12
+       clr r21
+       rcall memxor
+       
+       tst r16
+       brne 1b
+       pop_ r16, r15, r14, r13, r12
+       ret     
+       
+       
+       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/serpent/serpent-sboxes-bitslice-asm.S b/serpent/serpent-sboxes-bitslice-asm.S
new file mode 100644 (file)
index 0000000..4e0d7db
--- /dev/null
@@ -0,0 +1,854 @@
+/* serpent-sboxes-bitslice.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* serpent-sboxes.c
+ * a bitsliced implementation of the serpent sboxes
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ */
+
+#include "avr-asm-macros.S"
+IN0  = 22
+IN1  = 23
+IN2  = 24
+IN3  = 25
+OUT0 = 18
+OUT1 = 19
+OUT2 = 20
+OUT3 = 21
+T00 =  2
+T00 =  3
+T01 =  4
+T02 =  5
+T03 =  6
+T04 =  7
+T05 =  8
+T06 =  9
+T07 = 10
+T08 = 11
+T09 = 12
+T10 = 13
+T11 = 14
+T12 = 15
+T13 = 16
+T14 = 17
+T15 = 26
+T16 = 27
+T17 =  0
+
+/* S0:   3  8 15  1 10  6  5 11 14 13  4  2  7  0  9 12 */
+
+/* depth = 5,7,4,2, Total gates=18 */
+sb0:
+    mov T00, IN1
+    eor T00, IN2
+    mov T01, IN0
+    or  T01, IN3
+    mov T02, IN0
+    eor T02, IN1
+    mov OUT3, T01
+    eor OUT3, T00
+    mov T04, IN2
+    or  T04, OUT3
+    mov T05, IN0
+    eor T05, IN3
+    mov T06, IN1
+    or  T06, IN2
+    mov T07, IN3
+    and T07, T04
+    mov T08, T02
+    and T08, T06
+    mov OUT2, T08
+    eor OUT2, T07
+    mov T10, T08
+    and T10, OUT2
+    mov T11, IN2
+    eor T11, IN3
+    mov T12, T06
+    eor T12, T10
+    mov T13, IN1
+    and T13, T05
+    mov T14, T05
+    eor T14, T12
+       mov OUT0, T14
+       com OUT0
+       mov T16, OUT0
+    eor T16, T13
+    mov OUT1, T11
+    eor OUT1, T16
+       ret
+
+       
+/* InvS0:  13  3 11  0 10  6  5 12  1 14  4  7 15  9  8  2 */
+
+/* depth = 8,4,3,6, Total gates=19 */
+sb0_inv:
+    mov T00, IN2
+    eor T00, IN3
+    mov T01, IN0
+    or  T01, IN1
+    mov T02, IN1
+    or  T02, IN2
+    mov T03, IN2
+    and T03, T00
+    mov T04, T01
+    eor T04, T00
+    mov T05, IN0
+    or  T05, T03
+       mov OUT2, T04
+       com OUT2
+    mov T07, IN1
+    eor T07, IN3
+    mov T08, T02
+    and T08, T07
+    mov T09, IN3
+    or  T09, OUT2
+    mov OUT1, T08
+    eor OUT1, T05
+    mov T11, IN0
+    or  T11, T04
+    mov T12, OUT1
+    eor T12, T11
+    mov T13, T02
+    eor T13, T09
+    mov T14, IN0
+    eor T14, IN2
+    mov OUT3, T13
+    eor OUT3, T12
+    mov T16, T04
+    and T16, T12
+    mov T17, T13
+    or  T17, T16
+    mov OUT0, T14
+    eor OUT0, T17
+       ret
+
+
+/* S1:  15 12  2  7  9  0  5 10  1 11 14  8  6 13  3  4 */
+
+/* depth = 10,7,3,5, Total gates=18 */
+sb1:
+    mov T00, IN0
+    or  T00, IN3
+    mov T01, IN2
+    eor T01, IN3
+       mov T02, IN1
+       com T02
+    mov T03, IN0
+    eor T03, IN2
+    mov T04, IN0
+    or  T04, T02
+    mov T05, IN3
+    and T05, T03
+    mov T06, T00
+    and T06, T01
+    mov T07, IN1
+    or  T07, T05
+    mov OUT2, T01
+    eor OUT2, T04
+    mov T09, T06
+    eor T09, T07
+    mov T10, T00
+    eor T10, T09
+    mov T11, OUT2
+    eor T11, T10
+    mov T12, IN1
+    and T12, IN3
+       mov OUT3, T09
+       com OUT3
+    mov OUT1, T12
+    eor OUT1, T11
+    mov T15, T09
+    or  T15, OUT1
+    mov T16, T04
+    and T16, T15
+    mov OUT0, IN2
+    eor OUT0, T16
+       ret
+
+
+/* InvS1:   5  8  2 14 15  6 12  3 11  4  7  9  1 13 10  0 */
+
+/* depth = 7,4,5,3, Total gates=18 */
+sb1_inv:
+    mov T00, IN0
+    eor T00, IN1
+    mov T01, IN1
+    or  T01, IN3
+    mov T02, IN0
+    and T02, IN2
+    mov T03, IN2
+    eor T03, T01
+    mov T04, IN0
+    or  T04, T03
+    mov T05, T00
+    and T05, T04
+    mov T06, IN3
+    or  T06, T02
+    mov T07, IN1
+    eor T07, T05
+    mov T08, T06
+    eor T08, T05
+    mov T09, T03
+    or  T09, T02
+    mov T10, IN3
+    and T10, T07
+    mov OUT2, T08
+    com OUT2
+       mov OUT1, T09
+    eor OUT1, T10
+    mov T13, IN0
+    or  T13, OUT2
+    mov T14, T05
+    eor T14, OUT1
+    mov OUT3, T00
+    eor OUT3, T03
+    mov T16, IN2
+    eor T16, T14
+    mov OUT0, T13
+    eor OUT0, T16
+       ret
+
+/* S2:   8  6  7  9  3 12 10 15 13  1 14  4  0 11  5  2 */
+
+/* depth = 3,8,11,7, Total gates=16 */
+sb2:
+    mov T00, IN0
+    or  T00, IN2
+    mov T01, IN0
+    eor T01, IN1
+    mov T02, IN3
+    eor T02, T00
+    mov OUT0, T01
+    eor OUT0, T02
+    mov T04, IN2
+    eor T04, OUT0
+    mov T05, IN1
+    eor T05, T04
+    mov T06, IN1
+    or  T06, T04
+    mov T07, T00
+    and T07, T05
+    mov T08, T02
+    eor T08, T06
+    mov T09, T01
+    or  T09, T08
+    mov OUT1, T09
+    eor OUT1, T07
+    mov T11, IN0
+    or  T11, IN3
+    mov T12, T08
+    eor T12, OUT1
+    mov T13, IN1
+    eor T13, T12
+       mov OUT3, T08
+       com OUT3
+    mov OUT2, T11
+    eor OUT2, T13
+       ret
+
+/* InvS2:  12  9 15  4 11 14  1  2  0  3  6 13  5  8 10  7 */
+
+/* depth = 3,6,8,3, Total gates=18 */
+sb2_inv:
+    mov T00, IN0
+    eor T00, IN3
+    mov T01, IN2
+    eor T01, IN3
+    mov T02, IN0
+    and T02, IN2
+    mov T03, IN1
+    or  T03, T01
+    mov OUT0, T00
+    eor OUT0, T03
+    mov T05, IN0
+    or  T05, IN2
+    mov T06, IN3
+    or  T06, OUT0
+       mov T07, IN3
+       com T07
+    mov T08, IN1
+    and T08, T05
+    mov T09, T07
+    or  T09, T02
+    mov T10, IN1
+    and T10, T06
+    mov T11, T05
+    and T11, T01
+    mov OUT3, T08
+    eor OUT3, T09
+    mov OUT1, T11
+    eor OUT1, T10
+    mov T14, IN2
+    and T14, OUT3
+    mov T15, OUT0
+    eor T15, OUT1
+    mov T16, T09
+    eor T16, T14
+    mov OUT2, T15
+    eor OUT2, T16
+       ret
+
+/* S3:   0 15 11  8 12  9  6  3 13  1  2  4 10  7  5 14 */
+
+/* depth = 8,3,5,5, Total gates=18 */
+sb3:
+    mov T00, IN0
+    eor T00, IN2
+    mov T01, IN0
+    or  T01, IN3
+    mov T02, IN0
+    and T02, IN3
+    mov T03, T00
+    and T03, T01
+    mov T04, IN1
+    or  T04, T02
+    mov T05, IN0
+    and T05, IN1
+    mov T06, IN3
+    eor T06, T03
+    mov T07, IN2
+    or  T07, T05
+    mov T08, IN1
+    eor T08, T06
+    mov T09, IN3
+    and T09, T04
+    mov T10, T01
+    eor T10, T09
+    mov OUT3, T07
+    eor OUT3, T08
+    mov T12, IN3
+    or  T12, OUT3
+    mov T13, IN0
+    or  T13, T06
+    mov T14, IN1
+    and T14, T12
+    mov OUT2, T07
+    eor OUT2, T10
+    mov OUT0, T13
+    eor OUT0, T14
+    mov OUT1, T04
+    eor OUT1, T03
+       ret
+
+/* InvS3:   0  9 10  7 11 14  6 13  3  5 12  2  4  8 15  1 */
+
+/* depth = 3,6,4,4, Total gates=17 */
+sb3_inv:
+    mov T00, IN2
+    or  T00, IN3
+    mov T01, IN0
+    or  T01, IN3
+    mov T02, IN2
+    eor T02, T01
+    mov T03, IN1
+    eor T03, T01
+    mov T04, IN0
+    eor T04, IN3
+    mov T05, T03
+    and T05, T02
+    mov T06, IN1
+    and T06, T00
+    mov OUT2, T04
+    eor OUT2, T05
+    mov T08, IN0
+    eor T08, T02
+    mov OUT0, T06
+    eor OUT0, T02
+    mov T10, OUT0
+    or  T10, T04
+    mov T11, T08
+    and T11, T10
+    mov T12, IN0
+    and T12, OUT2
+    mov T13, T00
+    eor T13, T04
+    mov OUT1, IN1
+    eor OUT1, T11
+    mov T15, IN1
+    or  T15, T12
+    mov OUT3, T13
+    eor OUT3, T15
+       ret
+
+/* S4:   1 15  8  3 12  0 11  6  2  5  4 10  9 14  7 13 */
+
+/* depth = 6,7,5,3, Total gates=19 */
+sb4:
+    mov T00, IN0
+    or  T00, IN1
+    mov T01, IN1
+    or  T01, IN2
+    mov T02, IN0
+    eor T02, T01
+    mov T03, IN1
+    eor T03, IN3
+    mov T04, IN3
+    or  T04, T02
+    mov T05, IN3
+    and T05, T00
+    mov OUT3, T02
+    eor OUT3, T05
+    mov T07, OUT3
+    and T07, T03
+    mov T08, T03
+    and T08, T04
+    mov T09, IN2
+    eor T09, T05
+    mov T10, IN1
+    and T10, IN2
+    mov T11, T03
+    eor T11, T07
+    mov T12, T10
+    or  T12, T02
+    mov T13, T09
+    eor T13, T08
+    mov T14, IN0
+    and T14, T04
+    mov T15, T10
+    or  T15, T11
+    mov OUT2, T12
+    eor OUT2, T07
+    mov OUT1, T14
+    eor OUT1, T15
+       mov OUT0, T13
+       com OUT0
+       ret
+
+/* InvS4:   5  0  8  3 10  9  7 14  2 12 11  6  4 15 13  1 */
+
+/* depth = 6,4,7,3, Total gates=17 */
+sb4_inv:
+    mov T00, IN1
+    or  T00, IN3
+    mov T01, IN2
+    or  T01, IN3
+    mov T02, IN0
+    and T02, T00
+    mov T03, IN1
+    eor T03, T01
+    mov T04, IN2
+    eor T04, IN3
+       mov T05, T02
+       com T05
+    mov T06, IN0
+    and T06, T03
+    mov OUT1, T04
+    eor OUT1, T06
+    mov T08, OUT1
+    or  T08, T05
+    mov T09, IN0
+    eor T09, T06
+    mov T10, T00
+    eor T10, T08
+    mov T11, IN3
+    eor T11, T03
+    mov T12, IN2
+    or  T12, T09
+    mov OUT3, T02
+    eor OUT3, T11
+    mov T14, IN0
+    eor T14, T03
+    mov OUT2, T10
+    eor OUT2, T12
+    mov OUT0, T14
+    eor OUT0, T08
+       ret
+
+/* S5:  15  5  2 11  4 10  9 12  0  3 14  8 13  6  7  1 */
+
+/* depth = 4,6,8,6, Total gates=17 */
+sb5:
+    mov T00, IN1
+    eor T00, IN3
+    mov T01, IN1
+    or  T01, IN3
+    mov T02, IN0
+    and T02, T00
+    mov T03, IN2
+    eor T03, T01
+    mov T04, T02
+    eor T04, T03
+       mov OUT0, T04
+       com OUT0
+    mov T06, IN0
+    eor T06, T00
+    mov T07, IN3
+    or  T07, OUT0
+    mov T08, IN1
+    or  T08, T04
+    mov T09, IN3
+    eor T09, T07
+    mov T10, IN1
+    or  T10, T06
+    mov T11, T02
+    or  T11, OUT0
+    mov T12, T06
+    or  T12, T09
+    mov T13, T00
+    eor T13, T10
+    mov OUT2, T08
+    eor OUT2, T12
+    mov OUT1, T06
+    eor OUT1, T07
+    mov OUT3, T11
+    eor OUT3, T13
+       ret
+
+/* InvS5:   8 15  2  9  4  1 13 14 11  6  5  3  7 12 10  0 */
+
+/* depth = 4,6,9,7, Total gates=17 */
+sb5_inv:
+    mov T00, IN0
+    and T00, IN3
+    mov T01, IN2
+    eor T01, T00
+    mov T02, IN0
+    eor T02, IN3
+    mov T03, IN1
+    and T03, T01
+    mov T04, IN0
+    and T04, IN2
+    mov OUT0, T02
+    eor OUT0, T03
+    mov T06, IN0
+    and T06, OUT0
+    mov T07, T00
+    eor T07, OUT0
+    mov T08, IN1
+    or  T08, T04
+       mov T09, IN1
+       com T09
+    mov OUT1, T07
+    eor OUT1, T08
+    mov T11, T09
+    or  T11, T06
+    mov T12, OUT0
+    or  T12, OUT1
+    mov OUT3, T01
+    eor OUT3, T11
+    mov T14, T01
+    eor T14, T12
+    mov T15, IN1
+    eor T15, IN3
+    mov OUT2, T15
+    eor OUT2, T14
+       ret
+
+/* S6:   7  2 12  5  8  4  6 11 14  9  1 15 13  3 10  0 */
+
+/* depth = 8,3,6,3, Total gates=19 */
+sb6:
+    mov T00, IN0
+    and T00, IN3
+    mov T01, IN1
+    eor T01, IN2
+    mov T02, IN0
+    eor T02, IN3
+    mov T03, T00
+    eor T03, T01
+    mov T04, IN1
+    or  T04, IN2
+       mov OUT1, T03
+       com OUT1
+    mov T06, T02
+    and T06, T04
+    mov T07, IN1
+    and T07, OUT1
+    mov T08, IN0
+    or  T08, IN2
+    mov T09, T06
+    eor T09, T07
+    mov T10, IN1
+    or  T10, IN3
+    mov T11, IN2
+    eor T11, T10
+    mov T12, T08
+    eor T12, T09
+       mov OUT2, T12
+       com OUT2
+    mov T14, OUT1
+    and T14, T02
+    mov OUT3, T11
+    eor OUT3, T06
+    mov T16, IN0
+    eor T16, IN1
+    mov T17, OUT2
+    eor T17, T14
+    mov OUT0, T16
+    eor OUT0, T17
+       ret
+
+/* InvS6:  15 10  1 13  5  3  6  0  4  9 14  7  2 12  8 11 */
+
+/* depth = 5,3,8,6, Total gates=19 */
+sb6_inv:
+    mov T00, IN0
+    eor T00, IN2
+       mov T01, IN2
+       com T01
+    mov T02, IN1
+    and T02, T00
+    mov T03, IN1
+    or  T03, T01
+    mov T04, IN3
+    or  T04, T02
+    mov T05, IN1
+    eor T05, IN3
+    mov T06, IN0
+    and T06, T03
+    mov T07, IN0
+    or  T07, T01
+    mov T08, T06
+    eor T08, T04
+    mov OUT1, T05
+    eor OUT1, T07
+       mov OUT0, T08
+       com OUT0
+    mov T11, IN1
+    and T11, OUT0
+    mov T12, T00
+    and T12, T04
+    mov T13, T00
+    eor T13, T11
+    mov T14, T06
+    eor T14, T12
+    mov T15, IN3
+    or  T15, T01
+    mov T16, IN0
+    eor T16, OUT1
+    mov OUT3, T16
+    eor OUT3, T14
+    mov OUT2, T15
+    eor OUT2, T13
+       ret
+
+/* S7:   1 13 15  0 14  8  2 11  7  4 12 10  9  3  5  6 */
+
+/* depth = 10,7,10,4, Total gates=19 */
+sb7:
+    mov T00, IN0
+    and T00, IN2
+       mov T01, IN3
+       com T01
+    mov T02, IN0
+    and T02, T01
+    mov T03, IN1
+    or  T03, T00
+    mov T04, IN0
+    and T04, IN1
+    mov T05, IN2
+    eor T05, T03
+    mov OUT3, T02
+    eor OUT3, T05
+    mov T07, IN2
+    or  T07, OUT3
+    mov T08, IN3
+    or  T08, T04
+    mov T09, IN0
+    eor T09, T07
+    mov T10, T03
+    and T10, OUT3
+    mov OUT1, T08
+    eor OUT1, T09
+    mov T12, IN1
+    eor T12, OUT1
+    mov T13, T00
+    eor T13, OUT1
+    mov T14, IN2
+    eor T14, T04
+    mov T15, T10
+    or  T15, T12
+    mov T16, T01
+    or  T16, T13
+    mov OUT0, T14
+    eor OUT0, T16
+    mov OUT2, IN0
+    eor OUT2, T15
+       ret
+
+/* InvS7:   3  0  6 13  9 14 15  8  5 12 11  7 10  1  4  2 */
+
+/* depth = 9,7,3,3, Total gates=18 */
+sb7_inv:
+    mov T00, IN0
+    and T00, IN1
+    mov T01, IN0
+    or  T01, IN1
+    mov T02, IN2
+    or  T02, T00
+    mov T03, IN3
+    and T03, T01
+    mov OUT3, T02
+    eor OUT3, T03
+    mov T05, IN1
+    eor T05, T03
+    mov T06, IN3
+    eor T06, OUT3
+    mov T07, T06
+    com T07
+    mov T08, T05
+    or  T08, T07
+    mov T09, IN1
+    eor T09, IN3
+    mov T10, IN0
+    or  T10, IN3
+    mov OUT1, IN0
+    eor OUT1, T08
+    mov T12, IN2
+    eor T12, T05
+    mov T13, IN2
+    and T13, T10
+    mov T14, IN3
+    or  T14, OUT1
+    mov T15, T00
+    or  T15, T09
+    mov OUT0, T12
+    eor OUT0, T14
+    mov OUT2, T13
+    eor OUT2, T15
+       ret
+
+sf_tab:
+.word sb0, sb1, sb2, sb3
+.word sb4, sb5, sb6, sb7
+
+sinvf_tab:
+.word sb0_inv, sb1_inv, sb2_inv, sb3_inv
+.word sb4_inv, sb5_inv, sb6_inv, sb7_inv
+
+/*
+.byte pm_lo8(sb0), pm_hi8(sb0)
+.byte pm_lo8(sb1), pm_hi8(sb1)
+.byte pm_lo8(sb2), pm_hi8(sb2)
+.byte pm_lo8(sb3), pm_hi8(sb3)
+.byte pm_lo8(sb4), pm_hi8(sb4)
+.byte pm_lo8(sb5), pm_hi8(sb5)
+.byte pm_lo8(sb6), pm_hi8(sb6)
+.byte pm_lo8(sb7), pm_hi8(sb7)
+
+
+sinvf_tab:
+.byte pm_lo8(sb0_inv), pm_hi8(sb0_inv)
+.byte pm_lo8(sb1_inv), pm_hi8(sb1_inv)
+.byte pm_lo8(sb2_inv), pm_hi8(sb2_inv)
+.byte pm_lo8(sb3_inv), pm_hi8(sb3_inv)
+.byte pm_lo8(sb4_inv), pm_hi8(sb4_inv)
+.byte pm_lo8(sb5_inv), pm_hi8(sb5_inv)
+.byte pm_lo8(sb6_inv), pm_hi8(sb6_inv)
+.byte pm_lo8(sb7_inv), pm_hi8(sb7_inv)
+*/
+/*
+void sbox128(void * w, uint8_t box){
+       uint8_t i, buffer[16];
+       box &= 0x7;
+       
+       sb_fpt fp;
+       fp = (sb_fpt)pgm_read_word(&(sf_tab[box]));
+       for(i=0; i<4; ++i){
+               fp(buffer+i, (uint8_t*)w+i);
+       }
+       memcpy(w, buffer, 16);
+}
+*/
+.global sbox128
+sbox128:
+       ldi r30, lo8(sf_tab)
+       ldi r31, hi8(sf_tab)
+1:
+;      clr r1
+       andi r22, 0x07
+       lsl r22
+       add r30, r22
+       adc r31, r1
+       lpm r26, Z+
+       lpm r27, Z
+       lsr r27
+       ror r26
+       push r28
+       push r29
+       movw r30, r26
+       movw r28, r24
+       push_range 2, 17
+       ldd IN0, Y+0
+       ldd IN1, Y+4
+       ldd IN2, Y+8
+       ldd IN3, Y+12
+       icall 
+       std Y+0, OUT0
+       std Y+4, OUT1
+       std Y+8, OUT2
+       std Y+12, OUT3
+       ldd IN0, Y+0+1
+       ldd IN1, Y+4+1
+       ldd IN2, Y+8+1
+       ldd IN3, Y+12+1
+       icall
+       std Y+0+1, OUT0
+       std Y+4+1, OUT1
+       std Y+8+1, OUT2
+       std Y+12+1, OUT3
+       ldd IN0, Y+0+2
+       ldd IN1, Y+4+2
+       ldd IN2, Y+8+2
+       ldd IN3, Y+12+2
+       icall
+       std Y+0+2, OUT0
+       std Y+4+2, OUT1
+       std Y+8+2, OUT2
+       std Y+12+2, OUT3
+       ldd IN0, Y+0+3
+       ldd IN1, Y+4+3
+       ldd IN2, Y+8+3
+       ldd IN3, Y+12+3
+       icall
+       std Y+0+3, OUT0
+       std Y+4+3, OUT1
+       std Y+8+3, OUT2
+       std Y+12+3, OUT3
+       pop_range 2, 17
+       pop r29
+       pop r28
+       ret
+       
+.global        inv_sbox128
+inv_sbox128:
+       ldi r30, lo8(sinvf_tab)
+       ldi r31, hi8(sinvf_tab)
+       rjmp 1b 
+/*     
+void inv_sbox128(void * w, uint8_t box){
+       uint8_t i, buffer[16];
+       box &= 0x7;
+       
+       sb_fpt fp;
+       fp = (sb_fpt)pgm_read_word(&(sinvf_tab[box]));
+       for(i=0; i<4; ++i){
+               fp(buffer+i, (uint8_t*)w+i);
+       }
+       memcpy(w, buffer, 16);
+}
+*/
+
+
+
+
+
+
+
diff --git a/serpent/serpent-sboxes-bitslice.c b/serpent/serpent-sboxes-bitslice.c
new file mode 100644 (file)
index 0000000..96f9c68
--- /dev/null
@@ -0,0 +1,479 @@
+/* serpent-sboxes-bitslice.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* serpent-sboxes.c
+ * a bitsliced implementation of the serpent sboxes
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "serpent-sboxes.h"
+
+
+
+
+/* S0:   3  8 15  1 10  6  5 11 14 13  4  2  7  0  9 12 */
+
+/* depth = 5,7,4,2, Total gates=18 */
+static
+void sb0(uint8_t* out, const uint8_t* in){
+// (a,b,c,d,w,x,y,z) 
+       uint8_t t01, t02, t03, t05, t06, t07, t08, t09, t11, t12, t13, t14, t15, t17;
+       t01          = in[4*1]  ^ in[4*2]; 
+       t02          = in[4*0]  | in[4*3]; 
+       t03          = in[4*0]  ^ in[4*1]; 
+       out[4*3]   = t02        ^ t01; 
+       t05          = in[4*2]  | out[4*3]; 
+       t06          = in[4*0]  ^ in[4*3]; 
+       t07          = in[4*1]  | in[4*2]; 
+       t08          = in[4*3]  & t05; 
+       t09          = t03        & t07; 
+       out[4*2]   = t09        ^ t08; 
+       t11          = t09        & out[4*2]; 
+       t12          = in[4*2]  ^ in[4*3]; 
+       t13          = t07        ^ t11; 
+       t14          = in[4*1]  & t06; 
+       t15          = t06        ^ t13; 
+       out[4*0]   =     ~ t15; 
+       t17          = out[4*0] ^ t14; 
+       out[4*1]   = t12        ^ t17; 
+}
+
+/* InvS0:  13  3 11  0 10  6  5 12  1 14  4  7 15  9  8  2 */
+
+/* depth = 8,4,3,6, Total gates=19 */
+static
+void sb0_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;
+       t01          = in[4*2] ^ in[4*3];
+       t02          = in[4*0] | in[4*1];
+       t03          = in[4*1] | in[4*2];
+       t04          = in[4*2] & t01;
+       t05          = t02       ^ t01;
+       t06          = in[4*0] | t04;
+       out[4*2]   =     ~ t05;
+       t08          = in[4*1]   ^ in[4*3];
+       t09          = t03       & t08;
+       t10          = in[4*3]   | out[4*2];
+       out[4*1]   = t09       ^ t06;
+       t12          = in[4*0]   | t05;
+       t13          = out[4*1]   ^ t12;
+       t14          = t03       ^ t10;
+       t15          = in[4*0]   ^ in[4*2];
+       out[4*3]   = t14       ^ t13;
+       t17          = t05       & t13;
+       t18          = t14       | t17;
+       out[4*0]   = t15       ^ t18; 
+}
+
+/* S1:  15 12  2  7  9  0  5 10  1 11 14  8  6 13  3  4 */
+
+/* depth = 10,7,3,5, Total gates=18 */
+static 
+void sb1(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t08, t10, t11, t12, t13, t16, t17, t01;
+       t01          = in[4*0]   | in[4*3];
+       t02          = in[4*2]   ^ in[4*3];
+       t03          =     ~ in[4*1];
+       t04          = in[4*0]   ^ in[4*2];
+       t05          = in[4*0]   | t03;
+       t06          = in[4*3]   & t04;
+       t07          = t01       & t02;
+       t08          = in[4*1]   | t06;
+       out[4*2]   = t02       ^ t05;
+       t10          = t07       ^ t08;
+       t11          = t01       ^ t10;
+       t12          = out[4*2]   ^ t11;
+       t13          = in[4*1]   & in[4*3];
+       out[4*3]   =     ~ t10;
+       out[4*1]   = t13       ^ t12;
+       t16          = t10       | out[4*1];
+       t17          = t05       & t16;
+       out[4*0]   = in[4*2]   ^ t17; 
+}
+
+/* InvS1:   5  8  2 14 15  6 12  3 11  4  7  9  1 13 10  0 */
+
+/* depth = 7,4,5,3, Total gates=18 */
+static void sb1_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;
+       t01          = in[4*0]   ^ in[4*1];
+       t02          = in[4*1]   | in[4*3];
+       t03          = in[4*0]   & in[4*2];
+       t04          = in[4*2]   ^ t02;
+       t05          = in[4*0]   | t04;
+       t06          = t01       & t05;
+       t07          = in[4*3]   | t03;
+       t08          = in[4*1]   ^ t06;
+       t09          = t07       ^ t06;
+       t10          = t04       | t03;
+       t11          = in[4*3]   & t08;
+       out[4*2]   =     ~ t09;
+       out[4*1]   = t10       ^ t11;
+       t14          = in[4*0]   | out[4*2];
+       t15          = t06       ^ out[4*1];
+       out[4*3]   = t01       ^ t04;
+       t17          = in[4*2]   ^ t15;
+       out[4*0]   = t14       ^ t17; 
+}
+
+/* S2:   8  6  7  9  3 12 10 15 13  1 14  4  0 11  5  2 */
+
+/* depth = 3,8,11,7, Total gates=16 */
+static void sb2(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t05, t06, t07, t08, t09, t10, t12, t13, t14, t01;
+       t01          = in[4*0]   | in[4*2];
+       t02          = in[4*0]   ^ in[4*1];
+       t03          = in[4*3]   ^ t01;
+       out[4*0]   = t02       ^ t03;
+       t05          = in[4*2]   ^ out[4*0];
+       t06          = in[4*1]   ^ t05;
+       t07          = in[4*1]   | t05;
+       t08          = t01       & t06;
+       t09          = t03       ^ t07;
+       t10          = t02       | t09;
+       out[4*1]   = t10       ^ t08;
+       t12          = in[4*0]   | in[4*3];
+       t13          = t09       ^ out[4*1];
+       t14          = in[4*1]   ^ t13;
+       out[4*3]   =     ~ t09;
+       out[4*2]   = t12       ^ t14; 
+}
+
+/* InvS2:  12  9 15  4 11 14  1  2  0  3  6 13  5  8 10  7 */
+
+/* depth = 3,6,8,3, Total gates=18 */
+static void sb2_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;
+       t01          = in[4*0]   ^ in[4*3];
+       t02          = in[4*2]   ^ in[4*3];
+       t03          = in[4*0]   & in[4*2];
+       t04          = in[4*1]   | t02;
+       out[4*0]   = t01       ^ t04;
+       t06          = in[4*0]   | in[4*2];
+       t07          = in[4*3]   | out[4*0];
+       t08          =     ~ in[4*3];
+       t09          = in[4*1]   & t06;
+       t10          = t08       | t03;
+       t11          = in[4*1]   & t07;
+       t12          = t06       & t02;
+       out[4*3]   = t09       ^ t10;
+       out[4*1]   = t12       ^ t11;
+       t15          = in[4*2]   & out[4*3];
+       t16          = out[4*0]   ^ out[4*1];
+       t17          = t10       ^ t15;
+       out[4*2]   = t16       ^ t17; 
+}
+
+/* S3:   0 15 11  8 12  9  6  3 13  1  2  4 10  7  5 14 */
+
+/* depth = 8,3,5,5, Total gates=18 */
+static void sb3(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t13, t14, t15, t01;
+       t01          = in[4*0]   ^ in[4*2];
+       t02          = in[4*0]   | in[4*3];
+       t03          = in[4*0]   & in[4*3];
+       t04          = t01       & t02;
+       t05          = in[4*1]   | t03;
+       t06          = in[4*0]   & in[4*1];
+       t07          = in[4*3]   ^ t04;
+       t08          = in[4*2]   | t06;
+       t09          = in[4*1]   ^ t07;
+       t10          = in[4*3]   & t05;
+       t11          = t02       ^ t10;
+       out[4*3]   = t08       ^ t09;
+       t13          = in[4*3]   | out[4*3];
+       t14          = in[4*0]   | t07;
+       t15          = in[4*1]   & t13;
+       out[4*2]   = t08       ^ t11;
+       out[4*0]   = t14       ^ t15;
+       out[4*1]   = t05       ^ t04; 
+}
+
+/* InvS3:   0  9 10  7 11 14  6 13  3  5 12  2  4  8 15  1 */
+
+/* depth = 3,6,4,4, Total gates=17 */
+static void sb3_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;
+       t01          = in[4*2]   | in[4*3];
+       t02          = in[4*0]   | in[4*3];
+       t03          = in[4*2]   ^ t02;
+       t04          = in[4*1]   ^ t02;
+       t05          = in[4*0]   ^ in[4*3];
+       t06          = t04       & t03;
+       t07          = in[4*1]   & t01;
+       out[4*2]   = t05       ^ t06;
+       t09          = in[4*0]   ^ t03;
+       out[4*0]   = t07       ^ t03;
+       t11          = out[4*0]   | t05;
+       t12          = t09       & t11;
+       t13          = in[4*0]   & out[4*2];
+       t14          = t01       ^ t05;
+       out[4*1]   = in[4*1]   ^ t12;
+       t16          = in[4*1]   | t13;
+       out[4*3]   = t14       ^ t16; 
+}
+
+/* S4:   1 15  8  3 12  0 11  6  2  5  4 10  9 14  7 13 */
+
+/* depth = 6,7,5,3, Total gates=19 */
+static void sb4(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t12, t13, t14, t15, t16, t01;
+       t01          = in[4*0]   | in[4*1];
+       t02          = in[4*1]   | in[4*2];
+       t03          = in[4*0]   ^ t02;
+       t04          = in[4*1]   ^ in[4*3];
+       t05          = in[4*3]   | t03;
+       t06          = in[4*3]   & t01;
+       out[4*3]   = t03       ^ t06;
+       t08          = out[4*3]   & t04;
+       t09          = t04       & t05;
+       t10          = in[4*2]   ^ t06;
+       t11          = in[4*1]   & in[4*2];
+       t12          = t04       ^ t08;
+       t13          = t11       | t03;
+       t14          = t10       ^ t09;
+       t15          = in[4*0]   & t05;
+       t16          = t11       | t12;
+       out[4*2]   = t13       ^ t08;
+       out[4*1]   = t15       ^ t16;
+       out[4*0]   =     ~ t14; 
+}
+
+/* InvS4:   5  0  8  3 10  9  7 14  2 12 11  6  4 15 13  1 */
+
+/* depth = 6,4,7,3, Total gates=17 */
+static void sb4_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;
+       t01          = in[4*1]   | in[4*3];
+       t02          = in[4*2]   | in[4*3];
+       t03          = in[4*0]   & t01;
+       t04          = in[4*1]   ^ t02;
+       t05          = in[4*2]   ^ in[4*3];
+       t06          =     ~ t03;
+       t07          = in[4*0]   & t04;
+       out[4*1]   = t05       ^ t07;
+       t09          = out[4*1]   | t06;
+       t10          = in[4*0]   ^ t07;
+       t11          = t01       ^ t09;
+       t12          = in[4*3]   ^ t04;
+       t13          = in[4*2]   | t10;
+       out[4*3]   = t03       ^ t12;
+       t15          = in[4*0]   ^ t04;
+       out[4*2]   = t11       ^ t13;
+       out[4*0]   = t15       ^ t09; 
+}
+
+/* S5:  15  5  2 11  4 10  9 12  0  3 14  8 13  6  7  1 */
+
+/* depth = 4,6,8,6, Total gates=17 */
+static void sb5(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t14, t01;
+       t01          = in[4*1]   ^ in[4*3];
+       t02          = in[4*1]   | in[4*3];
+       t03          = in[4*0]   & t01;
+       t04          = in[4*2]   ^ t02;
+       t05          = t03       ^ t04;
+       out[4*0]   =     ~ t05;
+       t07          = in[4*0]   ^ t01;
+       t08          = in[4*3]   | out[4*0];
+       t09          = in[4*1]   | t05;
+       t10          = in[4*3]   ^ t08;
+       t11          = in[4*1]   | t07;
+       t12          = t03       | out[4*0];
+       t13          = t07       | t10;
+       t14          = t01       ^ t11;
+       out[4*2]   = t09       ^ t13;
+       out[4*1]   = t07       ^ t08;
+       out[4*3]   = t12       ^ t14; 
+}
+
+/* InvS5:   8 15  2  9  4  1 13 14 11  6  5  3  7 12 10  0 */
+
+/* depth = 4,6,9,7, Total gates=17 */
+static void sb5_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;
+       t01          = in[4*0]   & in[4*3];
+       t02          = in[4*2]   ^ t01;
+       t03          = in[4*0]   ^ in[4*3];
+       t04          = in[4*1]   & t02;
+       t05          = in[4*0]   & in[4*2];
+       out[4*0]   = t03       ^ t04;
+       t07          = in[4*0]   & out[4*0];
+       t08          = t01       ^ out[4*0];
+       t09          = in[4*1]   | t05;
+       t10          =     ~ in[4*1];
+       out[4*1]   = t08       ^ t09;
+       t12          = t10       | t07;
+       t13          = out[4*0]   | out[4*1];
+       out[4*3]   = t02       ^ t12;
+       t15          = t02       ^ t13;
+       t16          = in[4*1]   ^ in[4*3];
+       out[4*2]   = t16       ^ t15; 
+}
+
+/* S6:   7  2 12  5  8  4  6 11 14  9  1 15 13  3 10  0 */
+
+/* depth = 8,3,6,3, Total gates=19 */
+static void sb6(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t15, t17, t18, t01;
+       t01          = in[4*0]   & in[4*3];
+       t02          = in[4*1]   ^ in[4*2];
+       t03          = in[4*0]   ^ in[4*3];
+       t04          = t01       ^ t02;
+       t05          = in[4*1]   | in[4*2];
+       out[4*1]   =     ~ t04;
+       t07          = t03       & t05;
+       t08          = in[4*1]   & out[4*1];
+       t09          = in[4*0]   | in[4*2];
+       t10          = t07       ^ t08;
+       t11          = in[4*1]   | in[4*3];
+       t12          = in[4*2]   ^ t11;
+       t13          = t09       ^ t10;
+       out[4*2]   =     ~ t13;
+       t15          = out[4*1]   & t03;
+       out[4*3]   = t12       ^ t07;
+       t17          = in[4*0]   ^ in[4*1];
+       t18          = out[4*2]   ^ t15;
+       out[4*0]   = t17       ^ t18; 
+}
+
+/* InvS6:  15 10  1 13  5  3  6  0  4  9 14  7  2 12  8 11 */
+
+/* depth = 5,3,8,6, Total gates=19 */
+static void sb6_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;
+       t01          = in[4*0]   ^ in[4*2];
+       t02          =     ~ in[4*2];
+       t03          = in[4*1]   & t01;
+       t04          = in[4*1]   | t02;
+       t05          = in[4*3]   | t03;
+       t06          = in[4*1]   ^ in[4*3];
+       t07          = in[4*0]   & t04;
+       t08          = in[4*0]   | t02;
+       t09          = t07       ^ t05;
+       out[4*1]   = t06       ^ t08;
+       out[4*0]   =     ~ t09;
+       t12          = in[4*1]   & out[4*0];
+       t13          = t01       & t05;
+       t14          = t01       ^ t12;
+       t15          = t07       ^ t13;
+       t16          = in[4*3]   | t02;
+       t17          = in[4*0]   ^ out[4*1];
+       out[4*3]   = t17       ^ t15;
+       out[4*2]   = t16       ^ t14; 
+}
+
+/* S7:   1 13 15  0 14  8  2 11  7  4 12 10  9  3  5  6 */
+
+/* depth = 10,7,10,4, Total gates=19 */
+static void sb7(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t13, t14, t15, t16, t17, t01;
+       t01          = in[4*0]   & in[4*2];
+       t02          =     ~ in[4*3];
+       t03          = in[4*0]   & t02;
+       t04          = in[4*1]   | t01;
+       t05          = in[4*0]   & in[4*1];
+       t06          = in[4*2]   ^ t04;
+       out[4*3]   = t03       ^ t06;
+       t08          = in[4*2]   | out[4*3];
+       t09          = in[4*3]   | t05;
+       t10          = in[4*0]   ^ t08;
+       t11          = t04       & out[4*3];
+       out[4*1]   = t09       ^ t10;
+       t13          = in[4*1]   ^ out[4*1];
+       t14          = t01       ^ out[4*1];
+       t15          = in[4*2]   ^ t05;
+       t16          = t11       | t13;
+       t17          = t02       | t14;
+       out[4*0]   = t15       ^ t17;
+       out[4*2]   = in[4*0]   ^ t16; 
+}
+
+/* InvS7:   3  0  6 13  9 14 15  8  5 12 11  7 10  1  4  2 */
+
+/* depth = 9,7,3,3, Total gates=18 */
+static void sb7_inv(uint8_t* out, const uint8_t* in){
+       uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;
+       t01          = in[4*0]   & in[4*1];
+       t02          = in[4*0]   | in[4*1];
+       t03          = in[4*2]   | t01;
+       t04          = in[4*3]   & t02;
+       out[4*3]   = t03       ^ t04;
+       t06          = in[4*1]   ^ t04;
+       t07          = in[4*3]   ^ out[4*3];
+       t08          =     ~ t07;
+       t09          = t06       | t08;
+       t10          = in[4*1]   ^ in[4*3];
+       t11          = in[4*0]   | in[4*3];
+       out[4*1]   = in[4*0]   ^ t09;
+       t13          = in[4*2]   ^ t06;
+       t14          = in[4*2]   & t11;
+       t15          = in[4*3]   | out[4*1];
+       t16          = t01       | t10;
+       out[4*0]   = t13       ^ t15;
+       out[4*2]   = t14       ^ t16; 
+}
+
+typedef void(*sb_fpt)(uint8_t*, const uint8_t*);
+
+sb_fpt sf_tab[] PROGMEM = {
+       sb0, sb1, sb2, sb3, 
+       sb4, sb5, sb6, sb7
+};
+
+sb_fpt sinvf_tab[] PROGMEM = {
+       sb0_inv, sb1_inv, sb2_inv, sb3_inv, 
+       sb4_inv, sb5_inv, sb6_inv, sb7_inv
+};
+
+void sbox128(void * w, uint8_t box){
+       uint8_t i, buffer[16];
+       box &= 0x7;
+       
+       sb_fpt fp;
+       fp = (sb_fpt)pgm_read_word(&(sf_tab[box]));
+       for(i=0; i<4; ++i){
+               fp(buffer+i, (uint8_t*)w+i);
+       }
+       memcpy(w, buffer, 16);
+}
+
+void inv_sbox128(void * w, uint8_t box){
+       uint8_t i, buffer[16];
+       box &= 0x7;
+       
+       sb_fpt fp;
+       fp = (sb_fpt)pgm_read_word(&(sinvf_tab[box]));
+       for(i=0; i<4; ++i){
+               fp(buffer+i, (uint8_t*)w+i);
+       }
+       memcpy(w, buffer, 16);
+}
+
+
+
+
+
+
+
+
diff --git a/serpent/serpent-sboxes-fast.S b/serpent/serpent-sboxes-fast.S
new file mode 100644 (file)
index 0000000..9242272
--- /dev/null
@@ -0,0 +1,233 @@
+/* serpent-sboxes-fast.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* 
+ * File:        serpent-sboxes-fast.S
+ * Author:      Daniel Otte
+ * Date:        2008-08-07
+ * License:     GPLv3 or later
+ * Description: Implementation of the serpent sbox function.
+ * 
+ */
+#include <avr/io.h>
+#include "avr-asm-macros.S"
+
+
+serpent_sbox_fast:
+ .byte 0x33, 0x88, 0xFF, 0x11, 0xAA, 0x66, 0x55, 0xBB 
+ .byte 0xEE, 0xDD, 0x44, 0x22, 0x77, 0x00, 0x99, 0xCC
+ .byte 0xFF, 0xCC, 0x22, 0x77, 0x99, 0x00, 0x55, 0xAA
+ .byte 0x11, 0xBB, 0xEE, 0x88, 0x66, 0xDD, 0x33, 0x44 
+ .byte 0x88, 0x66, 0x77, 0x99, 0x33, 0xCC, 0xAA, 0xFF 
+ .byte 0xDD, 0x11, 0xEE, 0x44, 0x00, 0xBB, 0x55, 0x22
+ .byte 0x00, 0xFF, 0xBB, 0x88, 0xCC, 0x99, 0x66, 0x33 
+ .byte 0xDD, 0x11, 0x22, 0x44, 0xAA, 0x77, 0x55, 0xEE
+ .byte 0x11, 0xFF, 0x88, 0x33, 0xCC, 0x00, 0xBB, 0x66 
+ .byte 0x22, 0x55, 0x44, 0xAA, 0x99, 0xEE, 0x77, 0xDD
+ .byte 0xFF, 0x55, 0x22, 0xBB, 0x44, 0xAA, 0x99, 0xCC 
+ .byte 0x00, 0x33, 0xEE, 0x88, 0xDD, 0x66, 0x77, 0x11
+ .byte 0x77, 0x22, 0xCC, 0x55, 0x88, 0x44, 0x66, 0xBB 
+ .byte 0xEE, 0x99, 0x11, 0xFF, 0xDD, 0x33, 0xAA, 0x00
+ .byte 0x11, 0xDD, 0xFF, 0x00, 0xEE, 0x88, 0x22, 0xBB 
+ .byte 0x77, 0x44, 0xCC, 0xAA, 0x99, 0x33, 0x55, 0x66
+
+serpent_sbox_inv_fast:
+ .byte 0xDD, 0x33, 0xBB, 0x00, 0xAA, 0x66, 0x55, 0xCC 
+ .byte 0x11, 0xEE, 0x44, 0x77, 0xFF, 0x99, 0x88, 0x22
+ .byte 0x55, 0x88, 0x22, 0xEE, 0xFF, 0x66, 0xCC, 0x33 
+ .byte 0xBB, 0x44, 0x77, 0x99, 0x11, 0xDD, 0xAA, 0x00
+ .byte 0xCC, 0x99, 0xFF, 0x44, 0xBB, 0xEE, 0x11, 0x22 
+ .byte 0x00, 0x33, 0x66, 0xDD, 0x55, 0x88, 0xAA, 0x77
+ .byte 0x00, 0x99, 0xAA, 0x77, 0xBB, 0xEE, 0x66, 0xDD 
+ .byte 0x33, 0x55, 0xCC, 0x22, 0x44, 0x88, 0xFF, 0x11
+ .byte 0x55, 0x00, 0x88, 0x33, 0xAA, 0x99, 0x77, 0xEE 
+ .byte 0x22, 0xCC, 0xBB, 0x66, 0x44, 0xFF, 0xDD, 0x11
+ .byte 0x88, 0xFF, 0x22, 0x99, 0x44, 0x11, 0xDD, 0xEE 
+ .byte 0xBB, 0x66, 0x55, 0x33, 0x77, 0xCC, 0xAA, 0x00
+ .byte 0xFF, 0xAA, 0x11, 0xDD, 0x55, 0x33, 0x66, 0x00 
+ .byte 0x44, 0x99, 0xEE, 0x77, 0x22, 0xCC, 0x88, 0xBB
+ .byte 0x33, 0x00, 0x66, 0xDD, 0x99, 0xEE, 0xFF, 0x88 
+ .byte 0x55, 0xCC, 0xBB, 0x77, 0xAA, 0x11, 0x44, 0x22
+                  
+/*
+ * void ip(uint32_t *i, uint8_t *o){
+ */
+/* 
+ * param i is given in r24:r25
+ * parma o is given in r22:r23
+ */
+.global serpent_ip
+serpent_ip:
+       push_range 2, 17        
+       movw r26, r24
+       ldi r24, 16
+       clr r31
+       ldi r30, 2
+1:
+       ld r25, X+
+       st Z+, r25
+       dec r24
+       brne 1b
+       /* now the whole input is loaded in r2-r18 */
+       movw r26, r22
+       ldi r21, 4
+4:
+       ldi r20, 8      
+2:     
+       lsr r2
+       ror r19
+       lsr r6
+       ror 19
+       lsr r10
+       ror r19
+       lsr r14
+       ror 19
+       sbrc r20, 0
+       st X+, r19
+       dec r20
+       brne 2b
+       
+       ldi r20, 15
+       ldi r30, 2
+3:
+       ldd r19, Z+1
+       st Z+, r19
+       dec r20
+       brne 3b
+       
+       dec r21
+       brne 4b
+       pop_range 2, 17 
+       ret
+
+/*
+ * void serpent_fp(uint32_t *i, uint8_t *o){
+ */
+/* 
+ * param i is given in r24:r25
+ * parma o is given in r22:r23
+ */
+.global serpent_fp
+serpent_fp:
+       movw r26, r24
+       movw r30, r22
+       ldi r18, 4
+1:     
+       ldi r19, 8 
+2:
+       sbrs r19, 0
+       ld r24, X+
+3:
+       lsr r24
+       ror r20
+       lsr r24
+       ror r21
+       lsr r24
+       ror r22
+       lsr r24
+       ror r23
+       dec r19
+       brne 2b
+       
+       st Z+, r20
+       std Z+3, r21
+       std Z+7, r22
+       std Z+11, r23
+       
+       dec r18
+       brne 1b         
+       ret
+       
+
+/*
+ * void inv_sbox128(void * w, uint8_t box)
+ */
+.global inv_sbox128 
+inv_sbox128:
+       andi r22, 0x07
+       ori  r22, 0x08
+       rjmp sbox128x_fast
+/*     
+ * void sbox128(void * w, uint8_t box);
+ */
+/*
+ * param w   is passed in r24:r25
+ * param box is passed in r22
+ */
+.global sbox128 
+sbox128:
+       andi r22, 0x07
+sbox128x_fast:
+       stack_alloc 16
+       adiw r30, 1
+       push_ r24, r25, r22, r30, r31
+       movw r22, r30   /* Z points to the stack buffer */
+       rcall serpent_ip
+       pop_ r27, r26, r22
+       ldi r25, hi8(serpent_sbox_fast)
+       ldi r24, lo8(serpent_sbox_fast)
+       swap r22 /* r22 *= 16 */
+       add r24, r22
+       adc r25, r1
+       /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
+       ldi r22, 16
+1:     
+       movw r30, r24
+       ld r18, X
+       mov r20, r18
+       andi r18, 0x0f
+       add r30, r18
+       adc r31, r1
+       lpm r19, Z
+2:     
+       swap r20
+       andi r20, 0x0f
+       movw r30, r24
+       add r30, r20
+       adc r31, r1
+       lpm r21, Z
+3:     
+       andi r19, 0x0F
+       andi r21, 0xF0
+       or r19, r21
+       st X+, r19
+       dec r22
+       brne 1b
+       
+       pop_ r23, r22
+       movw r24, r26
+       sbiw r24, 16
+
+       rcall serpent_fp
+       
+       stack_free 16   
+       ret
+
+
+
+
+
+
+
+
diff --git a/serpent/serpent-sboxes-small.S b/serpent/serpent-sboxes-small.S
new file mode 100644 (file)
index 0000000..028fd77
--- /dev/null
@@ -0,0 +1,231 @@
+/* serpent_sboxes.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* 
+ * File:        serpent_sboxes.S
+ * Author:      Daniel Otte
+ * Date:        2008-08-07
+ * License:     GPLv3 or later
+ * Description: Implementation of the serpent sbox function.
+ * 
+ */
+#include <avr/io.h>
+#include "avr-asm-macros.S"
+
+
+serpent_sbox:
+ .byte 0x83, 0x1F, 0x6A, 0xB5, 0xDE, 0x24, 0x07, 0xC9
+ .byte 0xCF, 0x72, 0x09, 0xA5, 0xB1, 0x8E, 0xD6, 0x43 
+ .byte 0x68, 0x97, 0xC3, 0xFA, 0x1D, 0x4E, 0xB0, 0x25
+ .byte 0xF0, 0x8B, 0x9C, 0x36, 0x1D, 0x42, 0x7A, 0xE5
+ .byte 0xF1, 0x38, 0x0C, 0x6B, 0x52, 0xA4, 0xE9, 0xD7
+ .byte 0x5F, 0xB2, 0xA4, 0xC9, 0x30, 0x8E, 0x6D, 0x17
+ .byte 0x27, 0x5C, 0x48, 0xB6, 0x9E, 0xF1, 0x3D, 0x0A
+ .byte 0xD1, 0x0F, 0x8E, 0xB2, 0x47, 0xAC, 0x39, 0x65
+
+serpent_sbox_inv:
+ .byte 0x3D, 0x0B, 0x6A, 0xC5, 0xE1, 0x74, 0x9F, 0x28
+ .byte 0x85, 0xE2, 0x6F, 0x3C, 0x4B, 0x97, 0xD1, 0x0A
+ .byte 0x9C, 0x4F, 0xEB, 0x21, 0x30, 0xD6, 0x85, 0x7A
+ .byte 0x90, 0x7A, 0xEB, 0xD6, 0x53, 0x2C, 0x84, 0x1F
+ .byte 0x05, 0x38, 0x9A, 0xE7, 0xC2, 0x6B, 0xF4, 0x1D
+ .byte 0xF8, 0x92, 0x14, 0xED, 0x6B, 0x35, 0xC7, 0x0A
+ .byte 0xAF, 0xD1, 0x35, 0x06, 0x94, 0x7E, 0xC2, 0xB8
+ .byte 0x03, 0xD6, 0xE9, 0x8F, 0xC5, 0x7B, 0x1A, 0x24                  
+/*
+ * void ip(uint32_t *i, uint8_t *o){
+ */
+/* 
+ * param i is given in r24:r25
+ * parma o is given in r22:r23
+ */
+.global serpent_ip
+serpent_ip:
+       push_range 2, 17        
+       movw r26, r24
+       ldi r24, 16
+       clr r31
+       ldi r30, 2
+1:
+       ld r25, X+
+       st Z+, r25
+       dec r24
+       brne 1b
+       /* now the whole input is loaded in r2-r18 */
+       movw r26, r22
+       ldi r21, 4
+4:
+       ldi r20, 8      
+2:     
+       lsr r2
+       ror r19
+       lsr r6
+       ror 19
+       lsr r10
+       ror r19
+       lsr r14
+       ror 19
+       sbrc r20, 0
+       st X+, r19
+       dec r20
+       brne 2b
+       
+       ldi r20, 15
+       ldi r30, 2
+3:
+       ldd r19, Z+1
+       st Z+, r19
+       dec r20
+       brne 3b
+       
+       dec r21
+       brne 4b
+       pop_range 2, 17 
+       ret
+
+/*
+ * void serpent_fp(uint32_t *i, uint8_t *o){
+ */
+/* 
+ * param i is given in r24:r25
+ * parma o is given in r22:r23
+ */
+.global serpent_fp
+serpent_fp:
+       movw r26, r24
+       movw r30, r22
+       ldi r18, 4
+1:     
+       ldi r19, 8 
+2:
+       sbrs r19, 0
+       ld r24, X+
+3:
+       lsr r24
+       ror r20
+       lsr r24
+       ror r21
+       lsr r24
+       ror r22
+       lsr r24
+       ror r23
+       dec r19
+       brne 2b
+       
+       st Z+, r20
+       std Z+3, r21
+       std Z+7, r22
+       std Z+11, r23
+       
+       dec r18
+       brne 1b 
+       
+       ret
+/*
+ * void inv_sbox128(void * w, uint8_t box)
+ */
+.global inv_sbox128 
+inv_sbox128:
+       andi r22, 0x07
+       ori  r22, 0x08
+       rjmp sbox128x
+/*     
+ * void sbox128(void * w, uint8_t box);
+ */
+/*
+ * param w   is passed in r24:r25
+ * param box is passed in r22
+ */
+.global sbox128 
+sbox128:
+       andi r22, 0x07
+
+/*     
+ * void sbox128x(void * w, uint8_t box);
+ */
+/*
+ * param w   is passed in r24:r25
+ * param box is passed in r22
+ */
+.global sbox128x
+sbox128x:
+       stack_alloc 16
+       adiw r30, 1
+       push_ r24, r25, r22, r30, r31
+       movw r22, r30   /* Z points to the stack buffer */
+       rcall serpent_ip
+       pop_ r27, r26, r22
+       ldi r25, hi8(serpent_sbox)
+       ldi r24, lo8(serpent_sbox)
+       swap r22
+       lsr  r22 /* r22 *= 8 */
+       add r24, r22
+       adc r25, r1
+       /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
+       ldi r22, 16
+1:     
+       movw r30, r24
+       ld r18, X
+       mov r20, r18
+       andi r18, 0x0f
+       bst r18, 0
+       lsr r18
+       add r30, r18
+       adc r31, r1
+       lpm r19, Z
+       brtc 2f
+       swap r19
+2:     
+       swap r20
+       andi r20, 0x0f
+       bst r20, 0
+       lsr r20
+       movw r30, r24
+       add r30, r20
+       adc r31, r1
+       lpm r21, Z
+       brts 3f
+       swap r21
+3:     
+       andi r19, 0x0F
+       andi r21, 0xF0
+       or r19, r21
+       st X+, r19
+       dec r22
+       brne 1b
+       
+       pop_ r23, r22
+       movw r24, r26
+       sbiw r24, 16
+
+       rcall serpent_fp
+       
+       stack_free 16   
+       ret
+
+
+
+
+
diff --git a/serpent/serpent-sboxes.h b/serpent/serpent-sboxes.h
new file mode 100644 (file)
index 0000000..c391edc
--- /dev/null
@@ -0,0 +1,28 @@
+/* serpent-sboxes.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SERPENTSBOXES_H_
+#define SERPENTSBOXES_H_
+
+#include <stdint.h>
+
+void sbox128(void * w, uint8_t box);
+void inv_sbox128(void * w, uint8_t box);
+
+
+#endif /*SERPENTSBOXES_H_*/
diff --git a/serpent/serpent-sboxes_c.c b/serpent/serpent-sboxes_c.c
new file mode 100644 (file)
index 0000000..3a59969
--- /dev/null
@@ -0,0 +1,128 @@
+/* serpent-sboxes.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* serpent-sboxes.c
+ * a non-bitsliced implementation of the serpent sboxes
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ */
+
+#include <stdint.h>
+#include <string.h> /* memset() */
+#include <avr/pgmspace.h>
+#include "serpent-sboxes.h"
+
+uint8_t sbox[] PROGMEM = {
+ 0x38, 0xF1, 0xA6, 0x5B, 0xED, 0x42, 0x70, 0x9C,
+ 0xFC, 0x27, 0x90, 0x5A, 0x1B, 0xE8, 0x6D, 0x34, 
+ 0x86, 0x79, 0x3C, 0xAF, 0xD1, 0xE4, 0x0B, 0x52,
+ 0x0F, 0xB8, 0xC9, 0x63, 0xD1, 0x24, 0xA7, 0x5E,
+ 0x1F, 0x83, 0xC0, 0xB6, 0x25, 0x4A, 0x9E, 0x7D,
+ 0xF5, 0x2B, 0x4A, 0x9C, 0x03, 0xE8, 0xD6, 0x71,
+ 0x72, 0xC5, 0x84, 0x6B, 0xE9, 0x1F, 0xD3, 0xA0,
+ 0x1D, 0xF0, 0xE8, 0x2B, 0x74, 0xCA, 0x93, 0x56,
+/* now the inverted sboxes */
+ 0xD3, 0xB0, 0xA6, 0x5C, 0x1E, 0x47, 0xF9, 0x82,
+ 0x58, 0x2E, 0xF6, 0xC3, 0xB4, 0x79, 0x1D, 0xA0,
+ 0xC9, 0xF4, 0xBE, 0x12, 0x03, 0x6D, 0x58, 0xA7,
+ 0x09, 0xA7, 0xBE, 0x6D, 0x35, 0xC2, 0x48, 0xF1,
+ 0x50, 0x83, 0xA9, 0x7E, 0x2C, 0xB6, 0x4F, 0xD1,
+ 0x8F, 0x29, 0x41, 0xDE, 0xB6, 0x53, 0x7C, 0xA0,
+ 0xFA, 0x1D, 0x53, 0x60, 0x49, 0xE7, 0x2C, 0x8B,
+ 0x30, 0x6D, 0x9E, 0xF8, 0x5C, 0xB7, 0xA1, 0x42
+};        
+         
+
+#define SHR_O(a) c=(a)&1; ((a) = (a)>>1)
+#define SHR_I(a) ((a) = (c?0x80:0x00)| ((a)>>1))
+
+static void serpent_ip(uint32_t *i, uint8_t *o){
+       uint8_t c; // carry 
+       uint8_t n,m;
+       memset(o, 0, 16);
+       for(n=0; n<16; ++n){
+               for(m=0; m<2; ++m){
+               SHR_O(i[0]);
+               SHR_I(o[n]);
+               SHR_O(i[1]);
+               SHR_I(o[n]);
+               SHR_O(i[2]);
+               SHR_I(o[n]);
+               SHR_O(i[3]);
+               SHR_I(o[n]);
+               }
+       }
+}
+
+#undef SHR_I
+#define SHR_I(a) ((a) = (c?0x80000000L:0x00L)| ((a)>>1)) /* we use 32-bit words here */
+
+static void serpent_fp(uint32_t *i, uint32_t *o){
+       uint8_t c; // carry 
+       uint8_t n,m;
+       memset(o, 0, 16);
+       for(n=0; n<4; ++n){
+               for(m=0; m<8; ++m){
+               SHR_O(i[n]);
+               SHR_I(o[0]);
+               SHR_O(i[n]);
+               SHR_I(o[1]);
+               SHR_O(i[n]);
+               SHR_I(o[2]);
+               SHR_O(i[n]);
+               SHR_I(o[3]);
+               }
+       }
+}
+
+/******************************************************************************/
+static void sbox128x(uint8_t box, void* w){
+       uint8_t sb[16];
+       uint8_t i,t,x;
+       box &= 0x0f;
+       /* load sbox */
+       for(i=0; i<8; ++i){
+               t = pgm_read_byte(sbox + box*8 + i);
+               sb[2*i+0]=t>>4;
+               sb[2*i+1]=t&0xf;
+       }
+       uint8_t o[16];
+       serpent_ip(w,o);
+       
+       for(i=0; i<16; ++i){
+               t = ((uint8_t*)o)[i];
+               x = sb[t>>4];
+               x <<= 4;
+               x |= sb[t&0xf];
+               ((uint8_t*)o)[i] = x;
+       }
+       serpent_fp((uint32_t*)o, w);
+}
+
+void sbox128(void * w, uint8_t box){
+       sbox128x(box&0x7, w);
+}
+
+
+void inv_sbox128(void * w, uint8_t box){
+       sbox128x(((box&0x7)|0x8), w);
+}
+
+
+
diff --git a/serpent/serpent.c b/serpent/serpent.c
new file mode 100644 (file)
index 0000000..40ccecd
--- /dev/null
@@ -0,0 +1,140 @@
+/* serpent.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* serpent.c
+ * a bitsliced implementation of the serpent cipher for avr microcontrollers
+ * author: Daniel Otte 
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ */
+
+#include <stdint.h>
+#include <string.h> /* memset() */
+#include <avr/pgmspace.h>
+#include "memxor.h"
+#include "serpent.h"
+#include "serpent-sboxes.h"
+
+/******************************************************************************/
+
+uint32_t rotl32(uint32_t a, uint8_t n){
+       return ((a<<n) | (a>>(32-n)));
+}
+
+
+uint32_t rotr32(uint32_t a, uint8_t n){
+       return ((a>>n) | (a<<(32-n)));
+}
+
+
+#define X0 (((uint32_t*)b)[0])
+#define X1 (((uint32_t*)b)[1])
+#define X2 (((uint32_t*)b)[2])
+#define X3 (((uint32_t*)b)[3])
+
+static void serpent_lt(uint8_t *b){
+       X0 = rotl32(X0, 13);
+       X2 = rotl32(X2,  3);
+       X1 ^= X0 ^ X2;
+       X3 ^= X2 ^ (X0 << 3);
+       X1 = rotl32(X1, 1);
+       X3 = rotl32(X3, 7);
+       X0 ^= X1 ^ X3;
+       X2 ^= X3 ^ (X1 << 7);
+       X0 = rotl32(X0, 5);
+       X2 = rotr32(X2, 10);
+}
+
+static void serpent_inv_lt(uint8_t *b){
+       X2 = rotl32(X2, 10);
+       X0 = rotr32(X0, 5);
+       X2 ^= X3 ^ (X1 << 7);
+       X0 ^= X1 ^ X3;
+       X3 = rotr32(X3, 7);
+       X1 = rotr32(X1, 1);
+       X3 ^= X2 ^ (X0 << 3);
+       X1 ^= X0 ^ X2;
+       X2 = rotr32(X2,  3);
+       X0 = rotr32(X0, 13);
+}
+
+#define GOLDEN_RATIO 0x9e3779b9l
+
+static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
+       uint32_t ret;
+       ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
+       ret = rotl32(ret, 11);
+       return ret;
+} 
+
+void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx){
+       uint32_t buffer[8];
+       uint8_t i,j;
+       if(keysize_b<256){
+               /* keysize is less than 256 bit, padding needed */
+               memset(buffer, 0, 32);
+               memcpy(buffer, key, (keysize_b+7)/8);
+               ((uint8_t*)buffer)[keysize_b/8] |= 1<<(keysize_b%8);
+       } else {
+               /* keysize is 256 bit */
+               memcpy(buffer, key, 32); 
+       }
+       for(i=0; i<33; ++i){
+               for(j=0; j<4; ++j){
+                       ctx->k[i][j] = serpent_gen_w(buffer, i*4+j);
+                       memmove(buffer, &(buffer[1]), 7*4); /* shift buffer one to the "left" */
+                       buffer[7] = ctx->k[i][j];
+               }
+       }
+       for(i=0; i<33; ++i){
+               sbox128(ctx->k[i],3-i);
+       }
+}
+
+void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
+       uint8_t i;
+       for(i=0; i<31; ++i){
+               memxor(buffer, ctx->k[i], 16);
+               sbox128(buffer, i);
+               serpent_lt((uint8_t*)buffer);
+       }
+       memxor(buffer, ctx->k[i], 16);
+       sbox128(buffer, i);
+       ++i;
+       memxor(buffer, ctx->k[i], 16);
+}
+
+void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
+       int8_t i=32;
+       
+       memxor(buffer, ctx->k[i], 16);
+       --i;
+       inv_sbox128(buffer, i);
+       memxor((uint8_t*)buffer, ctx->k[i], 16);
+       --i;
+       for(; i>=0; --i){
+               serpent_inv_lt(buffer);
+               inv_sbox128(buffer, i);
+               memxor(buffer, ctx->k[i], 16);
+       }
+}
+
+
+
+
+
diff --git a/serpent/serpent.h b/serpent/serpent.h
new file mode 100644 (file)
index 0000000..84e4a87
--- /dev/null
@@ -0,0 +1,47 @@
+/* serpent.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** \file   serpent.h
+ * \author  Daniel Otte
+ * \license GPLv3
+ * \brief a implementation of the serpent cipher for avr microcontrollers
+ */
+
+#ifndef SERPENT_H_
+#define SERPENT_H_
+
+#include <stdint.h>
+
+typedef uint32_t serpent_subkey_t[4];
+
+typedef struct serpent_ctx_st {
+       serpent_subkey_t k[33];
+}  serpent_ctx_t;
+
+#define SERPENT_KEY128 128
+#define SERPENT_KEY192 192
+#define SERPENT_KEY256 256
+
+
+/* key must be 256bit (32 byte) large! */
+void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx);
+void serpent_enc(void* buffer, const serpent_ctx_t* ctx);
+void serpent_dec(void* buffer, const serpent_ctx_t* ctx);
+
+
+#endif /*SERPENT_H_*/
diff --git a/sha1-asm.S b/sha1-asm.S
deleted file mode 100644 (file)
index f571685..0000000
+++ /dev/null
@@ -1,886 +0,0 @@
-/* sha1-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * Author:     Daniel Otte
- *
- * License: GPLv3 or later
-*/
-; SHA1 implementation in assembler for AVR
-SHA1_BLOCK_BITS = 512
-SHA1_HASH_BITS = 160
-
-.macro precall
-       /* push r18 - r27, r30 - r31*/
-       push r0
-       push r1
-       push r18
-       push r19
-       push r20
-       push r21
-       push r22
-       push r23
-       push r24
-       push r25
-       push r26
-       push r27
-       push r30
-       push r31
-       clr r1
-.endm
-
-.macro postcall
-       pop r31
-       pop r30
-       pop r27
-       pop r26
-       pop r25
-       pop r24
-       pop r23
-       pop r22
-       pop r21
-       pop r20
-       pop r19
-       pop r18
-       pop r1
-       pop r0
-.endm
-
-
-.macro hexdump length
-       push r27
-       push r26
-       ldi r25, '\r'
-       mov r24, r25
-       call uart_putc
-       ldi r25, '\n'
-       mov r24, r25
-       call uart_putc
-       pop r26
-       pop r27
-       movw r24, r26
-.if \length > 16
-       ldi r22, lo8(16)
-       ldi r23, hi8(16)
-       push r27
-       push r26
-       call uart_hexdump
-       pop r26
-       pop r27
-       adiw r26, 16
-       hexdump \length-16
-.else
-       ldi r22, lo8(\length)
-       ldi r23, hi8(\length)
-       call uart_hexdump
-.endif
-.endm
-
-.macro delay
-/*     
-       push r0
-       push r1
-       clr r0
-1:     clr r1
-2:     dec r1
-       brne 2b
-       dec r0
-       brne 1b
-       pop r1
-       pop r0  // */
-.endm
-
-/* X points to Block */
-.macro dbg_hexdump length
-/*     
-       precall
-       hexdump \length
-       postcall
-       // */
-.endm
-
-
-
-.section .text
-
-SPL = 0x3D
-SPH = 0x3E
-SREG = 0x3F
-
-
-;
-;sha1_ctx_t is:
-;
-; [h0][h1][h2][h3][h4][length]
-; hn is 32 bit large, length is 64 bit large
-
-;###########################################################   
-
-.global sha1_ctx2hash
-; === sha1_ctx2hash ===
-; this function converts a state into a normal hash (bytestring)
-;  param1: the 16-bit destination pointer
-;      given in r25,r24 (r25 is most significant)
-;  param2: the 16-bit pointer to sha1_ctx structure
-;      given in r23,r22
-sha1_ctx2hash:
-       movw r26, r22
-       movw r30, r24
-       ldi r21, 5
-       sbiw r26, 4
-1:     
-       ldi r20, 4
-       adiw r26, 8
-2:     
-               ld r0, -X
-               st Z+, r0       
-       dec r20
-       brne 2b
-       
-       dec r21
-       brne 1b
-       
-       ret
-
-;###########################################################   
-
-.global sha1
-; === sha1 ===
-; this function calculates SHA-1 hashes from messages in RAM
-;  param1: the 16-bit hash destination pointer
-;      given in r25,r24 (r25 is most significant)
-;  param2: the 16-bit pointer to message
-;      given in r23,r22
-;  param3: 32-bit length value (length of message in bits)
-;   given in r21,r20,r19,r18
-sha1:
-sha1_prolog:
-       push r8
-       push r9
-       push r10
-       push r11
-       push r12
-       push r13
-       push r16
-       push r17
-       in r16, SPL
-       in r17, SPH
-       subi r16, 5*4+8 
-       sbci r17, 0     
-       in r0, SREG
-       cli
-       out SPL, r16
-       out SPH, r17
-       out SREG, r0
-       
-       push r25
-       push r24
-       inc r16
-       adc r17, r1
-       
-       movw r8, r18            /* backup of length*/
-       movw r10, r20
-       
-       movw r12, r22   /* backup pf msg-ptr */
-       
-       movw r24, r16
-       rcall sha1_init
-       /* if length >= 512 */
-1:
-       tst r11
-       brne 4f
-       tst r10
-       brne 4f
-       mov r19, r9
-       cpi r19, 0x02
-       brlo 4f
-       
-       movw r24, r16
-       movw r22, r12
-       rcall sha1_nextBlock
-       ldi r19, 0x64
-       add r22, r19
-       adc r23, r1
-       /* length -= 512 */
-       ldi r19, 0x02
-       sub r9, r19
-       sbc r10, r1
-       sbc r11, r1
-       rjmp 1b
-       
-4:
-       movw r24, r16
-       movw r22, r12
-       movw r20, r8
-       rcall sha1_lastBlock
-       
-       pop r24
-       pop r25
-       movw r22, r16
-       rcall sha1_ctx2hash     
-       
-sha1_epilog:
-       in r30, SPL
-       in r31, SPH
-       adiw r30, 5*4+8         
-       in r0, SREG
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG, r0
-       pop r17
-       pop r16
-       pop r13
-       pop r12
-       pop r11
-       pop r10
-       pop r9
-       pop r8
-       ret
-
-;###########################################################   
-
-
-; block MUST NOT be larger than 64 bytes
-
-.global sha1_lastBlock
-; === sha1_lastBlock ===
-; this function does padding & Co. for calculating SHA-1 hashes
-;  param1: the 16-bit pointer to sha1_ctx structure
-;      given in r25,r24 (r25 is most significant)
-;  param2: an 16-bit pointer to 64 byte block to hash
-;      given in r23,r22
-;  param3: an 16-bit integer specifing length of block in bits
-;      given in r21,r20
-sha1_lastBlock_localSpace = (SHA1_BLOCK_BITS/8+1)
-
-
-sha1_lastBlock:
-       cpi r21, 0x02
-       brlo sha1_lastBlock_prolog
-       push r25
-       push r24
-       push r23
-       push r22
-       push r21
-       push r20
-       rcall sha1_nextBlock
-       pop r20
-       pop r21
-       pop r22
-       pop r23
-       pop r24
-       pop r25
-       subi r21, 2
-       subi r23, -2
-       rjmp sha1_lastBlock
-sha1_lastBlock_prolog:
-       /* allocate space on stack */
-       in r30, SPL
-       in r31, SPH
-       in r1, SREG
-       subi r30, lo8(64)
-       sbci r31, hi8(64) /* ??? */
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG,r1
-
-       adiw r30, 1 /* SP points to next free byte on stack */
-       mov r18, r20 /* r20 = LSB(length) */
-       lsr r18
-       lsr r18
-       lsr r18
-       bst r21, 0      /* may be we should explain this ... */
-       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
-       
-       
-       movw r26, r22 /* X points to begin of msg */
-       tst r18
-       breq sha1_lastBlock_post_copy
-       mov r1, r18
-sha1_lastBlock_copy_loop:
-       ld r0, X+
-       st Z+, r0
-       dec r1
-       brne sha1_lastBlock_copy_loop
-sha1_lastBlock_post_copy:      
-sha1_lastBlock_insert_stuffing_bit:    
-       ldi r19, 0x80
-       mov r0,r19      
-       ldi r19, 0x07
-       and r19, r20 /* if we are in bitmode */
-       breq 2f /* no bitmode */
-1:     
-       lsr r0
-       dec r19
-       brne 1b
-       ld r19, X
-/* maybe we should do some ANDing here, just for safety */
-       or r0, r19
-2:     
-       st Z+, r0
-       inc r18
-
-/* checking stuff here */
-       cpi r18, 64-8+1
-       brsh 0f 
-       rjmp sha1_lastBlock_insert_zeros
-0:
-       /* oh shit, we landed here */
-       /* first we have to fill it up with zeros */
-       ldi r19, 64
-       sub r19, r18
-       breq 2f
-1:     
-       st Z+, r1
-       dec r19
-       brne 1b 
-2:     
-       sbiw r30, 63
-       sbiw r30,  1
-       movw r22, r30
-       
-       push r31
-       push r30
-       push r25
-       push r24
-       push r21
-       push r20
-       rcall sha1_nextBlock
-       pop r20
-       pop r21
-       pop r24
-       pop r25
-       pop r30
-       pop r31
-       
-       /* now we should subtract 512 from length */
-       movw r26, r24
-       adiw r26, 4*5+1 /* we can skip the lowest byte */
-       ld r19, X
-       subi r19, hi8(512)
-       st X+, r19
-       ldi r18, 6
-1:
-       ld r19, X
-       sbci r19, 0
-       st X+, r19
-       dec r18
-       brne 1b
-       
-;      clr r18 /* not neccessary ;-) */
-       /* reset Z pointer to begin of block */
-
-sha1_lastBlock_insert_zeros:   
-       ldi r19, 64-8
-       sub r19, r18
-       breq sha1_lastBlock_insert_length
-       clr r1
-1:
-       st Z+, r1       /* r1 is still zero */
-       dec r19
-       brne 1b
-
-;      rjmp sha1_lastBlock_epilog
-sha1_lastBlock_insert_length:
-       movw r26, r24   /* X points to state */
-       adiw r26, 5*4   /* X points to (state.length) */
-       adiw r30, 8             /* Z points one after the last byte of block */
-       ld r0, X+
-       add r0, r20
-       st -Z, r0
-       ld r0, X+
-       adc r0, r21
-       st -Z, r0
-       ldi r19, 6
-1:
-       ld r0, X+
-       adc r0, r1
-       st -Z, r0
-       dec r19
-       brne 1b
-
-       sbiw r30, 64-8
-       movw r22, r30
-       rcall sha1_nextBlock
-
-sha1_lastBlock_epilog:
-       in r30, SPL
-       in r31, SPH
-       in r1, SREG
-       adiw r30, 63 ; lo8(64)
-       adiw r30,  1  ; hi8(64)
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG,r1
-       clr r1
-       clr r0
-       ret
-
-/**/
-;###########################################################   
-
-.global sha1_nextBlock
-; === sha1_nextBlock ===
-; this is the core function for calculating SHA-1 hashes
-;  param1: the 16-bit pointer to sha1_ctx structure
-;      given in r25,r24 (r25 is most significant)
-;  param2: an 16-bit pointer to 64 byte block to hash
-;      given in r23,r22
-sha1_nextBlock_localSpace = (16+5+1)*4 ; 16 32-bit values for w array and 5 32-bit values for a array (total 84 byte)
-
-xtmp = 0
-xNULL = 1
-W1 = 10
-W2 = 11
-T1     = 12
-T2     = 13
-T3     = 14
-T4     = 15
-LoopC = 16
-S        = 17
-tmp1 = 18
-tmp2 = 19
-tmp3 = 20
-tmp4 = 21
-F1 = 22
-F2 = 23
-F3 = 24
-F4 = 25
-
-/* byteorder: high number <--> high significance */
-sha1_nextBlock:
- ; initial, let's make some space ready for local vars
-                        /* replace push & pop by mem ops? */
-       push r10
-       push r11
-       push r12
-       push r13
-       push r14
-       push r15
-       push r16
-       push r17
-       push r28
-       push r29
-       in r20, SPL
-       in r21, SPH
-       movw r18, r20                   ;backup SP
-;      movw r26, r20                   ; X points to free space on stack /* maybe removeable? */ 
-       movw r30, r22                   ; Z points to message
-       subi r20, lo8(sha1_nextBlock_localSpace) ;sbiw can do only up to 63
-       sbci r21, hi8(sha1_nextBlock_localSpace)
-       movw r26, r20                   ; X points to free space on stack 
-       in r0, SREG
-       cli ; we want to be uninterrupted while updating SP
-       out SPL, r20
-       out SPH, r21
-       out SREG, r0
-       
-       push r18
-       push r19 /* push old SP on new stack */
-       push r24
-       push r25 /* param1 will be needed later */
-       
-       /* load a[] with state */
-       movw 28, r24 /* load pointer to state in Y */
-       adiw r26, 1 ; X++
-
-       ldi LoopC, 5*4  
-1:     ld tmp1, Y+
-       st X+, tmp1
-       dec LoopC
-       brne 1b
-
-       movw W1, r26 /* save pointer to w[0] */
-       /* load w[] with endian fixed message */
-               /* we might also use the changeendian32() function at bottom */
-       movw r30, r22 /* mv param2 (ponter to msg) to Z */      
-       ldi LoopC, 16
-1:
-       ldd tmp1, Z+3
-       st X+, tmp1
-       ldd tmp1, Z+2
-       st X+, tmp1
-       ldd tmp1, Z+1
-       st X+, tmp1
-       ld tmp1, Z
-       st X+, tmp1
-       adiw r30, 4
-       dec LoopC
-       brne 1b
-       
-       ;clr LoopC /* LoopC is named t in FIPS 180-2 */ 
-       clr xtmp
-sha1_nextBlock_mainloop:
-       mov S, LoopC
-       lsl S
-       lsl S
-       andi S, 0x3C /* S is a bytepointer so *4 */
-       /* load w[s] */
-       movw r26, W1
-       add r26, S /* X points at w[s] */
-       adc r27, xNULL
-       ld T1, X+
-       ld T2, X+
-       ld T3, X+
-       ld T4, X+
-
-       /**/
-       push r26
-       push r27
-       push T4
-       push T3
-       push T2
-       push T1
-       in r26, SPL
-       in r27, SPH
-       adiw r26, 1
-       dbg_hexdump 4
-       pop T1
-       pop T2
-       pop T3
-       pop T4
-       pop r27
-       pop r26
-       /**/
-
-       cpi LoopC, 16
-       brlt sha1_nextBlock_mainloop_core
-       /* update w[s] */
-       ldi tmp1, 2*4
-       rcall 1f
-       ldi tmp1, 8*4
-       rcall 1f
-       ldi tmp1, 13*4
-       rcall 1f
-       rjmp 2f
-1:             /* this might be "outsourced" to save the jump above */
-       add tmp1, S
-       andi tmp1, 0x3f
-       movw r26, W1
-       add r26, tmp1
-       adc r27, xNULL
-       ld tmp2, X+
-       eor T1, tmp2
-       ld tmp2, X+
-       eor T2, tmp2
-       ld tmp2, X+
-       eor T3, tmp2
-       ld tmp2, X+
-       eor T4, tmp2
-       ret
-2:     /* now we just hav to do a ROTL(T) and save T back */
-       mov tmp2, T4
-       rol tmp2
-       rol T1
-       rol T2
-       rol T3
-       rol T4
-       movw r26, W1
-       add r26, S
-       adc r27, xNULL
-       st X+, T1
-       st X+, T2
-       st X+, T3
-       st X+, T4
-       
-sha1_nextBlock_mainloop_core:  /* ther core function; T=ROTL5(a) ....*/        
-                                                               /* T already contains w[s] */
-       movw r26, W1
-       sbiw r26, 4*1           /* X points at a[4] aka e */
-       ld tmp1, X+ 
-       add T1, tmp1
-       ld tmp1, X+ 
-       adc T2, tmp1
-       ld tmp1, X+ 
-       adc T3, tmp1
-       ld tmp1, X+ 
-       adc T4, tmp1            /* T = w[s]+e */
-       sbiw r26, 4*5           /* X points at a[0] aka a */
-       ld F1, X+ 
-       ld F2, X+ 
-       ld F3, X+ 
-       ld F4, X+ 
-       mov tmp1, F4            /* X points at a[1] aka b */
-       ldi tmp2, 5
-1:
-       rol tmp1
-       rol F1
-       rol F2
-       rol F3
-       rol F4
-       dec tmp2
-       brne 1b
-       
-       add T1, F1
-       adc T2, F2
-       adc T3, F3
-       adc T4, F4 /* T = ROTL(a,5) + e + w[s] */
-       
-       /* now we have to do this fucking conditional stuff */
-       ldi r30, lo8(sha1_nextBlock_xTable)
-       ldi r31, hi8(sha1_nextBlock_xTable)
-       add r30, xtmp
-       adc r31, xNULL
-       lpm tmp1, Z
-       cp tmp1, LoopC
-       brne 1f
-       inc xtmp
-1:     ldi r30, lo8(sha1_nextBlock_KTable)
-       ldi r31, hi8(sha1_nextBlock_KTable)
-       lsl xtmp
-       lsl xtmp
-       add r30, xtmp
-       adc r31, xNULL
-       lsr xtmp
-       lsr xtmp
-        
-       lpm tmp1, Z+
-       add T1, tmp1
-       lpm tmp1, Z+
-       adc T2, tmp1
-       lpm tmp1, Z+
-       adc T3, tmp1
-       lpm tmp1, Z+
-       adc T4, tmp1
-                       /* T = ROTL(a,5) + e + kt + w[s] */
-       
-       /* Z-4 is just pointing to kt ... */
-       movw r28, r26 /* copy X in Y */
-       adiw r30, 3*4 /* now Z points to the rigth locatin in our jump-vector-table */
-       lsr r31
-       ror r30
-               
-       icall
-       mov F1, tmp1
-       icall
-       mov F2, tmp1
-       icall
-       mov F3, tmp1
-       icall
-       
-       add T1, F1
-       adc T2, F2
-       adc T3, F3
-       adc T4, tmp1 /* T = ROTL5(a) + f_t(b,c,d) + e + k_t + w[s] */
-                                /* X points still at a[1] aka b, Y points at a[2] aka c */     
-       /* update a[] */
-sha1_nextBlock_update_a:
-       /*first we move all vars in a[] "one up" e=d, d=c, c=b, b=a*/
-       //adiw r28, 3*4  /* Y should point at a[4] aka e */
-       movw r28, W1
-       sbiw r28, 4
-       
-       ldi tmp2, 4*4 
-1:     
-       ld tmp1, -Y
-       std Y+4, tmp1
-       dec tmp2
-       brne 1b
-       /* Y points at a[0] aka a*/
-       
-       movw r28, W1
-       sbiw r28, 5*4
-       /* store T in a[0] aka a */
-       st Y+, T1
-       st Y+, T2
-       st Y+, T3
-       st Y+, T4
-       /* Y points at a[1] aka b*/
-       
-       /* rotate c */
-       ldd T1, Y+1*4
-       ldd T2, Y+1*4+1
-       ldd T3, Y+1*4+2
-       ldd T4, Y+1*4+3
-       mov tmp1, T1
-       ldi tmp2, 2
-1:     ror tmp1
-       ror T4
-       ror T3
-       ror T2
-       ror T1
-       dec tmp2
-       brne 1b
-       std Y+1*4+0, T1
-       std Y+1*4+1, T2
-       std Y+1*4+2, T3
-       std Y+1*4+3, T4
-       
-       push r27
-       push r26
-       movw r26, W1
-       sbiw r26, 4*5
-       dbg_hexdump 4*5
-       pop r26
-       pop r27
-       
-       inc LoopC
-       cpi LoopC, 80
-       brge 1f
-       rjmp sha1_nextBlock_mainloop
-/**************************************/
-1:     
-   /* littel patch */
-       sbiw r28, 4
-
-/* add a[] to state and inc length */  
-       pop r27
-       pop r26         /* now X points to state (and Y still at a[0]) */
-       ldi tmp4, 5
-1:     clc
-       ldi tmp3, 4
-2:     ld tmp1, X
-       ld tmp2, Y+
-       adc tmp1, tmp2
-       st X+, tmp1
-       dec tmp3
-       brne 2b
-       dec tmp4
-       brne 1b
-       
-       /* now length += 512 */
-       adiw r26, 1 /* we skip the least significant byte */
-       ld tmp1, X
-       ldi tmp2, hi8(512) /* 2 */
-       add tmp1, tmp2
-       st X+, tmp1
-       ldi tmp2, 6
-1:
-       ld tmp1, X
-       adc tmp1, xNULL
-       st X+, tmp1
-       dec tmp2
-       brne 1b
-       
-; EPILOG
-sha1_nextBlock_epilog:
-/* now we should clean up the stack */
-       pop r21
-       pop r20
-       in r0, SREG
-       cli ; we want to be uninterrupted while updating SP
-       out SPL, r20
-       out SPH, r21
-       out SREG, r0
-       
-       clr r1
-       pop r29
-       pop r28
-       pop r17
-       pop r16
-       pop r15
-       pop r14
-       pop r13
-       pop r12
-       pop r11
-       pop r10
-       ret
-
-sha1_nextBlock_xTable:
-.byte 20,40,60,0
-sha1_nextBlock_KTable:
-.int   0x5a827999 
-.int   0x6ed9eba1 
-.int   0x8f1bbcdc 
-.int   0xca62c1d6
-sha1_nextBlock_JumpTable:
-rjmp sha1_nextBlock_Ch
-       nop     
-rjmp sha1_nextBlock_Parity
-       nop
-rjmp sha1_nextBlock_Maj
-       nop
-rjmp sha1_nextBlock_Parity
-
-        /* X and Y still point at a[1] aka b ; return value in tmp1 */
-sha1_nextBlock_Ch:
-       ld tmp1, Y+
-       mov tmp2, tmp1
-       com tmp2
-       ldd tmp3, Y+3   /* load from c */
-       and tmp1, tmp3
-       ldd tmp3, Y+7   /* load from d */
-       and tmp2, tmp3
-       eor tmp1, tmp2
-       ret
-       
-sha1_nextBlock_Maj:
-       ld tmp1, Y+
-       mov tmp2, tmp1
-       ldd tmp3, Y+3   /* load from c */
-       and tmp1, tmp3
-       ldd tmp4, Y+7   /* load from d */
-       and tmp2, tmp4
-       eor tmp1, tmp2
-       and tmp3, tmp4
-       eor tmp1, tmp3
-       ret
-
-sha1_nextBlock_Parity:
-       ld tmp1, Y+
-       ldd tmp2, Y+3   /* load from c */
-       eor tmp1, tmp2
-       ldd tmp2, Y+7   /* load from d */
-       eor tmp1, tmp2
-       ret
-/*     
-ch_str:                        .asciz "\r\nCh"
-maj_str:               .asciz "\r\nMaj"
-parity_str:    .asciz "\r\nParity"
-*/
-;###########################################################   
-
-.global sha1_init 
-;void sha1_init(sha1_ctx_t *state){
-;      DEBUG_S("\r\nSHA1_INIT");
-;      state->h[0] = 0x67452301;
-;      state->h[1] = 0xefcdab89;
-;      state->h[2] = 0x98badcfe;
-;      state->h[3] = 0x10325476;
-;      state->h[4] = 0xc3d2e1f0;
-;      state->length = 0;
-;}
-; param1: (Func3,r24) 16-bit pointer to sha1_ctx_t struct in ram
-; modifys: Z(r30,r31), Func1, r22
-sha1_init:
-       movw r26, r24 ; (24,25) --> (26,27) load X with param1
-       ldi r30, lo8((sha1_init_vector))
-       ldi r31, hi8((sha1_init_vector))
-       ldi r22, 5*4 /* bytes to copy */
-sha1_init_vloop:       
-       lpm r23, Z+ 
-       st X+, r23
-       dec r22
-       brne sha1_init_vloop
-       ldi r22, 8
-sha1_init_lloop:
-       st X+, r1
-       dec r22
-       brne sha1_init_lloop
-       ret
-       
-sha1_init_vector:
-.int 0x67452301;
-.int 0xefcdab89;
-.int 0x98badcfe;
-.int 0x10325476;
-.int 0xc3d2e1f0;
-
diff --git a/sha1.c b/sha1.c
deleted file mode 100644 (file)
index 97cde32..0000000
--- a/sha1.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* sha1.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       sha1.c
- * \author     Daniel Otte
- * \date       2006-10-08
- * \license GPLv3 or later
- * \brief SHA-1 implementation.
- * 
- */
-#include <string.h> /* memcpy & co */
-#include <stdint.h>
-#include "config.h"
-#undef DEBUG
-#include "debug.h"
-#include "sha1.h"
-
-#define LITTLE_ENDIAN
-
-/********************************************************************************************************/
-/**
- * \brief initialises given SHA-1 context
- * 
- */
-void sha1_init(sha1_ctx_t *state){
-       DEBUG_S("\r\nSHA1_INIT");
-       state->h[0] = 0x67452301;
-       state->h[1] = 0xefcdab89;
-       state->h[2] = 0x98badcfe;
-       state->h[3] = 0x10325476;
-       state->h[4] = 0xc3d2e1f0;
-       state->length = 0;
-}
-
-/********************************************************************************************************/
-/* some helping functions */
-uint32_t rotl32(uint32_t n, uint8_t bits){
-       return ((n<<bits) | (n>>(32-bits)));
-}
-
-uint32_t change_endian32(uint32_t x){
-       return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
-}
-
-
-/* three SHA-1 inner functions */
-uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
-       DEBUG_S("\r\nCH");
-       return ((x&y)^((~x)&z));
-}
-
-uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
-       DEBUG_S("\r\nMAJ");
-       return ((x&y)^(x&z)^(y&z));
-}
-
-uint32_t parity(uint32_t x, uint32_t y, uint32_t z){
-       DEBUG_S("\r\nPARITY");
-       return ((x^y)^z);
-}
-
-/********************************************************************************************************/
-/**
- * \brief "add" a block to the hash
- * This is the core function of the hash algorithm. To understand how it's working
- * and what thoese variables do, take a look at FIPS-182. This is an "alternativ" implementation 
- */
-
-#define MASK 0x0000000f 
-
-typedef uint32_t (*pf_t)(uint32_t x, uint32_t y, uint32_t z);
-
-void sha1_nextBlock (sha1_ctx_t *state, const void* block){
-       uint32_t a[5];
-       uint32_t w[16];
-       uint32_t temp;
-       uint8_t t,s;
-       pf_t f[] = {ch,parity,maj,parity};
-       uint32_t k[4]={ 0x5a827999, 
-                                       0x6ed9eba1, 
-                                       0x8f1bbcdc, 
-                                       0xca62c1d6};
-       
-       /* load the w array (changing the endian and so) */
-       for(t=0; t<16; ++t){
-               w[t] = change_endian32(((uint32_t*)block)[t]);
-       }
-
-       uint8_t dbgi;
-       for(dbgi=0; dbgi<16; ++dbgi){
-               DEBUG_S("\n\rBlock:");
-               DEBUG_B(dbgi);
-               DEBUG_C(':');
-               #ifdef DEBUG
-                       cli_hexdump(&(w[dbgi]) ,4);
-               #endif
-       }
-       
-       
-       /* load the state */
-       memcpy(a, state->h, 5*sizeof(uint32_t));
-       
-       
-       /* the fun stuff */
-       for(t=0; t<=79; ++t){
-               s = t & MASK;
-               if(t>=16){
-                       #ifdef DEBUG
-                        DEBUG_S("\r\n ws = "); cli_hexdump(&ws, 4);
-                       #endif
-                       w[s] = rotl32( w[(s+13)&MASK] ^ w[(s+8)&MASK] ^ 
-                                w[(s+ 2)&MASK] ^ w[s] ,1);                     
-                       #ifdef DEBUG
-                        DEBUG_S(" --> ws = "); cli_hexdump(&(w[s]), 4);
-                       #endif
-               }
-               
-               uint32_t dtemp;
-               temp = rotl32(a[0],5) + (dtemp=f[t/20](a[1],a[2],a[3])) + a[4] + k[t/20] + w[s];
-               memmove(&(a[1]), &(a[0]), 4*sizeof(uint32_t)); /* e=d; d=c; c=b; b=a; */
-               a[0] = temp;
-               a[2] = rotl32(a[2],30); /* we might also do rotr32(c,2) */
-               
-               /* debug dump */
-               DEBUG_S("\r\nt = "); DEBUG_B(t);
-               DEBUG_S("; a[]: ");
-               #ifdef DEBUG
-                cli_hexdump(a, 5*4);
-               #endif
-               DEBUG_S("; k = ");
-               #ifdef DEBUG
-                cli_hexdump(&(k[t/20]), 4);
-               #endif
-               DEBUG_S("; f(b,c,d) = ");
-               #ifdef DEBUG
-                cli_hexdump(&dtemp, 4);
-               #endif
-       }
-       
-       /* update the state */
-       for(t=0; t<5; ++t){
-               state->h[t] += a[t];
-       }
-       state->length += 512;
-}
-
-/********************************************************************************************************/
-
-void sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length){
-       uint8_t lb[SHA1_BLOCK_BITS/8]; /* local block */
-       state->length += length;
-       memcpy (&(lb[0]), block, length/8);
-       
-       /* set the final one bit */
-       if (length & 0x7){ /* 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 >> 7) + 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);
-               sha1_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
-       sha1_nextBlock(state, lb);
-}
-
-/********************************************************************************************************/
-
-void sha1_ctx2hash (sha1_hash_t *dest, sha1_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
-}
-
-/********************************************************************************************************/
-/**
- * 
- * 
- */
-void sha1 (sha1_hash_t *dest, const void* msg, uint32_t length){
-       sha1_ctx_t s;
-       DEBUG_S("\r\nBLA BLUB");
-       sha1_init(&s);
-       while(length & (~0x0001ff)){ /* length>=512 */
-               DEBUG_S("\r\none block");
-               sha1_nextBlock(&s, msg);
-               msg = (uint8_t*)msg + SHA1_BLOCK_BITS/8; /* increment pointer to next block */
-               length -= SHA1_BLOCK_BITS;
-       }
-       sha1_lastBlock(&s, msg, length);
-       sha1_ctx2hash(dest, &s);
-}
-
-
diff --git a/sha1.h b/sha1.h
deleted file mode 100644 (file)
index 6675d20..0000000
--- a/sha1.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* sha1.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       sha1.h
- * \author     Daniel Otte
- * \email   daniel.otte@rub.de
- * \date       2006-10-08
- * \license GPLv3 or later
- * \brief   SHA-1 declaration.
- * \ingroup SHA-1
- * 
- */
-#ifndef SHA1_H_
-#define SHA1_H_
-
-#include <stdint.h>
-/** \def SHA1_HASH_BITS
- * definees the size of a SHA-1 hash in bits 
- */
-
-/** \def SHA1_HASH_BYTES
- * definees the size of a SHA-1 hash in bytes 
- */
-
-/** \def SHA1_BLOCK_BITS
- * definees the size of a SHA-1 input block in bits 
- */
-
-/** \def SHA1_BLOCK_BYTES
- * definees the size of a SHA-1 input block in bytes 
- */
-#define SHA1_HASH_BITS  160
-#define SHA1_HASH_BYTES (SHA1_HASH_BITS/8)
-#define SHA1_BLOCK_BITS 512
-#define SHA1_BLOCK_BYTES (SHA1_BLOCK_BITS/8)
-
-/** \typedef sha1_ctx_t
- * \brief SHA-1 context type
- * 
- * A vatiable of this type may hold the state of a SHA-1 hashing process
- */
-typedef struct {
-       uint32_t h[5];
-       uint64_t length;
-} sha1_ctx_t;
-
-/** \typedef sha1_hash_t
- * \brief hash value type
- * A variable of this type may hold a SHA-1 hash value 
- */
-typedef uint8_t sha1_hash_t[SHA1_HASH_BITS/8];
-
-/** \fn sha1_init(sha1_ctx_t *state)
- * \brief initializes a SHA-1 context
- * This function sets a ::sha1_ctx_t variable to the initialization vector
- * for SHA-1 hashing.
- * \param state pointer to the SHA-1 context variable
- */
-void sha1_init(sha1_ctx_t *state);
-
-/** \fn sha1_nextBlock(sha1_ctx_t *state, const void* block)
- *  \brief process one input block
- * This function processes one input block and updates the hash context 
- * accordingly
- * \param state pointer to the state variable to update
- * \param block pointer to the message block to process
- */
-void sha1_nextBlock (sha1_ctx_t *state, const void* block);
-
-/** \fn sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length_b)
- * \brief processes the given block and finalizes the context
- * This function processes the last block in a SHA-1 hashing process.
- * The block should have a maximum length of a single input block.
- * \param state pointer to the state variable to update and finalize
- * \param block pointer to themessage block to process
- * \param length_b length of the message block in bits  
- */
-void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
-
-/** \fn sha1_ctx2hash(sha1_hash_t *dest, sha1_ctx_t *state)
- * \brief convert a state variable into an actual hash value
- * Writes the hash value corresponding to the state to the memory pointed by dest.
- * \param dest pointer to the hash value destination
- * \param state pointer to the hash context
- */ 
-void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
-
-/** \fn sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b)
- * \brief hashing a message which in located entirely in RAM
- * This function automatically hashes a message which is entirely in RAM with
- * the SHA-1 hashing algorithm.
- * \param dest pointer to the hash value destination
- * \param msg  pointer to the message which should be hashed
- * \param length_b length of the message in bits
- */ 
-void sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b);
-
-
-
-#endif /*SHA1_H_*/
diff --git a/sha1/sha1-asm.S b/sha1/sha1-asm.S
new file mode 100644 (file)
index 0000000..f571685
--- /dev/null
@@ -0,0 +1,886 @@
+/* sha1-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; SHA1 implementation in assembler for AVR
+SHA1_BLOCK_BITS = 512
+SHA1_HASH_BITS = 160
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+.macro delay
+/*     
+       push r0
+       push r1
+       clr r0
+1:     clr r1
+2:     dec r1
+       brne 2b
+       dec r0
+       brne 1b
+       pop r1
+       pop r0  // */
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+/*     
+       precall
+       hexdump \length
+       postcall
+       // */
+.endm
+
+
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha1_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha1_ctx2hash
+; === sha1_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha1_ctx structure
+;      given in r23,r22
+sha1_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 5
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha1
+; === sha1 ===
+; this function calculates SHA-1 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha1:
+sha1_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 5*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha1_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha1_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha1_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha1_ctx2hash     
+       
+sha1_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 5*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha1_lastBlock
+; === sha1_lastBlock ===
+; this function does padding & Co. for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha1_lastBlock_localSpace = (SHA1_BLOCK_BITS/8+1)
+
+
+sha1_lastBlock:
+       cpi r21, 0x02
+       brlo sha1_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 2
+       subi r23, -2
+       rjmp sha1_lastBlock
+sha1_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64) /* ??? */
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha1_lastBlock_post_copy
+       mov r1, r18
+sha1_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha1_lastBlock_copy_loop
+sha1_lastBlock_post_copy:      
+sha1_lastBlock_insert_stuffing_bit:    
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha1_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*5+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha1_lastBlock_insert_zeros:   
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha1_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha1_lastBlock_epilog
+sha1_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 5*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha1_nextBlock
+
+sha1_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha1_nextBlock
+; === sha1_nextBlock ===
+; this is the core function for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha1_nextBlock_localSpace = (16+5+1)*4 ; 16 32-bit values for w array and 5 32-bit values for a array (total 84 byte)
+
+xtmp = 0
+xNULL = 1
+W1 = 10
+W2 = 11
+T1     = 12
+T2     = 13
+T3     = 14
+T4     = 15
+LoopC = 16
+S        = 17
+tmp1 = 18
+tmp2 = 19
+tmp3 = 20
+tmp4 = 21
+F1 = 22
+F2 = 23
+F3 = 24
+F4 = 25
+
+/* byteorder: high number <--> high significance */
+sha1_nextBlock:
+ ; initial, let's make some space ready for local vars
+                        /* replace push & pop by mem ops? */
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack /* maybe removeable? */ 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha1_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha1_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       push r18
+       push r19 /* push old SP on new stack */
+       push r24
+       push r25 /* param1 will be needed later */
+       
+       /* load a[] with state */
+       movw 28, r24 /* load pointer to state in Y */
+       adiw r26, 1 ; X++
+
+       ldi LoopC, 5*4  
+1:     ld tmp1, Y+
+       st X+, tmp1
+       dec LoopC
+       brne 1b
+
+       movw W1, r26 /* save pointer to w[0] */
+       /* load w[] with endian fixed message */
+               /* we might also use the changeendian32() function at bottom */
+       movw r30, r22 /* mv param2 (ponter to msg) to Z */      
+       ldi LoopC, 16
+1:
+       ldd tmp1, Z+3
+       st X+, tmp1
+       ldd tmp1, Z+2
+       st X+, tmp1
+       ldd tmp1, Z+1
+       st X+, tmp1
+       ld tmp1, Z
+       st X+, tmp1
+       adiw r30, 4
+       dec LoopC
+       brne 1b
+       
+       ;clr LoopC /* LoopC is named t in FIPS 180-2 */ 
+       clr xtmp
+sha1_nextBlock_mainloop:
+       mov S, LoopC
+       lsl S
+       lsl S
+       andi S, 0x3C /* S is a bytepointer so *4 */
+       /* load w[s] */
+       movw r26, W1
+       add r26, S /* X points at w[s] */
+       adc r27, xNULL
+       ld T1, X+
+       ld T2, X+
+       ld T3, X+
+       ld T4, X+
+
+       /**/
+       push r26
+       push r27
+       push T4
+       push T3
+       push T2
+       push T1
+       in r26, SPL
+       in r27, SPH
+       adiw r26, 1
+       dbg_hexdump 4
+       pop T1
+       pop T2
+       pop T3
+       pop T4
+       pop r27
+       pop r26
+       /**/
+
+       cpi LoopC, 16
+       brlt sha1_nextBlock_mainloop_core
+       /* update w[s] */
+       ldi tmp1, 2*4
+       rcall 1f
+       ldi tmp1, 8*4
+       rcall 1f
+       ldi tmp1, 13*4
+       rcall 1f
+       rjmp 2f
+1:             /* this might be "outsourced" to save the jump above */
+       add tmp1, S
+       andi tmp1, 0x3f
+       movw r26, W1
+       add r26, tmp1
+       adc r27, xNULL
+       ld tmp2, X+
+       eor T1, tmp2
+       ld tmp2, X+
+       eor T2, tmp2
+       ld tmp2, X+
+       eor T3, tmp2
+       ld tmp2, X+
+       eor T4, tmp2
+       ret
+2:     /* now we just hav to do a ROTL(T) and save T back */
+       mov tmp2, T4
+       rol tmp2
+       rol T1
+       rol T2
+       rol T3
+       rol T4
+       movw r26, W1
+       add r26, S
+       adc r27, xNULL
+       st X+, T1
+       st X+, T2
+       st X+, T3
+       st X+, T4
+       
+sha1_nextBlock_mainloop_core:  /* ther core function; T=ROTL5(a) ....*/        
+                                                               /* T already contains w[s] */
+       movw r26, W1
+       sbiw r26, 4*1           /* X points at a[4] aka e */
+       ld tmp1, X+ 
+       add T1, tmp1
+       ld tmp1, X+ 
+       adc T2, tmp1
+       ld tmp1, X+ 
+       adc T3, tmp1
+       ld tmp1, X+ 
+       adc T4, tmp1            /* T = w[s]+e */
+       sbiw r26, 4*5           /* X points at a[0] aka a */
+       ld F1, X+ 
+       ld F2, X+ 
+       ld F3, X+ 
+       ld F4, X+ 
+       mov tmp1, F4            /* X points at a[1] aka b */
+       ldi tmp2, 5
+1:
+       rol tmp1
+       rol F1
+       rol F2
+       rol F3
+       rol F4
+       dec tmp2
+       brne 1b
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, F4 /* T = ROTL(a,5) + e + w[s] */
+       
+       /* now we have to do this fucking conditional stuff */
+       ldi r30, lo8(sha1_nextBlock_xTable)
+       ldi r31, hi8(sha1_nextBlock_xTable)
+       add r30, xtmp
+       adc r31, xNULL
+       lpm tmp1, Z
+       cp tmp1, LoopC
+       brne 1f
+       inc xtmp
+1:     ldi r30, lo8(sha1_nextBlock_KTable)
+       ldi r31, hi8(sha1_nextBlock_KTable)
+       lsl xtmp
+       lsl xtmp
+       add r30, xtmp
+       adc r31, xNULL
+       lsr xtmp
+       lsr xtmp
+        
+       lpm tmp1, Z+
+       add T1, tmp1
+       lpm tmp1, Z+
+       adc T2, tmp1
+       lpm tmp1, Z+
+       adc T3, tmp1
+       lpm tmp1, Z+
+       adc T4, tmp1
+                       /* T = ROTL(a,5) + e + kt + w[s] */
+       
+       /* Z-4 is just pointing to kt ... */
+       movw r28, r26 /* copy X in Y */
+       adiw r30, 3*4 /* now Z points to the rigth locatin in our jump-vector-table */
+       lsr r31
+       ror r30
+               
+       icall
+       mov F1, tmp1
+       icall
+       mov F2, tmp1
+       icall
+       mov F3, tmp1
+       icall
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, tmp1 /* T = ROTL5(a) + f_t(b,c,d) + e + k_t + w[s] */
+                                /* X points still at a[1] aka b, Y points at a[2] aka c */     
+       /* update a[] */
+sha1_nextBlock_update_a:
+       /*first we move all vars in a[] "one up" e=d, d=c, c=b, b=a*/
+       //adiw r28, 3*4  /* Y should point at a[4] aka e */
+       movw r28, W1
+       sbiw r28, 4
+       
+       ldi tmp2, 4*4 
+1:     
+       ld tmp1, -Y
+       std Y+4, tmp1
+       dec tmp2
+       brne 1b
+       /* Y points at a[0] aka a*/
+       
+       movw r28, W1
+       sbiw r28, 5*4
+       /* store T in a[0] aka a */
+       st Y+, T1
+       st Y+, T2
+       st Y+, T3
+       st Y+, T4
+       /* Y points at a[1] aka b*/
+       
+       /* rotate c */
+       ldd T1, Y+1*4
+       ldd T2, Y+1*4+1
+       ldd T3, Y+1*4+2
+       ldd T4, Y+1*4+3
+       mov tmp1, T1
+       ldi tmp2, 2
+1:     ror tmp1
+       ror T4
+       ror T3
+       ror T2
+       ror T1
+       dec tmp2
+       brne 1b
+       std Y+1*4+0, T1
+       std Y+1*4+1, T2
+       std Y+1*4+2, T3
+       std Y+1*4+3, T4
+       
+       push r27
+       push r26
+       movw r26, W1
+       sbiw r26, 4*5
+       dbg_hexdump 4*5
+       pop r26
+       pop r27
+       
+       inc LoopC
+       cpi LoopC, 80
+       brge 1f
+       rjmp sha1_nextBlock_mainloop
+/**************************************/
+1:     
+   /* littel patch */
+       sbiw r28, 4
+
+/* add a[] to state and inc length */  
+       pop r27
+       pop r26         /* now X points to state (and Y still at a[0]) */
+       ldi tmp4, 5
+1:     clc
+       ldi tmp3, 4
+2:     ld tmp1, X
+       ld tmp2, Y+
+       adc tmp1, tmp2
+       st X+, tmp1
+       dec tmp3
+       brne 2b
+       dec tmp4
+       brne 1b
+       
+       /* now length += 512 */
+       adiw r26, 1 /* we skip the least significant byte */
+       ld tmp1, X
+       ldi tmp2, hi8(512) /* 2 */
+       add tmp1, tmp2
+       st X+, tmp1
+       ldi tmp2, 6
+1:
+       ld tmp1, X
+       adc tmp1, xNULL
+       st X+, tmp1
+       dec tmp2
+       brne 1b
+       
+; EPILOG
+sha1_nextBlock_epilog:
+/* now we should clean up the stack */
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       ret
+
+sha1_nextBlock_xTable:
+.byte 20,40,60,0
+sha1_nextBlock_KTable:
+.int   0x5a827999 
+.int   0x6ed9eba1 
+.int   0x8f1bbcdc 
+.int   0xca62c1d6
+sha1_nextBlock_JumpTable:
+rjmp sha1_nextBlock_Ch
+       nop     
+rjmp sha1_nextBlock_Parity
+       nop
+rjmp sha1_nextBlock_Maj
+       nop
+rjmp sha1_nextBlock_Parity
+
+        /* X and Y still point at a[1] aka b ; return value in tmp1 */
+sha1_nextBlock_Ch:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       com tmp2
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp3, Y+7   /* load from d */
+       and tmp2, tmp3
+       eor tmp1, tmp2
+       ret
+       
+sha1_nextBlock_Maj:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp4, Y+7   /* load from d */
+       and tmp2, tmp4
+       eor tmp1, tmp2
+       and tmp3, tmp4
+       eor tmp1, tmp3
+       ret
+
+sha1_nextBlock_Parity:
+       ld tmp1, Y+
+       ldd tmp2, Y+3   /* load from c */
+       eor tmp1, tmp2
+       ldd tmp2, Y+7   /* load from d */
+       eor tmp1, tmp2
+       ret
+/*     
+ch_str:                        .asciz "\r\nCh"
+maj_str:               .asciz "\r\nMaj"
+parity_str:    .asciz "\r\nParity"
+*/
+;###########################################################   
+
+.global sha1_init 
+;void sha1_init(sha1_ctx_t *state){
+;      DEBUG_S("\r\nSHA1_INIT");
+;      state->h[0] = 0x67452301;
+;      state->h[1] = 0xefcdab89;
+;      state->h[2] = 0x98badcfe;
+;      state->h[3] = 0x10325476;
+;      state->h[4] = 0xc3d2e1f0;
+;      state->length = 0;
+;}
+; param1: (Func3,r24) 16-bit pointer to sha1_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha1_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha1_init_vector))
+       ldi r31, hi8((sha1_init_vector))
+       ldi r22, 5*4 /* bytes to copy */
+sha1_init_vloop:       
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha1_init_vloop
+       ldi r22, 8
+sha1_init_lloop:
+       st X+, r1
+       dec r22
+       brne sha1_init_lloop
+       ret
+       
+sha1_init_vector:
+.int 0x67452301;
+.int 0xefcdab89;
+.int 0x98badcfe;
+.int 0x10325476;
+.int 0xc3d2e1f0;
+
diff --git a/sha1/sha1.c b/sha1/sha1.c
new file mode 100644 (file)
index 0000000..97cde32
--- /dev/null
@@ -0,0 +1,236 @@
+/* sha1.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha1.c
+ * \author     Daniel Otte
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief SHA-1 implementation.
+ * 
+ */
+#include <string.h> /* memcpy & co */
+#include <stdint.h>
+#include "config.h"
+#undef DEBUG
+#include "debug.h"
+#include "sha1.h"
+
+#define LITTLE_ENDIAN
+
+/********************************************************************************************************/
+/**
+ * \brief initialises given SHA-1 context
+ * 
+ */
+void sha1_init(sha1_ctx_t *state){
+       DEBUG_S("\r\nSHA1_INIT");
+       state->h[0] = 0x67452301;
+       state->h[1] = 0xefcdab89;
+       state->h[2] = 0x98badcfe;
+       state->h[3] = 0x10325476;
+       state->h[4] = 0xc3d2e1f0;
+       state->length = 0;
+}
+
+/********************************************************************************************************/
+/* some helping functions */
+uint32_t rotl32(uint32_t n, uint8_t bits){
+       return ((n<<bits) | (n>>(32-bits)));
+}
+
+uint32_t change_endian32(uint32_t x){
+       return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
+}
+
+
+/* three SHA-1 inner functions */
+uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
+       DEBUG_S("\r\nCH");
+       return ((x&y)^((~x)&z));
+}
+
+uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
+       DEBUG_S("\r\nMAJ");
+       return ((x&y)^(x&z)^(y&z));
+}
+
+uint32_t parity(uint32_t x, uint32_t y, uint32_t z){
+       DEBUG_S("\r\nPARITY");
+       return ((x^y)^z);
+}
+
+/********************************************************************************************************/
+/**
+ * \brief "add" a block to the hash
+ * This is the core function of the hash algorithm. To understand how it's working
+ * and what thoese variables do, take a look at FIPS-182. This is an "alternativ" implementation 
+ */
+
+#define MASK 0x0000000f 
+
+typedef uint32_t (*pf_t)(uint32_t x, uint32_t y, uint32_t z);
+
+void sha1_nextBlock (sha1_ctx_t *state, const void* block){
+       uint32_t a[5];
+       uint32_t w[16];
+       uint32_t temp;
+       uint8_t t,s;
+       pf_t f[] = {ch,parity,maj,parity};
+       uint32_t k[4]={ 0x5a827999, 
+                                       0x6ed9eba1, 
+                                       0x8f1bbcdc, 
+                                       0xca62c1d6};
+       
+       /* load the w array (changing the endian and so) */
+       for(t=0; t<16; ++t){
+               w[t] = change_endian32(((uint32_t*)block)[t]);
+       }
+
+       uint8_t dbgi;
+       for(dbgi=0; dbgi<16; ++dbgi){
+               DEBUG_S("\n\rBlock:");
+               DEBUG_B(dbgi);
+               DEBUG_C(':');
+               #ifdef DEBUG
+                       cli_hexdump(&(w[dbgi]) ,4);
+               #endif
+       }
+       
+       
+       /* load the state */
+       memcpy(a, state->h, 5*sizeof(uint32_t));
+       
+       
+       /* the fun stuff */
+       for(t=0; t<=79; ++t){
+               s = t & MASK;
+               if(t>=16){
+                       #ifdef DEBUG
+                        DEBUG_S("\r\n ws = "); cli_hexdump(&ws, 4);
+                       #endif
+                       w[s] = rotl32( w[(s+13)&MASK] ^ w[(s+8)&MASK] ^ 
+                                w[(s+ 2)&MASK] ^ w[s] ,1);                     
+                       #ifdef DEBUG
+                        DEBUG_S(" --> ws = "); cli_hexdump(&(w[s]), 4);
+                       #endif
+               }
+               
+               uint32_t dtemp;
+               temp = rotl32(a[0],5) + (dtemp=f[t/20](a[1],a[2],a[3])) + a[4] + k[t/20] + w[s];
+               memmove(&(a[1]), &(a[0]), 4*sizeof(uint32_t)); /* e=d; d=c; c=b; b=a; */
+               a[0] = temp;
+               a[2] = rotl32(a[2],30); /* we might also do rotr32(c,2) */
+               
+               /* debug dump */
+               DEBUG_S("\r\nt = "); DEBUG_B(t);
+               DEBUG_S("; a[]: ");
+               #ifdef DEBUG
+                cli_hexdump(a, 5*4);
+               #endif
+               DEBUG_S("; k = ");
+               #ifdef DEBUG
+                cli_hexdump(&(k[t/20]), 4);
+               #endif
+               DEBUG_S("; f(b,c,d) = ");
+               #ifdef DEBUG
+                cli_hexdump(&dtemp, 4);
+               #endif
+       }
+       
+       /* update the state */
+       for(t=0; t<5; ++t){
+               state->h[t] += a[t];
+       }
+       state->length += 512;
+}
+
+/********************************************************************************************************/
+
+void sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length){
+       uint8_t lb[SHA1_BLOCK_BITS/8]; /* local block */
+       state->length += length;
+       memcpy (&(lb[0]), block, length/8);
+       
+       /* set the final one bit */
+       if (length & 0x7){ /* 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 >> 7) + 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);
+               sha1_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
+       sha1_nextBlock(state, lb);
+}
+
+/********************************************************************************************************/
+
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_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
+}
+
+/********************************************************************************************************/
+/**
+ * 
+ * 
+ */
+void sha1 (sha1_hash_t *dest, const void* msg, uint32_t length){
+       sha1_ctx_t s;
+       DEBUG_S("\r\nBLA BLUB");
+       sha1_init(&s);
+       while(length & (~0x0001ff)){ /* length>=512 */
+               DEBUG_S("\r\none block");
+               sha1_nextBlock(&s, msg);
+               msg = (uint8_t*)msg + SHA1_BLOCK_BITS/8; /* increment pointer to next block */
+               length -= SHA1_BLOCK_BITS;
+       }
+       sha1_lastBlock(&s, msg, length);
+       sha1_ctx2hash(dest, &s);
+}
+
+
diff --git a/sha1/sha1.h b/sha1/sha1.h
new file mode 100644 (file)
index 0000000..6675d20
--- /dev/null
@@ -0,0 +1,117 @@
+/* sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha1.h
+ * \author     Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief   SHA-1 declaration.
+ * \ingroup SHA-1
+ * 
+ */
+#ifndef SHA1_H_
+#define SHA1_H_
+
+#include <stdint.h>
+/** \def SHA1_HASH_BITS
+ * definees the size of a SHA-1 hash in bits 
+ */
+
+/** \def SHA1_HASH_BYTES
+ * definees the size of a SHA-1 hash in bytes 
+ */
+
+/** \def SHA1_BLOCK_BITS
+ * definees the size of a SHA-1 input block in bits 
+ */
+
+/** \def SHA1_BLOCK_BYTES
+ * definees the size of a SHA-1 input block in bytes 
+ */
+#define SHA1_HASH_BITS  160
+#define SHA1_HASH_BYTES (SHA1_HASH_BITS/8)
+#define SHA1_BLOCK_BITS 512
+#define SHA1_BLOCK_BYTES (SHA1_BLOCK_BITS/8)
+
+/** \typedef sha1_ctx_t
+ * \brief SHA-1 context type
+ * 
+ * A vatiable of this type may hold the state of a SHA-1 hashing process
+ */
+typedef struct {
+       uint32_t h[5];
+       uint64_t length;
+} sha1_ctx_t;
+
+/** \typedef sha1_hash_t
+ * \brief hash value type
+ * A variable of this type may hold a SHA-1 hash value 
+ */
+typedef uint8_t sha1_hash_t[SHA1_HASH_BITS/8];
+
+/** \fn sha1_init(sha1_ctx_t *state)
+ * \brief initializes a SHA-1 context
+ * This function sets a ::sha1_ctx_t variable to the initialization vector
+ * for SHA-1 hashing.
+ * \param state pointer to the SHA-1 context variable
+ */
+void sha1_init(sha1_ctx_t *state);
+
+/** \fn sha1_nextBlock(sha1_ctx_t *state, const void* block)
+ *  \brief process one input block
+ * This function processes one input block and updates the hash context 
+ * accordingly
+ * \param state pointer to the state variable to update
+ * \param block pointer to the message block to process
+ */
+void sha1_nextBlock (sha1_ctx_t *state, const void* block);
+
+/** \fn sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length_b)
+ * \brief processes the given block and finalizes the context
+ * This function processes the last block in a SHA-1 hashing process.
+ * The block should have a maximum length of a single input block.
+ * \param state pointer to the state variable to update and finalize
+ * \param block pointer to themessage block to process
+ * \param length_b length of the message block in bits  
+ */
+void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
+
+/** \fn sha1_ctx2hash(sha1_hash_t *dest, sha1_ctx_t *state)
+ * \brief convert a state variable into an actual hash value
+ * Writes the hash value corresponding to the state to the memory pointed by dest.
+ * \param dest pointer to the hash value destination
+ * \param state pointer to the hash context
+ */ 
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
+
+/** \fn sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b)
+ * \brief hashing a message which in located entirely in RAM
+ * This function automatically hashes a message which is entirely in RAM with
+ * the SHA-1 hashing algorithm.
+ * \param dest pointer to the hash value destination
+ * \param msg  pointer to the message which should be hashed
+ * \param length_b length of the message in bits
+ */ 
+void sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b);
+
+
+
+#endif /*SHA1_H_*/
diff --git a/sha256-asm.S b/sha256-asm.S
deleted file mode 100644 (file)
index d9eb6b6..0000000
+++ /dev/null
@@ -1,1042 +0,0 @@
-/* sha256-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * Author:     Daniel Otte
- *
- * License: GPLv3 or later
-*/
-; sha-256 implementation in assembler  
-SHA256_BLOCK_BITS = 512
-SHA256_HASH_BITS = 256
-
-.macro precall
-       /* push r18 - r27, r30 - r31*/
-       push r0
-       push r1
-       push r18
-       push r19
-       push r20
-       push r21
-       push r22
-       push r23
-       push r24
-       push r25
-       push r26
-       push r27
-       push r30
-       push r31
-       clr r1
-.endm
-
-.macro postcall
-       pop r31
-       pop r30
-       pop r27
-       pop r26
-       pop r25
-       pop r24
-       pop r23
-       pop r22
-       pop r21
-       pop r20
-       pop r19
-       pop r18
-       pop r1
-       pop r0
-.endm
-
-
-.macro hexdump length
-       push r27
-       push r26
-       ldi r25, '\r'
-       mov r24, r25
-       call uart_putc
-       ldi r25, '\n'
-       mov r24, r25
-       call uart_putc
-       pop r26
-       pop r27
-       movw r24, r26
-.if \length > 16
-       ldi r22, lo8(16)
-       ldi r23, hi8(16)
-       push r27
-       push r26
-       call uart_hexdump
-       pop r26
-       pop r27
-       adiw r26, 16
-       hexdump \length-16
-.else
-       ldi r22, lo8(\length)
-       ldi r23, hi8(\length)
-       call uart_hexdump
-.endif
-.endm
-
-/* X points to Block */
-.macro dbg_hexdump length
-       precall
-       hexdump \length
-       postcall
-.endm
-
-.section .text
-
-SPL = 0x3D
-SPH = 0x3E
-SREG = 0x3F
-
-
-;
-;sha256_ctx_t is:
-;
-; [h0][h1][h2][h3][h4][h5][h6][h7][length]
-; hn is 32 bit large, length is 64 bit large
-
-;###########################################################   
-
-.global sha256_ctx2hash
-; === sha256_ctx2hash ===
-; this function converts a state into a normal hash (bytestring)
-;  param1: the 16-bit destination pointer
-;      given in r25,r24 (r25 is most significant)
-;  param2: the 16-bit pointer to sha256_ctx structure
-;      given in r23,r22
-sha256_ctx2hash:
-       movw r26, r22
-       movw r30, r24
-       ldi r21, 8
-       sbiw r26, 4
-1:     
-       ldi r20, 4
-       adiw r26, 8
-2:     
-               ld r0, -X
-               st Z+, r0       
-       dec r20
-       brne 2b
-       
-       dec r21
-       brne 1b
-       
-       ret
-
-;###########################################################   
-
-.global sha256
-; === sha256 ===
-; this function calculates SHA-256 hashes from messages in RAM
-;  param1: the 16-bit hash destination pointer
-;      given in r25,r24 (r25 is most significant)
-;  param2: the 16-bit pointer to message
-;      given in r23,r22
-;  param3: 32-bit length value (length of message in bits)
-;   given in r21,r20,r19,r18
-sha256:
-sha256_prolog:
-       push r8
-       push r9
-       push r10
-       push r11
-       push r12
-       push r13
-       push r16
-       push r17
-       in r16, SPL
-       in r17, SPH
-       subi r16, 8*4+8 
-       sbci r17, 0     
-       in r0, SREG
-       cli
-       out SPL, r16
-       out SPH, r17
-       out SREG, r0
-       
-       push r25
-       push r24
-       inc r16
-       adc r17, r1
-       
-       movw r8, r18            /* backup of length*/
-       movw r10, r20
-       
-       movw r12, r22   /* backup pf msg-ptr */
-       
-       movw r24, r16
-       rcall sha256_init
-       /* if length >= 512 */
-1:
-       tst r11
-       brne 4f
-       tst r10
-       brne 4f
-       mov r19, r9
-       cpi r19, 0x02
-       brlo 4f
-       
-       movw r24, r16
-       movw r22, r12
-       rcall sha256_nextBlock
-       ldi r19, 0x64
-       add r22, r19
-       adc r23, r1
-       /* length -= 512 */
-       ldi r19, 0x02
-       sub r9, r19
-       sbc r10, r1
-       sbc r11, r1
-       rjmp 1b
-       
-4:
-       movw r24, r16
-       movw r22, r12
-       movw r20, r8
-       rcall sha256_lastBlock
-       
-       pop r24
-       pop r25
-       movw r22, r16
-       rcall sha256_ctx2hash   
-       
-sha256_epilog:
-       in r30, SPL
-       in r31, SPH
-       adiw r30, 8*4+8         
-       in r0, SREG
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG, r0
-       pop r17
-       pop r16
-       pop r13
-       pop r12
-       pop r11
-       pop r10
-       pop r9
-       pop r8
-       ret
-
-;###########################################################   
-
-
-; block MUST NOT be larger than 64 bytes
-
-.global sha256_lastBlock
-; === sha256_lastBlock ===
-; this function does padding & Co. for calculating SHA-256 hashes
-;  param1: the 16-bit pointer to sha256_ctx structure
-;      given in r25,r24 (r25 is most significant)
-;  param2: an 16-bit pointer to 64 byte block to hash
-;      given in r23,r22
-;  param3: an 16-bit integer specifing length of block in bits
-;      given in r21,r20
-sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
-
-
-sha256_lastBlock:
-       cpi r21, 0x02
-       brlo sha256_lastBlock_prolog
-       push r25
-       push r24
-       push r23
-       push r22
-       push r21
-       push r20
-       rcall sha256_nextBlock
-       pop r20
-       pop r21
-       pop r22
-       pop r23
-       pop r24
-       pop r25
-       subi r21, 0x02
-       subi r23, -2
-       rjmp sha256_lastBlock   
-sha256_lastBlock_prolog:
-       /* allocate space on stack */
-       in r30, SPL
-       in r31, SPH
-       in r1, SREG
-       subi r30, lo8(64)
-       sbci r31, hi8(64)
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG,r1
-
-       adiw r30, 1 /* SP points to next free byte on stack */
-       mov r18, r20 /* r20 = LSB(length) */
-       lsr r18
-       lsr r18
-       lsr r18
-       bst r21, 0      /* may be we should explain this ... */
-       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
-       
-       
-       movw r26, r22 /* X points to begin of msg */
-       tst r18
-       breq sha256_lastBlock_post_copy
-       mov r1, r18
-sha256_lastBlock_copy_loop:
-       ld r0, X+
-       st Z+, r0
-       dec r1
-       brne sha256_lastBlock_copy_loop
-sha256_lastBlock_post_copy:    
-sha256_lastBlock_insert_stuffing_bit:  
-       ldi r19, 0x80
-       mov r0,r19      
-       ldi r19, 0x07
-       and r19, r20 /* if we are in bitmode */
-       breq 2f /* no bitmode */
-1:     
-       lsr r0
-       dec r19
-       brne 1b
-       ld r19, X
-/* maybe we should do some ANDing here, just for safety */
-       or r0, r19
-2:     
-       st Z+, r0
-       inc r18
-
-/* checking stuff here */
-       cpi r18, 64-8+1
-       brsh 0f 
-       rjmp sha256_lastBlock_insert_zeros
-0:
-       /* oh shit, we landed here */
-       /* first we have to fill it up with zeros */
-       ldi r19, 64
-       sub r19, r18
-       breq 2f
-1:     
-       st Z+, r1
-       dec r19
-       brne 1b 
-2:     
-       sbiw r30, 63
-       sbiw r30,  1
-       movw r22, r30
-       
-       push r31
-       push r30
-       push r25
-       push r24
-       push r21
-       push r20
-       rcall sha256_nextBlock
-       pop r20
-       pop r21
-       pop r24
-       pop r25
-       pop r30
-       pop r31
-       
-       /* now we should subtract 512 from length */
-       movw r26, r24
-       adiw r26, 4*8+1 /* we can skip the lowest byte */
-       ld r19, X
-       subi r19, hi8(512)
-       st X+, r19
-       ldi r18, 6
-1:
-       ld r19, X
-       sbci r19, 0
-       st X+, r19
-       dec r18
-       brne 1b
-       
-;      clr r18 /* not neccessary ;-) */
-       /* reset Z pointer to begin of block */
-
-sha256_lastBlock_insert_zeros: 
-       ldi r19, 64-8
-       sub r19, r18
-       breq sha256_lastBlock_insert_length
-       clr r1
-1:
-       st Z+, r1       /* r1 is still zero */
-       dec r19
-       brne 1b
-
-;      rjmp sha256_lastBlock_epilog
-sha256_lastBlock_insert_length:
-       movw r26, r24   /* X points to state */
-       adiw r26, 8*4   /* X points to (state.length) */
-       adiw r30, 8             /* Z points one after the last byte of block */
-       ld r0, X+
-       add r0, r20
-       st -Z, r0
-       ld r0, X+
-       adc r0, r21
-       st -Z, r0
-       ldi r19, 6
-1:
-       ld r0, X+
-       adc r0, r1
-       st -Z, r0
-       dec r19
-       brne 1b
-
-       sbiw r30, 64-8
-       movw r22, r30
-       rcall sha256_nextBlock
-
-sha256_lastBlock_epilog:
-       in r30, SPL
-       in r31, SPH
-       in r1, SREG
-       adiw r30, 63 ; lo8(64)
-       adiw r30,  1  ; hi8(64)
-       cli
-       out SPL, r30
-       out SPH, r31
-       out SREG,r1
-       clr r1
-       clr r0
-       ret
-
-/**/
-;###########################################################   
-
-.global sha256_nextBlock
-; === sha256_nextBlock ===
-; this is the core function for calculating SHA-256 hashes
-;  param1: the 16-bit pointer to sha256_ctx structure
-;      given in r25,r24 (r25 is most significant)
-;  param2: an 16-bit pointer to 64 byte block to hash
-;      given in r23,r22
-sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
-
-Bck1 = 12
-Bck2 = 13
-Bck3 = 14
-Bck4 = 15
-Func1 = 22
-Func2 = 23
-Func3 = 24
-Func4 = 25
-Accu1 = 16
-Accu2 = 17
-Accu3 = 18
-Accu4 = 19
-XAccu1 = 8
-XAccu2 = 9
-XAccu3 = 10
-XAccu4 = 11
-T1     = 4
-T2     = 5
-T3     = 6
-T4     = 7
-LoopC = 1
-/* byteorder: high number <--> high significance */
-sha256_nextBlock:
- ; initial, let's make some space ready for local vars
-       push r4 /* replace push & pop by mem ops? */
-       push r5
-       push r6
-       push r7
-       push r8
-       push r9
-       push r10
-       push r11
-       push r12
-       push r13
-       push r14
-       push r15
-       push r16
-       push r17
-       push r28
-       push r29
-       in r20, SPL
-       in r21, SPH
-       movw r18, r20                   ;backup SP
-;      movw r26, r20                   ; X points to free space on stack 
-       movw r30, r22                   ; Z points to message
-       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
-       sbci r21, hi8(sha256_nextBlock_localSpace)
-       movw r26, r20                   ; X points to free space on stack 
-       in r0, SREG
-       cli ; we want to be uninterrupted while updating SP
-       out SPL, r20
-       out SPH, r21
-       out SREG, r0
-       push r18
-       push r19
-       push r24
-       push r25 /* param1 will be needed later */
- ; now we fill the w array with message (think about endianess)
-       adiw r26, 1 ; X++
-       ldi r20, 16
-sha256_nextBlock_wcpyloop:     
-       ld r23, Z+
-       ld r22, Z+
-       ld r19, Z+
-       ld r18, Z+
-       st X+, r18
-       st X+, r19
-       st X+, r22      
-       st X+, r23
-       dec r20
-       brne sha256_nextBlock_wcpyloop
-/*     for (i=16; i<64; ++i){
-               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
-       } */
-       /* r25,r24,r23,r24 (r21,r20) are function values
-          r19,r18,r17,r16 are the accumulator
-          r15,r14,r13,rBck1 are backup1
-          r11,r10,r9 ,r8  are xor accu   
-          r1 is round counter                                                          */
-
-       ldi r20, 64-16
-       mov LoopC, r20
-sha256_nextBlock_wcalcloop:             
-       movw r30, r26 ; cp X to Z
-       sbiw r30, 63
-       sbiw r30, 1             ; substract 64 = 16*4
-       ld Accu1, Z+
-       ld Accu2, Z+
-       ld Accu3, Z+
-       ld Accu4, Z+ /* w[i] = w[i-16] */
-       ld Bck1, Z+
-       ld Bck2, Z+
-       ld Bck3, Z+
-       ld Bck4, Z+ /* backup = w[i-15] */
-       /* now sigma 0 */
-       mov Func1, Bck2
-       mov Func2, Bck3
-       mov Func3, Bck4
-       mov Func4, Bck1  /* prerotated by 8 */
-       ldi r20, 1
-       rcall bitrotl
-       movw XAccu1, Func1
-       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
-       movw Func1, Bck3
-       movw Func3, Bck1 /* prerotated by 16 */
-       ldi r20, 2
-       rcall bitrotr
-       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4
-       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
-sigma0_shr:
-       lsr Bck4
-       ror Bck3
-       ror Bck2
-       ror Bck1        
-       dec Func2
-       brne sigma0_shr
-       eor XAccu1, Bck1
-       eor XAccu2, Bck2
-       eor XAccu3, Bck3
-       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
-       add Accu1, XAccu1
-       adc Accu2, XAccu2
-       adc Accu3, XAccu3
-       adc Accu4, XAccu4 /* finished with sigma0 */
-       ldd Func1, Z+7*4  /* now accu += w[i-7] */
-       ldd Func2, Z+7*4+1
-       ldd Func3, Z+7*4+2
-       ldd Func4, Z+7*4+3
-       add Accu1, Func1
-       adc Accu2, Func2
-       adc Accu3, Func3
-       adc Accu4, Func4
-       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
-       ldd Bck2, Z+12*4+1
-       ldd Bck3, Z+12*4+2
-       ldd Bck4, Z+12*4+3
-       /* now sigma 1 */
-       movw Func1, Bck3
-       movw Func3, Bck1 /* prerotated by 16 */
-       ldi r20, 1
-       rcall bitrotr
-       movw XAccu3, Func3
-       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
-;      movw Func1, Bck3
-;      movw Func3, Bck1 /* prerotated by 16 */
-       ldi r20, 2
-       rcall bitrotr
-       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4
-       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
-sigma1_shr:
-       lsr Bck4
-       ror Bck3
-       ror Bck2        
-       dec Func2
-       brne sigma1_shr
-       eor XAccu1, Bck2
-       eor XAccu2, Bck3
-       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
-       add Accu1, XAccu1
-       adc Accu2, XAccu2
-       adc Accu3, XAccu3
-       adc Accu4, XAccu4 /* finished with sigma0 */
-       /* now let's store the shit */
-       st X+, Accu1
-       st X+, Accu2
-       st X+, Accu3
-       st X+, Accu4
-       dec LoopC
-       breq 3f  ; skip if zero
-       rjmp sha256_nextBlock_wcalcloop
-3:
-       /* we are finished with w array X points one byte post w */
-/* init a array */
-       pop r31
-       pop r30
-       push r30
-       push r31
-       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
-init_a_array:  
-       ld r1, Z+
-       st X+, r1
-       dec r25
-       brne init_a_array
-       
-/* now the real fun begins */
-/* 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;
-               } */
-       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
-       sbiw r26, 8*4  /* X still points at a[7]+1*/
-       movw r28, r26
-       ldi r30, lo8(sha256_kv)
-       ldi r31, hi8(sha256_kv)         
-       dec r27  /* X - (64*4 == 256) */
-       ldi r25, 64
-       mov LoopC, r25
-sha256_main_loop:
-       /* now calculate t1 */
-        /*CH(x,y,z) = (x&y)^((~x)&z)*/
-       ldd T1, Y+5*4
-       ldd T2, Y+5*4+1
-       ldd T3, Y+5*4+2
-       ldd T4, Y+5*4+3 /* y in T */
-       ldd Func1, Y+4*4
-       ldd Func2, Y+4*4+1
-       ldd Func3, Y+4*4+2
-       ldd Func4, Y+4*4+3  /* x in Func */
-       ldd Bck1, Y+6*4
-       ldd Bck2, Y+6*4+1
-       ldd Bck3, Y+6*4+2
-       ldd Bck4, Y+6*4+3 /* z in Bck */
-       and T1, Func1
-       and T2, Func2
-       and T3, Func3
-       and T4, Func4
-       com Func1
-       com Func2
-       com Func3
-       com Func4
-       and Bck1, Func1
-       and Bck2, Func2
-       and Bck3, Func3
-       and Bck4, Func4
-       eor T1, Bck1
-       eor T2, Bck2
-       eor T3, Bck3
-       eor T4, Bck4 /* done, CH(x,y,z) is in T */
-       /* now SIGMA1(a[4]) */
-       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
-       ldd Bck1, Y+4*4+1       
-       ldd Bck2, Y+4*4+2
-       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
-       movw Func1, Bck1
-       movw Func3, Bck3
-       ldi r20, 2 
-       rcall bitrotl           /* rotr(x,6) */ 
-       movw XAccu1, Func1
-       movw XAccu3, Func3
-       movw Func1, Bck1
-       movw Func3, Bck3
-       ldi r20, 3 
-       rcall bitrotr   /* rotr(x,11) */
-       eor XAccu1, Func1
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4
-       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
-       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
-       ldi r20, 1 
-       rcall bitrotr   /* rotr(x,11) */
-       eor XAccu1, Func1
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
-       add T1, XAccu1
-       adc T2, XAccu2
-       adc T3, XAccu3
-       adc T4, XAccu4
-       /* now we've to add a[7], w[i] and k[i] */
-       ldd XAccu1, Y+4*7
-       ldd XAccu2, Y+4*7+1
-       ldd XAccu3, Y+4*7+2
-       ldd XAccu4, Y+4*7+3
-       add T1, XAccu1
-       adc T2, XAccu2
-       adc T3, XAccu3
-       adc T4, XAccu4 /* add a[7] */
-       ld XAccu1, X+
-       ld XAccu2, X+
-       ld XAccu3, X+
-       ld XAccu4, X+
-       add T1, XAccu1
-       adc T2, XAccu2
-       adc T3, XAccu3
-       adc T4, XAccu4 /* add w[i] */
-       lpm XAccu1, Z+
-       lpm XAccu2, Z+
-       lpm XAccu3, Z+
-       lpm XAccu4, Z+
-       add T1, XAccu1
-       adc T2, XAccu2
-       adc T3, XAccu3
-       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
-       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
-               /* starting with MAJ(x,y,z) */
-       ldd Func1, Y+4*0+0
-       ldd Func2, Y+4*0+1
-       ldd Func3, Y+4*0+2
-       ldd Func4, Y+4*0+3 /* load x=a[0] */
-       ldd XAccu1, Y+4*1+0
-       ldd XAccu2, Y+4*1+1
-       ldd XAccu3, Y+4*1+2
-       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
-       and XAccu1, Func1
-       and XAccu2, Func2
-       and XAccu3, Func3
-       and XAccu4, Func4       /* XAccu == (x & y) */
-       ldd Bck1, Y+4*2+0
-       ldd Bck2, Y+4*2+1
-       ldd Bck3, Y+4*2+2
-       ldd Bck4, Y+4*2+3 /* load z=a[2] */
-       and Func1, Bck1
-       and Func2, Bck2
-       and Func3, Bck3
-       and Func4, Bck4
-       eor XAccu1, Func1
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
-       ldd Func1, Y+4*1+0
-       ldd Func2, Y+4*1+1
-       ldd Func3, Y+4*1+2
-       ldd Func4, Y+4*1+3 /* load y=a[1] */
-       and Func1, Bck1
-       and Func2, Bck2
-       and Func3, Bck3
-       and Func4, Bck4
-       eor XAccu1, Func1
-       eor XAccu2, Func2
-       eor XAccu3, Func3
-       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
-       /* SIGMA0(a[0]) */
-       ldd Bck1, Y+4*0+0 /* we should combine this with above */
-       ldd Bck2, Y+4*0+1
-       ldd Bck3, Y+4*0+2
-       ldd Bck4, Y+4*0+3
-       movw Func1, Bck1
-       movw Func3, Bck3
-       ldi r20, 2
-       rcall bitrotr
-       movw Accu1, Func1
-       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
-       movw Func1, Bck3 
-       movw Func3, Bck1 /* prerotate by 16 bits */
-       ldi r20, 3
-       rcall bitrotl
-       eor Accu1, Func1
-       eor Accu2, Func2
-       eor Accu3, Func3
-       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
-       mov Func1, Bck4
-       mov Func2, Bck1
-       mov Func3, Bck2
-       mov Func4, Bck3  /* prerotate by 24 bits */
-       ldi r20, 2
-       rcall bitrotl
-       eor Accu1, Func1
-       eor Accu2, Func2
-       eor Accu3, Func3
-       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
-       add Accu1, XAccu1 /* add previous result (MAJ)*/
-       adc Accu2, XAccu2
-       adc Accu3, XAccu3
-       adc Accu4, XAccu4
-       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
-       /* 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]; */
-
-       ldi r21, 7*4
-       adiw r28, 7*4
-a_shift_loop:
-       ld  r25, -Y /* warning: this is PREdecrement */
-       std Y+4, r25
-       dec r21
-       brne a_shift_loop
-
-       ldd Bck1, Y+4*4+0
-       ldd Bck2, Y+4*4+1
-       ldd Bck3, Y+4*4+2
-       ldd Bck4, Y+4*4+3
-       add Bck1, T1
-       adc Bck2, T2
-       adc Bck3, T3
-       adc Bck4, T4
-       std Y+4*4+0, Bck1
-       std Y+4*4+1, Bck2
-       std Y+4*4+2, Bck3
-       std Y+4*4+3, Bck4
-       add Accu1, T1
-       adc Accu2, T2
-       adc Accu3, T3
-       adc Accu4, T4
-       std Y+4*0+0, Accu1
-       std Y+4*0+1, Accu2
-       std Y+4*0+2, Accu3
-       std Y+4*0+3, Accu4 /* a array updated */
-       
-       
-       dec LoopC
-       breq update_state
-       rjmp sha256_main_loop ;brne sha256_main_loop
-update_state:  
-       /* update state */
-       /* pointers to state should still exist on the stack ;-) */
-       pop r31
-       pop r30
-       ldi r21, 8
-update_state_loop:
-       ldd Accu1, Z+0
-       ldd Accu2, Z+1
-       ldd Accu3, Z+2
-       ldd Accu4, Z+3 
-       ld Func1, Y+
-       ld Func2, Y+
-       ld Func3, Y+
-       ld Func4, Y+
-       add Accu1, Func1
-       adc Accu2, Func2
-       adc Accu3, Func3
-       adc Accu4, Func4
-       st Z+, Accu1
-       st Z+, Accu2
-       st Z+, Accu3
-       st Z+, Accu4
-       dec r21
-       brne update_state_loop
-       /* now we just have to update the length */
-       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
-       ldi r21, 2
-       ldi r22, 6
-       ld r20, Z
-       add r20, r21
-       st Z+, r20      
-       clr r21
-sha256_nextBlock_fix_length:   
-       brcc sha256_nextBlock_epilog
-       ld r20, Z
-       adc r20, r21
-       st Z+, r20
-       dec r22
-       brne sha256_nextBlock_fix_length
-       
-; EPILOG
-sha256_nextBlock_epilog:
-/* now we should clean up the stack */
-       
-       pop r21
-       pop r20
-       in r0, SREG
-       cli ; we want to be uninterrupted while updating SP
-       out SPL, r20
-       out SPH, r21
-       out SREG, r0
-       
-       clr r1
-       pop r29
-       pop r28
-       pop r17
-       pop r16
-       pop r15
-       pop r14
-       pop r13
-       pop r12
-       pop r11
-       pop r10
-       pop r9
-       pop r8
-       pop r7
-       pop r6
-       pop r5
-       pop r4 
-       ret
-
-sha256_kv: ; round-key-vector stored in ProgMem 
-.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
-.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
-.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
-.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
-.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
-.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
-.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
-.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
-
-       
-;###########################################################   
-
-.global sha256_init 
-;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);
-;}
-; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
-; modifys: Z(r30,r31), Func1, r22
-sha256_init:
-       movw r26, r24 ; (24,25) --> (26,27) load X with param1
-       ldi r30, lo8((sha256_init_vector))
-       ldi r31, hi8((sha256_init_vector))
-       ldi r22, 32+8
-sha256_init_vloop:     
-       lpm r23, Z+ 
-       st X+, r23
-       dec r22
-       brne sha256_init_vloop
-       ret
-       
-sha256_init_vector:
-.word 0xE667, 0x6A09
-.word 0xAE85, 0xBB67 
-.word 0xF372, 0x3C6E 
-.word 0xF53A, 0xA54F 
-.word 0x527F, 0x510E 
-.word 0x688C, 0x9B05 
-.word 0xD9AB, 0x1F83 
-.word 0xCD19, 0x5BE0
-.word 0x0000, 0x0000
-.word 0x0000, 0x0000
-
-;###########################################################   
-
-.global rotl32
-; === ROTL32 ===
-; function that rotates a 32 bit word to the left
-;  param1: the 32-bit word to rotate
-;      given in r25,r24,r23,r22 (r25 is most significant)
-;  param2: an 8-bit value telling how often to rotate
-;      given in r20
-; modifys: r21, r22
-rotl32:
-       cpi r20, 8
-       brlo bitrotl
-       mov r21, r25
-       mov r25, r24
-       mov r24, r23
-       mov r23, r22
-       mov r22, r21
-       subi r20, 8
-       rjmp rotl32
-bitrotl:
-       clr r21
-       clc
-bitrotl_loop:  
-       tst r20
-       breq fixrotl
-       rol r22
-       rol r23
-       rol r24
-       rol r25
-       rol r21
-       dec r20
-       rjmp bitrotl_loop
-fixrotl:
-       or r22, r21
-       ret
-       
-
-;###########################################################   
-
-.global rotr32
-; === ROTR32 ===
-; function that rotates a 32 bit word to the right
-;  param1: the 32-bit word to rotate
-;      given in r25,r24,r23,22 (r25 is most significant)
-;  param2: an 8-bit value telling how often to rotate
-;      given in r20
-; modifys: r21, r22
-rotr32:
-       cpi r20, 8
-       brlo bitrotr
-       mov r21, r22
-       mov r22, r23
-       mov r23, r24
-       mov r24, r25
-       mov r25, r21
-       subi r20, 8
-       rjmp rotr32
-bitrotr:
-       clr r21
-       clc
-bitrotr_loop:  
-       tst r20
-       breq fixrotr
-       ror r25
-       ror r24
-       ror r23
-       ror r22
-       ror r21
-       dec r20
-       rjmp bitrotr_loop
-fixrotr:
-       or r25, r21
-       ret
-       
-       
-;###########################################################   
-       
-.global change_endian32
-; === change_endian32 ===
-; function that changes the endianess of a 32-bit word
-;  param1: the 32-bit word
-;      given in r25,r24,r23,22 (r25 is most significant)
-;  modifys: r21, r22
-change_endian32:
-       movw r20,  r22 ; (r22,r23) --> (r20,r21)
-       mov r22, r25
-       mov r23, r24
-       mov r24, r21
-       mov r25, r20 
-       ret
-
diff --git a/sha256.c b/sha256.c
deleted file mode 100644 (file)
index f654968..0000000
--- a/sha256.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* sha256.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file               sha256.c
- * \author             Daniel Otte 
- * \date               16.05.2006
- * 
- * \par License:       
- *     GPL
- * 
- * \brief SHA-256 implementation.
- * 
- * 
- */
-
-#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 };
-
-
-/*************************************************************************/
-
-/**
- * \brief \c sh256_init initialises a sha256 context for hashing. 
- * \c sh256_init c initialises the given sha256 context for hashing
- * @param state pointer to a sha256 context
- * @return none
- */
-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, const 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;
-} 
-
-
-/*************************************************************************/
-
-/**
- * \brief function to process the last block being hashed
- * @param state Pointer to the context in which this block should be processed.
- * @param block Pointer to the message wich should be hashed.
- * @param 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, const 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 & 0x7){ // 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 & 0x7);
-       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, const 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 = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
-               length -= SHA256_BLOCK_BITS;
-       }
-       sha256_lastBlock(&s, msg, length);
-       sha256_ctx2hash(dest,&s);
-}
-
-
-
-/*************************************************************************/
-
-void sha256_ctx2hash(sha256_hash_t *dest, const 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
-}
-
-
diff --git a/sha256.h b/sha256.h
deleted file mode 100644 (file)
index 24960a3..0000000
--- a/sha256.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* sha256.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       sha256.h
- * \author  Daniel Otte 
- * \date    2006-05-16
- * \license    GPLv3 or later
- * 
- */
-
-#ifndef SHA256_H_
-#define SHA256_H_
-
-#define __LITTLE_ENDIAN__
-
-
-#include <stdint.h>
-
-/** \def SHA256_HASH_BITS
- * defines the size of a SHA-256 hash value in bits
- */
-
-/** \def SHA256_HASH_BYTES
- * defines the size of a SHA-256 hash value in bytes
- */
-
-/** \def SHA256_BLOCK_BITS
- * defines the size of a SHA-256 input block in bits
- */
-
-/** \def SHA256_BLOCK_BYTES
- * defines the size of a SHA-256 input block in bytes
- */
-
-#define SHA256_HASH_BITS  256
-#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
-#define SHA256_BLOCK_BITS 512
-#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
-
-/** \typedef sha256_ctx_t
- * \brief SHA-256 context type
- * 
- * A variable of this type may hold the state of a SHA-256 hashing process
- */
-typedef struct {
-       uint32_t h[8];
-       uint64_t length;
-} sha256_ctx_t;
-
-/** \typedef sha256_hash_t
- * \brief SHA-256 hash value type
- * 
- * A variable of this type may hold the hash value produced by the
- * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
- */
-typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
-
-/** \fn void sha256_init(sha256_ctx_t *state)
- * \brief initialise a SHA-256 context
- * 
- * This function sets a ::sha256_ctx_t to the initial values for hashing.
- * \param state pointer to the SHA-256 hashing context
- */
-void sha256_init(sha256_ctx_t *state);
-
-/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
- * \brief update the context with a given block
- * 
- * This function updates the SHA-256 hash context by processing the given block
- * of fixed length.
- * \param state pointer to the SHA-256 hash context
- * \param block pointer to the block of fixed length (512 bit = 64 byte)
- */
-void sha256_nextBlock (sha256_ctx_t* state, const void* block);
-
-/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
- * \brief finalize the context with the given block 
- * 
- * This function finalizes the SHA-256 hash context by processing the given block
- * of variable length.
- * \param state pointer to the SHA-256 hash context
- * \param block pointer to the block of fixed length (512 bit = 64 byte)
- * \param length_b the length of the block in bits
- */
-void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
-
-/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
- * \brief convert the hash state into the hash value
- * This function reads the context and writes the hash value to the destination
- * \param dest pointer to the location where the hash value should be written
- * \param state pointer to the SHA-256 hash context
- */
-void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
-
-/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
- * \brief simple SHA-256 hashing function for direct hashing
- * 
- * This function automaticaly hashes a given message of arbitary length with
- * the SHA-256 hashing algorithm.
- * \param dest pointer to the location where the hash value is going to be written to
- * \param msg pointer to the message thats going to be hashed
- * \param length_b length of the message in bits
- */
-void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
-
-#endif /*SHA256_H_*/
diff --git a/sha256/sha256-asm.S b/sha256/sha256-asm.S
new file mode 100644 (file)
index 0000000..d9eb6b6
--- /dev/null
@@ -0,0 +1,1042 @@
+/* sha256-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; sha-256 implementation in assembler  
+SHA256_BLOCK_BITS = 512
+SHA256_HASH_BITS = 256
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+       precall
+       hexdump \length
+       postcall
+.endm
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha256_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha256_ctx2hash
+; === sha256_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha256_ctx structure
+;      given in r23,r22
+sha256_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 8
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha256
+; === sha256 ===
+; this function calculates SHA-256 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha256:
+sha256_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 8*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha256_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha256_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha256_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha256_ctx2hash   
+       
+sha256_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 8*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha256_lastBlock
+; === sha256_lastBlock ===
+; this function does padding & Co. for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
+
+
+sha256_lastBlock:
+       cpi r21, 0x02
+       brlo sha256_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 0x02
+       subi r23, -2
+       rjmp sha256_lastBlock   
+sha256_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha256_lastBlock_post_copy
+       mov r1, r18
+sha256_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha256_lastBlock_copy_loop
+sha256_lastBlock_post_copy:    
+sha256_lastBlock_insert_stuffing_bit:  
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha256_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*8+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha256_lastBlock_insert_zeros: 
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha256_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha256_lastBlock_epilog
+sha256_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 8*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha256_nextBlock
+
+sha256_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha256_nextBlock
+; === sha256_nextBlock ===
+; this is the core function for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
+
+Bck1 = 12
+Bck2 = 13
+Bck3 = 14
+Bck4 = 15
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+Accu1 = 16
+Accu2 = 17
+Accu3 = 18
+Accu4 = 19
+XAccu1 = 8
+XAccu2 = 9
+XAccu3 = 10
+XAccu4 = 11
+T1     = 4
+T2     = 5
+T3     = 6
+T4     = 7
+LoopC = 1
+/* byteorder: high number <--> high significance */
+sha256_nextBlock:
+ ; initial, let's make some space ready for local vars
+       push r4 /* replace push & pop by mem ops? */
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha256_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       push r18
+       push r19
+       push r24
+       push r25 /* param1 will be needed later */
+ ; now we fill the w array with message (think about endianess)
+       adiw r26, 1 ; X++
+       ldi r20, 16
+sha256_nextBlock_wcpyloop:     
+       ld r23, Z+
+       ld r22, Z+
+       ld r19, Z+
+       ld r18, Z+
+       st X+, r18
+       st X+, r19
+       st X+, r22      
+       st X+, r23
+       dec r20
+       brne sha256_nextBlock_wcpyloop
+/*     for (i=16; i<64; ++i){
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+       } */
+       /* r25,r24,r23,r24 (r21,r20) are function values
+          r19,r18,r17,r16 are the accumulator
+          r15,r14,r13,rBck1 are backup1
+          r11,r10,r9 ,r8  are xor accu   
+          r1 is round counter                                                          */
+
+       ldi r20, 64-16
+       mov LoopC, r20
+sha256_nextBlock_wcalcloop:             
+       movw r30, r26 ; cp X to Z
+       sbiw r30, 63
+       sbiw r30, 1             ; substract 64 = 16*4
+       ld Accu1, Z+
+       ld Accu2, Z+
+       ld Accu3, Z+
+       ld Accu4, Z+ /* w[i] = w[i-16] */
+       ld Bck1, Z+
+       ld Bck2, Z+
+       ld Bck3, Z+
+       ld Bck4, Z+ /* backup = w[i-15] */
+       /* now sigma 0 */
+       mov Func1, Bck2
+       mov Func2, Bck3
+       mov Func3, Bck4
+       mov Func4, Bck1  /* prerotated by 8 */
+       ldi r20, 1
+       rcall bitrotl
+       movw XAccu1, Func1
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
+sigma0_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2
+       ror Bck1        
+       dec Func2
+       brne sigma0_shr
+       eor XAccu1, Bck1
+       eor XAccu2, Bck2
+       eor XAccu3, Bck3
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */
+       ldd Func2, Z+7*4+1
+       ldd Func3, Z+7*4+2
+       ldd Func4, Z+7*4+3
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
+       ldd Bck2, Z+12*4+1
+       ldd Bck3, Z+12*4+2
+       ldd Bck4, Z+12*4+3
+       /* now sigma 1 */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 1
+       rcall bitrotr
+       movw XAccu3, Func3
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
+;      movw Func1, Bck3
+;      movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
+sigma1_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2        
+       dec Func2
+       brne sigma1_shr
+       eor XAccu1, Bck2
+       eor XAccu2, Bck3
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       /* now let's store the shit */
+       st X+, Accu1
+       st X+, Accu2
+       st X+, Accu3
+       st X+, Accu4
+       dec LoopC
+       breq 3f  ; skip if zero
+       rjmp sha256_nextBlock_wcalcloop
+3:
+       /* we are finished with w array X points one byte post w */
+/* init a array */
+       pop r31
+       pop r30
+       push r30
+       push r31
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
+init_a_array:  
+       ld r1, Z+
+       st X+, r1
+       dec r25
+       brne init_a_array
+       
+/* now the real fun begins */
+/* 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;
+               } */
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
+       sbiw r26, 8*4  /* X still points at a[7]+1*/
+       movw r28, r26
+       ldi r30, lo8(sha256_kv)
+       ldi r31, hi8(sha256_kv)         
+       dec r27  /* X - (64*4 == 256) */
+       ldi r25, 64
+       mov LoopC, r25
+sha256_main_loop:
+       /* now calculate t1 */
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/
+       ldd T1, Y+5*4
+       ldd T2, Y+5*4+1
+       ldd T3, Y+5*4+2
+       ldd T4, Y+5*4+3 /* y in T */
+       ldd Func1, Y+4*4
+       ldd Func2, Y+4*4+1
+       ldd Func3, Y+4*4+2
+       ldd Func4, Y+4*4+3  /* x in Func */
+       ldd Bck1, Y+6*4
+       ldd Bck2, Y+6*4+1
+       ldd Bck3, Y+6*4+2
+       ldd Bck4, Y+6*4+3 /* z in Bck */
+       and T1, Func1
+       and T2, Func2
+       and T3, Func3
+       and T4, Func4
+       com Func1
+       com Func2
+       com Func3
+       com Func4
+       and Bck1, Func1
+       and Bck2, Func2
+       and Bck3, Func3
+       and Bck4, Func4
+       eor T1, Bck1
+       eor T2, Bck2
+       eor T3, Bck3
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */
+       /* now SIGMA1(a[4]) */
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
+       ldd Bck1, Y+4*4+1       
+       ldd Bck2, Y+4*4+2
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2 
+       rcall bitrotl           /* rotr(x,6) */ 
+       movw XAccu1, Func1
+       movw XAccu3, Func3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 3 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
+       ldi r20, 1 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4
+       /* now we've to add a[7], w[i] and k[i] */
+       ldd XAccu1, Y+4*7
+       ldd XAccu2, Y+4*7+1
+       ldd XAccu3, Y+4*7+2
+       ldd XAccu4, Y+4*7+3
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add a[7] */
+       ld XAccu1, X+
+       ld XAccu2, X+
+       ld XAccu3, X+
+       ld XAccu4, X+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add w[i] */
+       lpm XAccu1, Z+
+       lpm XAccu2, Z+
+       lpm XAccu3, Z+
+       lpm XAccu4, Z+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
+               /* starting with MAJ(x,y,z) */
+       ldd Func1, Y+4*0+0
+       ldd Func2, Y+4*0+1
+       ldd Func3, Y+4*0+2
+       ldd Func4, Y+4*0+3 /* load x=a[0] */
+       ldd XAccu1, Y+4*1+0
+       ldd XAccu2, Y+4*1+1
+       ldd XAccu3, Y+4*1+2
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
+       and XAccu1, Func1
+       and XAccu2, Func2
+       and XAccu3, Func3
+       and XAccu4, Func4       /* XAccu == (x & y) */
+       ldd Bck1, Y+4*2+0
+       ldd Bck2, Y+4*2+1
+       ldd Bck3, Y+4*2+2
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
+       ldd Func1, Y+4*1+0
+       ldd Func2, Y+4*1+1
+       ldd Func3, Y+4*1+2
+       ldd Func4, Y+4*1+3 /* load y=a[1] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
+       /* SIGMA0(a[0]) */
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */
+       ldd Bck2, Y+4*0+1
+       ldd Bck3, Y+4*0+2
+       ldd Bck4, Y+4*0+3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2
+       rcall bitrotr
+       movw Accu1, Func1
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
+       movw Func1, Bck3 
+       movw Func3, Bck1 /* prerotate by 16 bits */
+       ldi r20, 3
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
+       mov Func1, Bck4
+       mov Func2, Bck1
+       mov Func3, Bck2
+       mov Func4, Bck3  /* prerotate by 24 bits */
+       ldi r20, 2
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
+       add Accu1, XAccu1 /* add previous result (MAJ)*/
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
+       /* 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]; */
+
+       ldi r21, 7*4
+       adiw r28, 7*4
+a_shift_loop:
+       ld  r25, -Y /* warning: this is PREdecrement */
+       std Y+4, r25
+       dec r21
+       brne a_shift_loop
+
+       ldd Bck1, Y+4*4+0
+       ldd Bck2, Y+4*4+1
+       ldd Bck3, Y+4*4+2
+       ldd Bck4, Y+4*4+3
+       add Bck1, T1
+       adc Bck2, T2
+       adc Bck3, T3
+       adc Bck4, T4
+       std Y+4*4+0, Bck1
+       std Y+4*4+1, Bck2
+       std Y+4*4+2, Bck3
+       std Y+4*4+3, Bck4
+       add Accu1, T1
+       adc Accu2, T2
+       adc Accu3, T3
+       adc Accu4, T4
+       std Y+4*0+0, Accu1
+       std Y+4*0+1, Accu2
+       std Y+4*0+2, Accu3
+       std Y+4*0+3, Accu4 /* a array updated */
+       
+       
+       dec LoopC
+       breq update_state
+       rjmp sha256_main_loop ;brne sha256_main_loop
+update_state:  
+       /* update state */
+       /* pointers to state should still exist on the stack ;-) */
+       pop r31
+       pop r30
+       ldi r21, 8
+update_state_loop:
+       ldd Accu1, Z+0
+       ldd Accu2, Z+1
+       ldd Accu3, Z+2
+       ldd Accu4, Z+3 
+       ld Func1, Y+
+       ld Func2, Y+
+       ld Func3, Y+
+       ld Func4, Y+
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       st Z+, Accu1
+       st Z+, Accu2
+       st Z+, Accu3
+       st Z+, Accu4
+       dec r21
+       brne update_state_loop
+       /* now we just have to update the length */
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
+       ldi r21, 2
+       ldi r22, 6
+       ld r20, Z
+       add r20, r21
+       st Z+, r20      
+       clr r21
+sha256_nextBlock_fix_length:   
+       brcc sha256_nextBlock_epilog
+       ld r20, Z
+       adc r20, r21
+       st Z+, r20
+       dec r22
+       brne sha256_nextBlock_fix_length
+       
+; EPILOG
+sha256_nextBlock_epilog:
+/* now we should clean up the stack */
+       
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4 
+       ret
+
+sha256_kv: ; round-key-vector stored in ProgMem 
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
+
+       
+;###########################################################   
+
+.global sha256_init 
+;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);
+;}
+; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha256_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha256_init_vector))
+       ldi r31, hi8((sha256_init_vector))
+       ldi r22, 32+8
+sha256_init_vloop:     
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha256_init_vloop
+       ret
+       
+sha256_init_vector:
+.word 0xE667, 0x6A09
+.word 0xAE85, 0xBB67 
+.word 0xF372, 0x3C6E 
+.word 0xF53A, 0xA54F 
+.word 0x527F, 0x510E 
+.word 0x688C, 0x9B05 
+.word 0xD9AB, 0x1F83 
+.word 0xCD19, 0x5BE0
+.word 0x0000, 0x0000
+.word 0x0000, 0x0000
+
+;###########################################################   
+
+.global rotl32
+; === ROTL32 ===
+; function that rotates a 32 bit word to the left
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,r22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       clr r21
+       clc
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       rol r21
+       dec r20
+       rjmp bitrotl_loop
+fixrotl:
+       or r22, r21
+       ret
+       
+
+;###########################################################   
+
+.global rotr32
+; === ROTR32 ===
+; function that rotates a 32 bit word to the right
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotr32:
+       cpi r20, 8
+       brlo bitrotr
+       mov r21, r22
+       mov r22, r23
+       mov r23, r24
+       mov r24, r25
+       mov r25, r21
+       subi r20, 8
+       rjmp rotr32
+bitrotr:
+       clr r21
+       clc
+bitrotr_loop:  
+       tst r20
+       breq fixrotr
+       ror r25
+       ror r24
+       ror r23
+       ror r22
+       ror r21
+       dec r20
+       rjmp bitrotr_loop
+fixrotr:
+       or r25, r21
+       ret
+       
+       
+;###########################################################   
+       
+.global change_endian32
+; === change_endian32 ===
+; function that changes the endianess of a 32-bit word
+;  param1: the 32-bit word
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  modifys: r21, r22
+change_endian32:
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)
+       mov r22, r25
+       mov r23, r24
+       mov r24, r21
+       mov r25, r20 
+       ret
+
diff --git a/sha256/sha256.c b/sha256/sha256.c
new file mode 100644 (file)
index 0000000..f654968
--- /dev/null
@@ -0,0 +1,231 @@
+/* sha256.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file               sha256.c
+ * \author             Daniel Otte 
+ * \date               16.05.2006
+ * 
+ * \par License:       
+ *     GPL
+ * 
+ * \brief SHA-256 implementation.
+ * 
+ * 
+ */
+
+#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 };
+
+
+/*************************************************************************/
+
+/**
+ * \brief \c sh256_init initialises a sha256 context for hashing. 
+ * \c sh256_init c initialises the given sha256 context for hashing
+ * @param state pointer to a sha256 context
+ * @return none
+ */
+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, const 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;
+} 
+
+
+/*************************************************************************/
+
+/**
+ * \brief function to process the last block being hashed
+ * @param state Pointer to the context in which this block should be processed.
+ * @param block Pointer to the message wich should be hashed.
+ * @param 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, const 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 & 0x7){ // 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 & 0x7);
+       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, const 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 = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
+               length -= SHA256_BLOCK_BITS;
+       }
+       sha256_lastBlock(&s, msg, length);
+       sha256_ctx2hash(dest,&s);
+}
+
+
+
+/*************************************************************************/
+
+void sha256_ctx2hash(sha256_hash_t *dest, const 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
+}
+
+
diff --git a/sha256/sha256.h b/sha256/sha256.h
new file mode 100644 (file)
index 0000000..24960a3
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialise a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automaticaly hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/shabea.c b/shabea.c
deleted file mode 100644 (file)
index b59e138..0000000
--- a/shabea.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* shabea.c */
-/*
- *   This file is part of AnonAccess, an access system which can be used
- *    to open door or doing other things with an anonymity featured
- *    account managment.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file       shabea.c
- * \author     Daniel Otte 
- * \date       2007-06-07
- * \brief      SHABEA - a SHA Based Encryption Algorithm implementation
- * \par License        
- * GPL
- * 
- * SHABEAn-r where n is the blocksize and r the number of round used
- * 
- * 
- */
-#include <stdlib.h>
-#include <string.h>
-#include "sha256.h"
-
-#include "config.h"
-#include "memxor.h"
-
-
-/*
- * SHABEA256-n
- */ 
-#define SHABEA_BLOCKSIZE 256
-#define SHABEA_BLOCKSIZEB (SHABEA_BLOCKSIZE/8)
-#define SHABEA_HALFSIZEB  (SHABEA_BLOCKSIZEB/2)
-#define SHABEA_HALFSIZE (SHABEA_BLOCKSIZE/2)
-
-#define L ((uint8_t*)block+ 0)
-#define R ((uint8_t*)block+16)
-void shabea256(void * block, void * key, uint16_t keysize_b, uint8_t enc, uint8_t rounds){
-       uint8_t r;              /**/
-       uint8_t tb[SHABEA_HALFSIZEB+2+(keysize_b+7)/8]; /**/
-       uint16_t kbs;   /* bytes used for the key / temporary block */
-       sha256_hash_t hash;
-       uint8_t termcond; 
-       int8_t dir;
-       if(enc){
-               r = 0;
-               termcond = rounds-1;
-               dir = 1;
-       } else {
-               r = rounds-1;
-               termcond = 0;
-               dir = -1;
-       }
-       kbs = (keysize_b+7)/8;
-       memcpy(tb+SHABEA_HALFSIZEB+2, key, kbs); /* copy key to temporary block */
-       tb[SHABEA_HALFSIZEB+0] = 0;     /* set round counter high value to zero */
-       
-       for(;;r+=dir){ /* enc: 0..(rounds-1) ; !enc: (rounds-1)..0 */
-               memcpy(tb, R, SHABEA_HALFSIZEB); /* copy right half into tb */
-               tb[SHABEA_HALFSIZEB+1] = r;
-               sha256(&hash, tb, SHABEA_HALFSIZE+16+keysize_b);
-               if(r!=termcond){        
-                       /* swap */
-                       memxor(hash, L, SHABEA_HALFSIZEB);
-                       memcpy(L, R, SHABEA_HALFSIZEB);
-                       memcpy(R, hash, SHABEA_HALFSIZEB);
-               } else {
-                       /* last round */
-                       /* no swap */
-                       memxor(L, hash, SHABEA_HALFSIZEB);
-                       return; 
-               }
-       }
-}
-
-
diff --git a/shabea.h b/shabea.h
deleted file mode 100644 (file)
index fdb4916..0000000
--- a/shabea.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* shabea.h */
-/*
- *   This file is part of AnonAccess, an access system which can be used
- *    to open door or doing other things with an anonymity featured
- *    account managment.
- *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/**
- * \file       shabea.h
- * \author     Daniel Otte 
- * \date       2007-06-07
- * \brief      SHABEA - a SHA Based Encryption Algorithm declarations
- * \par License        
- * GPL
- * 
- * SHABEAn-r where n is the blocksize and r the number of round used
- * 
- */
-#ifndef SHABEA_H_
-#define SHABEA_H_
-
-void shabea256(void * block, void * key, uint16_t keysize_b, uint8_t enc, uint8_t rounds);
-#endif /*SHABEA_H_*/
diff --git a/shabea/memxor.S b/shabea/memxor.S
new file mode 100644 (file)
index 0000000..a32058b
--- /dev/null
@@ -0,0 +1,66 @@
+/* memxor.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File:        memxor.S
+ * Author:      Daniel Otte
+ * Date:        2008-08-07
+ * License:     GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+  * param dest is passed in r24:r25
+  * param src  is passed in r22:r23
+  * param n    is passed in r20:r21
+  */
+.global memxor
+memxor:
+       movw r30, r24
+       movw r26, r22
+       movw r24, r20
+       adiw r24, 0
+       breq 2f
+1:
+       ld r20, X+
+       ld r21, Z
+       eor r20, r21
+       st Z+, r20
+       sbiw r24, 1
+       brne 1b
+2:
+       ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/shabea/memxor.h b/shabea/memxor.h
new file mode 100644 (file)
index 0000000..a62a616
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
diff --git a/shabea/sha256-asm.S b/shabea/sha256-asm.S
new file mode 100644 (file)
index 0000000..d9eb6b6
--- /dev/null
@@ -0,0 +1,1042 @@
+/* sha256-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; sha-256 implementation in assembler  
+SHA256_BLOCK_BITS = 512
+SHA256_HASH_BITS = 256
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+       precall
+       hexdump \length
+       postcall
+.endm
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha256_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha256_ctx2hash
+; === sha256_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha256_ctx structure
+;      given in r23,r22
+sha256_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 8
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha256
+; === sha256 ===
+; this function calculates SHA-256 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha256:
+sha256_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 8*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha256_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha256_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha256_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha256_ctx2hash   
+       
+sha256_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 8*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha256_lastBlock
+; === sha256_lastBlock ===
+; this function does padding & Co. for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
+
+
+sha256_lastBlock:
+       cpi r21, 0x02
+       brlo sha256_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 0x02
+       subi r23, -2
+       rjmp sha256_lastBlock   
+sha256_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha256_lastBlock_post_copy
+       mov r1, r18
+sha256_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha256_lastBlock_copy_loop
+sha256_lastBlock_post_copy:    
+sha256_lastBlock_insert_stuffing_bit:  
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha256_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*8+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha256_lastBlock_insert_zeros: 
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha256_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha256_lastBlock_epilog
+sha256_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 8*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha256_nextBlock
+
+sha256_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha256_nextBlock
+; === sha256_nextBlock ===
+; this is the core function for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
+
+Bck1 = 12
+Bck2 = 13
+Bck3 = 14
+Bck4 = 15
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+Accu1 = 16
+Accu2 = 17
+Accu3 = 18
+Accu4 = 19
+XAccu1 = 8
+XAccu2 = 9
+XAccu3 = 10
+XAccu4 = 11
+T1     = 4
+T2     = 5
+T3     = 6
+T4     = 7
+LoopC = 1
+/* byteorder: high number <--> high significance */
+sha256_nextBlock:
+ ; initial, let's make some space ready for local vars
+       push r4 /* replace push & pop by mem ops? */
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha256_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       push r18
+       push r19
+       push r24
+       push r25 /* param1 will be needed later */
+ ; now we fill the w array with message (think about endianess)
+       adiw r26, 1 ; X++
+       ldi r20, 16
+sha256_nextBlock_wcpyloop:     
+       ld r23, Z+
+       ld r22, Z+
+       ld r19, Z+
+       ld r18, Z+
+       st X+, r18
+       st X+, r19
+       st X+, r22      
+       st X+, r23
+       dec r20
+       brne sha256_nextBlock_wcpyloop
+/*     for (i=16; i<64; ++i){
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+       } */
+       /* r25,r24,r23,r24 (r21,r20) are function values
+          r19,r18,r17,r16 are the accumulator
+          r15,r14,r13,rBck1 are backup1
+          r11,r10,r9 ,r8  are xor accu   
+          r1 is round counter                                                          */
+
+       ldi r20, 64-16
+       mov LoopC, r20
+sha256_nextBlock_wcalcloop:             
+       movw r30, r26 ; cp X to Z
+       sbiw r30, 63
+       sbiw r30, 1             ; substract 64 = 16*4
+       ld Accu1, Z+
+       ld Accu2, Z+
+       ld Accu3, Z+
+       ld Accu4, Z+ /* w[i] = w[i-16] */
+       ld Bck1, Z+
+       ld Bck2, Z+
+       ld Bck3, Z+
+       ld Bck4, Z+ /* backup = w[i-15] */
+       /* now sigma 0 */
+       mov Func1, Bck2
+       mov Func2, Bck3
+       mov Func3, Bck4
+       mov Func4, Bck1  /* prerotated by 8 */
+       ldi r20, 1
+       rcall bitrotl
+       movw XAccu1, Func1
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
+sigma0_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2
+       ror Bck1        
+       dec Func2
+       brne sigma0_shr
+       eor XAccu1, Bck1
+       eor XAccu2, Bck2
+       eor XAccu3, Bck3
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */
+       ldd Func2, Z+7*4+1
+       ldd Func3, Z+7*4+2
+       ldd Func4, Z+7*4+3
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
+       ldd Bck2, Z+12*4+1
+       ldd Bck3, Z+12*4+2
+       ldd Bck4, Z+12*4+3
+       /* now sigma 1 */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 1
+       rcall bitrotr
+       movw XAccu3, Func3
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
+;      movw Func1, Bck3
+;      movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
+sigma1_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2        
+       dec Func2
+       brne sigma1_shr
+       eor XAccu1, Bck2
+       eor XAccu2, Bck3
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       /* now let's store the shit */
+       st X+, Accu1
+       st X+, Accu2
+       st X+, Accu3
+       st X+, Accu4
+       dec LoopC
+       breq 3f  ; skip if zero
+       rjmp sha256_nextBlock_wcalcloop
+3:
+       /* we are finished with w array X points one byte post w */
+/* init a array */
+       pop r31
+       pop r30
+       push r30
+       push r31
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
+init_a_array:  
+       ld r1, Z+
+       st X+, r1
+       dec r25
+       brne init_a_array
+       
+/* now the real fun begins */
+/* 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;
+               } */
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
+       sbiw r26, 8*4  /* X still points at a[7]+1*/
+       movw r28, r26
+       ldi r30, lo8(sha256_kv)
+       ldi r31, hi8(sha256_kv)         
+       dec r27  /* X - (64*4 == 256) */
+       ldi r25, 64
+       mov LoopC, r25
+sha256_main_loop:
+       /* now calculate t1 */
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/
+       ldd T1, Y+5*4
+       ldd T2, Y+5*4+1
+       ldd T3, Y+5*4+2
+       ldd T4, Y+5*4+3 /* y in T */
+       ldd Func1, Y+4*4
+       ldd Func2, Y+4*4+1
+       ldd Func3, Y+4*4+2
+       ldd Func4, Y+4*4+3  /* x in Func */
+       ldd Bck1, Y+6*4
+       ldd Bck2, Y+6*4+1
+       ldd Bck3, Y+6*4+2
+       ldd Bck4, Y+6*4+3 /* z in Bck */
+       and T1, Func1
+       and T2, Func2
+       and T3, Func3
+       and T4, Func4
+       com Func1
+       com Func2
+       com Func3
+       com Func4
+       and Bck1, Func1
+       and Bck2, Func2
+       and Bck3, Func3
+       and Bck4, Func4
+       eor T1, Bck1
+       eor T2, Bck2
+       eor T3, Bck3
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */
+       /* now SIGMA1(a[4]) */
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
+       ldd Bck1, Y+4*4+1       
+       ldd Bck2, Y+4*4+2
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2 
+       rcall bitrotl           /* rotr(x,6) */ 
+       movw XAccu1, Func1
+       movw XAccu3, Func3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 3 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
+       ldi r20, 1 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4
+       /* now we've to add a[7], w[i] and k[i] */
+       ldd XAccu1, Y+4*7
+       ldd XAccu2, Y+4*7+1
+       ldd XAccu3, Y+4*7+2
+       ldd XAccu4, Y+4*7+3
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add a[7] */
+       ld XAccu1, X+
+       ld XAccu2, X+
+       ld XAccu3, X+
+       ld XAccu4, X+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add w[i] */
+       lpm XAccu1, Z+
+       lpm XAccu2, Z+
+       lpm XAccu3, Z+
+       lpm XAccu4, Z+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
+               /* starting with MAJ(x,y,z) */
+       ldd Func1, Y+4*0+0
+       ldd Func2, Y+4*0+1
+       ldd Func3, Y+4*0+2
+       ldd Func4, Y+4*0+3 /* load x=a[0] */
+       ldd XAccu1, Y+4*1+0
+       ldd XAccu2, Y+4*1+1
+       ldd XAccu3, Y+4*1+2
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
+       and XAccu1, Func1
+       and XAccu2, Func2
+       and XAccu3, Func3
+       and XAccu4, Func4       /* XAccu == (x & y) */
+       ldd Bck1, Y+4*2+0
+       ldd Bck2, Y+4*2+1
+       ldd Bck3, Y+4*2+2
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
+       ldd Func1, Y+4*1+0
+       ldd Func2, Y+4*1+1
+       ldd Func3, Y+4*1+2
+       ldd Func4, Y+4*1+3 /* load y=a[1] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
+       /* SIGMA0(a[0]) */
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */
+       ldd Bck2, Y+4*0+1
+       ldd Bck3, Y+4*0+2
+       ldd Bck4, Y+4*0+3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2
+       rcall bitrotr
+       movw Accu1, Func1
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
+       movw Func1, Bck3 
+       movw Func3, Bck1 /* prerotate by 16 bits */
+       ldi r20, 3
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
+       mov Func1, Bck4
+       mov Func2, Bck1
+       mov Func3, Bck2
+       mov Func4, Bck3  /* prerotate by 24 bits */
+       ldi r20, 2
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
+       add Accu1, XAccu1 /* add previous result (MAJ)*/
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
+       /* 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]; */
+
+       ldi r21, 7*4
+       adiw r28, 7*4
+a_shift_loop:
+       ld  r25, -Y /* warning: this is PREdecrement */
+       std Y+4, r25
+       dec r21
+       brne a_shift_loop
+
+       ldd Bck1, Y+4*4+0
+       ldd Bck2, Y+4*4+1
+       ldd Bck3, Y+4*4+2
+       ldd Bck4, Y+4*4+3
+       add Bck1, T1
+       adc Bck2, T2
+       adc Bck3, T3
+       adc Bck4, T4
+       std Y+4*4+0, Bck1
+       std Y+4*4+1, Bck2
+       std Y+4*4+2, Bck3
+       std Y+4*4+3, Bck4
+       add Accu1, T1
+       adc Accu2, T2
+       adc Accu3, T3
+       adc Accu4, T4
+       std Y+4*0+0, Accu1
+       std Y+4*0+1, Accu2
+       std Y+4*0+2, Accu3
+       std Y+4*0+3, Accu4 /* a array updated */
+       
+       
+       dec LoopC
+       breq update_state
+       rjmp sha256_main_loop ;brne sha256_main_loop
+update_state:  
+       /* update state */
+       /* pointers to state should still exist on the stack ;-) */
+       pop r31
+       pop r30
+       ldi r21, 8
+update_state_loop:
+       ldd Accu1, Z+0
+       ldd Accu2, Z+1
+       ldd Accu3, Z+2
+       ldd Accu4, Z+3 
+       ld Func1, Y+
+       ld Func2, Y+
+       ld Func3, Y+
+       ld Func4, Y+
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       st Z+, Accu1
+       st Z+, Accu2
+       st Z+, Accu3
+       st Z+, Accu4
+       dec r21
+       brne update_state_loop
+       /* now we just have to update the length */
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
+       ldi r21, 2
+       ldi r22, 6
+       ld r20, Z
+       add r20, r21
+       st Z+, r20      
+       clr r21
+sha256_nextBlock_fix_length:   
+       brcc sha256_nextBlock_epilog
+       ld r20, Z
+       adc r20, r21
+       st Z+, r20
+       dec r22
+       brne sha256_nextBlock_fix_length
+       
+; EPILOG
+sha256_nextBlock_epilog:
+/* now we should clean up the stack */
+       
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4 
+       ret
+
+sha256_kv: ; round-key-vector stored in ProgMem 
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
+
+       
+;###########################################################   
+
+.global sha256_init 
+;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);
+;}
+; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha256_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha256_init_vector))
+       ldi r31, hi8((sha256_init_vector))
+       ldi r22, 32+8
+sha256_init_vloop:     
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha256_init_vloop
+       ret
+       
+sha256_init_vector:
+.word 0xE667, 0x6A09
+.word 0xAE85, 0xBB67 
+.word 0xF372, 0x3C6E 
+.word 0xF53A, 0xA54F 
+.word 0x527F, 0x510E 
+.word 0x688C, 0x9B05 
+.word 0xD9AB, 0x1F83 
+.word 0xCD19, 0x5BE0
+.word 0x0000, 0x0000
+.word 0x0000, 0x0000
+
+;###########################################################   
+
+.global rotl32
+; === ROTL32 ===
+; function that rotates a 32 bit word to the left
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,r22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       clr r21
+       clc
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       rol r21
+       dec r20
+       rjmp bitrotl_loop
+fixrotl:
+       or r22, r21
+       ret
+       
+
+;###########################################################   
+
+.global rotr32
+; === ROTR32 ===
+; function that rotates a 32 bit word to the right
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotr32:
+       cpi r20, 8
+       brlo bitrotr
+       mov r21, r22
+       mov r22, r23
+       mov r23, r24
+       mov r24, r25
+       mov r25, r21
+       subi r20, 8
+       rjmp rotr32
+bitrotr:
+       clr r21
+       clc
+bitrotr_loop:  
+       tst r20
+       breq fixrotr
+       ror r25
+       ror r24
+       ror r23
+       ror r22
+       ror r21
+       dec r20
+       rjmp bitrotr_loop
+fixrotr:
+       or r25, r21
+       ret
+       
+       
+;###########################################################   
+       
+.global change_endian32
+; === change_endian32 ===
+; function that changes the endianess of a 32-bit word
+;  param1: the 32-bit word
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  modifys: r21, r22
+change_endian32:
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)
+       mov r22, r25
+       mov r23, r24
+       mov r24, r21
+       mov r25, r20 
+       ret
+
diff --git a/shabea/sha256.h b/shabea/sha256.h
new file mode 100644 (file)
index 0000000..24960a3
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialise a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automaticaly hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/shabea/shabea.c b/shabea/shabea.c
new file mode 100644 (file)
index 0000000..b59e138
--- /dev/null
@@ -0,0 +1,91 @@
+/* shabea.c */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file       shabea.c
+ * \author     Daniel Otte 
+ * \date       2007-06-07
+ * \brief      SHABEA - a SHA Based Encryption Algorithm implementation
+ * \par License        
+ * GPL
+ * 
+ * SHABEAn-r where n is the blocksize and r the number of round used
+ * 
+ * 
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "sha256.h"
+
+#include "config.h"
+#include "memxor.h"
+
+
+/*
+ * SHABEA256-n
+ */ 
+#define SHABEA_BLOCKSIZE 256
+#define SHABEA_BLOCKSIZEB (SHABEA_BLOCKSIZE/8)
+#define SHABEA_HALFSIZEB  (SHABEA_BLOCKSIZEB/2)
+#define SHABEA_HALFSIZE (SHABEA_BLOCKSIZE/2)
+
+#define L ((uint8_t*)block+ 0)
+#define R ((uint8_t*)block+16)
+void shabea256(void * block, void * key, uint16_t keysize_b, uint8_t enc, uint8_t rounds){
+       uint8_t r;              /**/
+       uint8_t tb[SHABEA_HALFSIZEB+2+(keysize_b+7)/8]; /**/
+       uint16_t kbs;   /* bytes used for the key / temporary block */
+       sha256_hash_t hash;
+       uint8_t termcond; 
+       int8_t dir;
+       if(enc){
+               r = 0;
+               termcond = rounds-1;
+               dir = 1;
+       } else {
+               r = rounds-1;
+               termcond = 0;
+               dir = -1;
+       }
+       kbs = (keysize_b+7)/8;
+       memcpy(tb+SHABEA_HALFSIZEB+2, key, kbs); /* copy key to temporary block */
+       tb[SHABEA_HALFSIZEB+0] = 0;     /* set round counter high value to zero */
+       
+       for(;;r+=dir){ /* enc: 0..(rounds-1) ; !enc: (rounds-1)..0 */
+               memcpy(tb, R, SHABEA_HALFSIZEB); /* copy right half into tb */
+               tb[SHABEA_HALFSIZEB+1] = r;
+               sha256(&hash, tb, SHABEA_HALFSIZE+16+keysize_b);
+               if(r!=termcond){        
+                       /* swap */
+                       memxor(hash, L, SHABEA_HALFSIZEB);
+                       memcpy(L, R, SHABEA_HALFSIZEB);
+                       memcpy(R, hash, SHABEA_HALFSIZEB);
+               } else {
+                       /* last round */
+                       /* no swap */
+                       memxor(L, hash, SHABEA_HALFSIZEB);
+                       return; 
+               }
+       }
+}
+
+
diff --git a/shabea/shabea.h b/shabea/shabea.h
new file mode 100644 (file)
index 0000000..fdb4916
--- /dev/null
@@ -0,0 +1,39 @@
+/* shabea.h */
+/*
+ *   This file is part of AnonAccess, an access system which can be used
+ *    to open door or doing other things with an anonymity featured
+ *    account managment.
+ *   Copyright (C) 2006, 2007, 2008  Daniel Otte (daniel.otte@rub.de)
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * \file       shabea.h
+ * \author     Daniel Otte 
+ * \date       2007-06-07
+ * \brief      SHABEA - a SHA Based Encryption Algorithm declarations
+ * \par License        
+ * GPL
+ * 
+ * SHABEAn-r where n is the blocksize and r the number of round used
+ * 
+ */
+#ifndef SHABEA_H_
+#define SHABEA_H_
+
+void shabea256(void * block, void * key, uint16_t keysize_b, uint8_t enc, uint8_t rounds);
+#endif /*SHABEA_H_*/
diff --git a/shacal1/sha1-asm.S b/shacal1/sha1-asm.S
new file mode 100644 (file)
index 0000000..f571685
--- /dev/null
@@ -0,0 +1,886 @@
+/* sha1-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; SHA1 implementation in assembler for AVR
+SHA1_BLOCK_BITS = 512
+SHA1_HASH_BITS = 160
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+.macro delay
+/*     
+       push r0
+       push r1
+       clr r0
+1:     clr r1
+2:     dec r1
+       brne 2b
+       dec r0
+       brne 1b
+       pop r1
+       pop r0  // */
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+/*     
+       precall
+       hexdump \length
+       postcall
+       // */
+.endm
+
+
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha1_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha1_ctx2hash
+; === sha1_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha1_ctx structure
+;      given in r23,r22
+sha1_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 5
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha1
+; === sha1 ===
+; this function calculates SHA-1 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha1:
+sha1_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 5*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha1_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha1_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha1_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha1_ctx2hash     
+       
+sha1_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 5*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha1_lastBlock
+; === sha1_lastBlock ===
+; this function does padding & Co. for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha1_lastBlock_localSpace = (SHA1_BLOCK_BITS/8+1)
+
+
+sha1_lastBlock:
+       cpi r21, 0x02
+       brlo sha1_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 2
+       subi r23, -2
+       rjmp sha1_lastBlock
+sha1_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64) /* ??? */
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha1_lastBlock_post_copy
+       mov r1, r18
+sha1_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha1_lastBlock_copy_loop
+sha1_lastBlock_post_copy:      
+sha1_lastBlock_insert_stuffing_bit:    
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha1_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha1_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*5+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha1_lastBlock_insert_zeros:   
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha1_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha1_lastBlock_epilog
+sha1_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 5*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha1_nextBlock
+
+sha1_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha1_nextBlock
+; === sha1_nextBlock ===
+; this is the core function for calculating SHA-1 hashes
+;  param1: the 16-bit pointer to sha1_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha1_nextBlock_localSpace = (16+5+1)*4 ; 16 32-bit values for w array and 5 32-bit values for a array (total 84 byte)
+
+xtmp = 0
+xNULL = 1
+W1 = 10
+W2 = 11
+T1     = 12
+T2     = 13
+T3     = 14
+T4     = 15
+LoopC = 16
+S        = 17
+tmp1 = 18
+tmp2 = 19
+tmp3 = 20
+tmp4 = 21
+F1 = 22
+F2 = 23
+F3 = 24
+F4 = 25
+
+/* byteorder: high number <--> high significance */
+sha1_nextBlock:
+ ; initial, let's make some space ready for local vars
+                        /* replace push & pop by mem ops? */
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack /* maybe removeable? */ 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha1_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha1_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       push r18
+       push r19 /* push old SP on new stack */
+       push r24
+       push r25 /* param1 will be needed later */
+       
+       /* load a[] with state */
+       movw 28, r24 /* load pointer to state in Y */
+       adiw r26, 1 ; X++
+
+       ldi LoopC, 5*4  
+1:     ld tmp1, Y+
+       st X+, tmp1
+       dec LoopC
+       brne 1b
+
+       movw W1, r26 /* save pointer to w[0] */
+       /* load w[] with endian fixed message */
+               /* we might also use the changeendian32() function at bottom */
+       movw r30, r22 /* mv param2 (ponter to msg) to Z */      
+       ldi LoopC, 16
+1:
+       ldd tmp1, Z+3
+       st X+, tmp1
+       ldd tmp1, Z+2
+       st X+, tmp1
+       ldd tmp1, Z+1
+       st X+, tmp1
+       ld tmp1, Z
+       st X+, tmp1
+       adiw r30, 4
+       dec LoopC
+       brne 1b
+       
+       ;clr LoopC /* LoopC is named t in FIPS 180-2 */ 
+       clr xtmp
+sha1_nextBlock_mainloop:
+       mov S, LoopC
+       lsl S
+       lsl S
+       andi S, 0x3C /* S is a bytepointer so *4 */
+       /* load w[s] */
+       movw r26, W1
+       add r26, S /* X points at w[s] */
+       adc r27, xNULL
+       ld T1, X+
+       ld T2, X+
+       ld T3, X+
+       ld T4, X+
+
+       /**/
+       push r26
+       push r27
+       push T4
+       push T3
+       push T2
+       push T1
+       in r26, SPL
+       in r27, SPH
+       adiw r26, 1
+       dbg_hexdump 4
+       pop T1
+       pop T2
+       pop T3
+       pop T4
+       pop r27
+       pop r26
+       /**/
+
+       cpi LoopC, 16
+       brlt sha1_nextBlock_mainloop_core
+       /* update w[s] */
+       ldi tmp1, 2*4
+       rcall 1f
+       ldi tmp1, 8*4
+       rcall 1f
+       ldi tmp1, 13*4
+       rcall 1f
+       rjmp 2f
+1:             /* this might be "outsourced" to save the jump above */
+       add tmp1, S
+       andi tmp1, 0x3f
+       movw r26, W1
+       add r26, tmp1
+       adc r27, xNULL
+       ld tmp2, X+
+       eor T1, tmp2
+       ld tmp2, X+
+       eor T2, tmp2
+       ld tmp2, X+
+       eor T3, tmp2
+       ld tmp2, X+
+       eor T4, tmp2
+       ret
+2:     /* now we just hav to do a ROTL(T) and save T back */
+       mov tmp2, T4
+       rol tmp2
+       rol T1
+       rol T2
+       rol T3
+       rol T4
+       movw r26, W1
+       add r26, S
+       adc r27, xNULL
+       st X+, T1
+       st X+, T2
+       st X+, T3
+       st X+, T4
+       
+sha1_nextBlock_mainloop_core:  /* ther core function; T=ROTL5(a) ....*/        
+                                                               /* T already contains w[s] */
+       movw r26, W1
+       sbiw r26, 4*1           /* X points at a[4] aka e */
+       ld tmp1, X+ 
+       add T1, tmp1
+       ld tmp1, X+ 
+       adc T2, tmp1
+       ld tmp1, X+ 
+       adc T3, tmp1
+       ld tmp1, X+ 
+       adc T4, tmp1            /* T = w[s]+e */
+       sbiw r26, 4*5           /* X points at a[0] aka a */
+       ld F1, X+ 
+       ld F2, X+ 
+       ld F3, X+ 
+       ld F4, X+ 
+       mov tmp1, F4            /* X points at a[1] aka b */
+       ldi tmp2, 5
+1:
+       rol tmp1
+       rol F1
+       rol F2
+       rol F3
+       rol F4
+       dec tmp2
+       brne 1b
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, F4 /* T = ROTL(a,5) + e + w[s] */
+       
+       /* now we have to do this fucking conditional stuff */
+       ldi r30, lo8(sha1_nextBlock_xTable)
+       ldi r31, hi8(sha1_nextBlock_xTable)
+       add r30, xtmp
+       adc r31, xNULL
+       lpm tmp1, Z
+       cp tmp1, LoopC
+       brne 1f
+       inc xtmp
+1:     ldi r30, lo8(sha1_nextBlock_KTable)
+       ldi r31, hi8(sha1_nextBlock_KTable)
+       lsl xtmp
+       lsl xtmp
+       add r30, xtmp
+       adc r31, xNULL
+       lsr xtmp
+       lsr xtmp
+        
+       lpm tmp1, Z+
+       add T1, tmp1
+       lpm tmp1, Z+
+       adc T2, tmp1
+       lpm tmp1, Z+
+       adc T3, tmp1
+       lpm tmp1, Z+
+       adc T4, tmp1
+                       /* T = ROTL(a,5) + e + kt + w[s] */
+       
+       /* Z-4 is just pointing to kt ... */
+       movw r28, r26 /* copy X in Y */
+       adiw r30, 3*4 /* now Z points to the rigth locatin in our jump-vector-table */
+       lsr r31
+       ror r30
+               
+       icall
+       mov F1, tmp1
+       icall
+       mov F2, tmp1
+       icall
+       mov F3, tmp1
+       icall
+       
+       add T1, F1
+       adc T2, F2
+       adc T3, F3
+       adc T4, tmp1 /* T = ROTL5(a) + f_t(b,c,d) + e + k_t + w[s] */
+                                /* X points still at a[1] aka b, Y points at a[2] aka c */     
+       /* update a[] */
+sha1_nextBlock_update_a:
+       /*first we move all vars in a[] "one up" e=d, d=c, c=b, b=a*/
+       //adiw r28, 3*4  /* Y should point at a[4] aka e */
+       movw r28, W1
+       sbiw r28, 4
+       
+       ldi tmp2, 4*4 
+1:     
+       ld tmp1, -Y
+       std Y+4, tmp1
+       dec tmp2
+       brne 1b
+       /* Y points at a[0] aka a*/
+       
+       movw r28, W1
+       sbiw r28, 5*4
+       /* store T in a[0] aka a */
+       st Y+, T1
+       st Y+, T2
+       st Y+, T3
+       st Y+, T4
+       /* Y points at a[1] aka b*/
+       
+       /* rotate c */
+       ldd T1, Y+1*4
+       ldd T2, Y+1*4+1
+       ldd T3, Y+1*4+2
+       ldd T4, Y+1*4+3
+       mov tmp1, T1
+       ldi tmp2, 2
+1:     ror tmp1
+       ror T4
+       ror T3
+       ror T2
+       ror T1
+       dec tmp2
+       brne 1b
+       std Y+1*4+0, T1
+       std Y+1*4+1, T2
+       std Y+1*4+2, T3
+       std Y+1*4+3, T4
+       
+       push r27
+       push r26
+       movw r26, W1
+       sbiw r26, 4*5
+       dbg_hexdump 4*5
+       pop r26
+       pop r27
+       
+       inc LoopC
+       cpi LoopC, 80
+       brge 1f
+       rjmp sha1_nextBlock_mainloop
+/**************************************/
+1:     
+   /* littel patch */
+       sbiw r28, 4
+
+/* add a[] to state and inc length */  
+       pop r27
+       pop r26         /* now X points to state (and Y still at a[0]) */
+       ldi tmp4, 5
+1:     clc
+       ldi tmp3, 4
+2:     ld tmp1, X
+       ld tmp2, Y+
+       adc tmp1, tmp2
+       st X+, tmp1
+       dec tmp3
+       brne 2b
+       dec tmp4
+       brne 1b
+       
+       /* now length += 512 */
+       adiw r26, 1 /* we skip the least significant byte */
+       ld tmp1, X
+       ldi tmp2, hi8(512) /* 2 */
+       add tmp1, tmp2
+       st X+, tmp1
+       ldi tmp2, 6
+1:
+       ld tmp1, X
+       adc tmp1, xNULL
+       st X+, tmp1
+       dec tmp2
+       brne 1b
+       
+; EPILOG
+sha1_nextBlock_epilog:
+/* now we should clean up the stack */
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       ret
+
+sha1_nextBlock_xTable:
+.byte 20,40,60,0
+sha1_nextBlock_KTable:
+.int   0x5a827999 
+.int   0x6ed9eba1 
+.int   0x8f1bbcdc 
+.int   0xca62c1d6
+sha1_nextBlock_JumpTable:
+rjmp sha1_nextBlock_Ch
+       nop     
+rjmp sha1_nextBlock_Parity
+       nop
+rjmp sha1_nextBlock_Maj
+       nop
+rjmp sha1_nextBlock_Parity
+
+        /* X and Y still point at a[1] aka b ; return value in tmp1 */
+sha1_nextBlock_Ch:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       com tmp2
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp3, Y+7   /* load from d */
+       and tmp2, tmp3
+       eor tmp1, tmp2
+       ret
+       
+sha1_nextBlock_Maj:
+       ld tmp1, Y+
+       mov tmp2, tmp1
+       ldd tmp3, Y+3   /* load from c */
+       and tmp1, tmp3
+       ldd tmp4, Y+7   /* load from d */
+       and tmp2, tmp4
+       eor tmp1, tmp2
+       and tmp3, tmp4
+       eor tmp1, tmp3
+       ret
+
+sha1_nextBlock_Parity:
+       ld tmp1, Y+
+       ldd tmp2, Y+3   /* load from c */
+       eor tmp1, tmp2
+       ldd tmp2, Y+7   /* load from d */
+       eor tmp1, tmp2
+       ret
+/*     
+ch_str:                        .asciz "\r\nCh"
+maj_str:               .asciz "\r\nMaj"
+parity_str:    .asciz "\r\nParity"
+*/
+;###########################################################   
+
+.global sha1_init 
+;void sha1_init(sha1_ctx_t *state){
+;      DEBUG_S("\r\nSHA1_INIT");
+;      state->h[0] = 0x67452301;
+;      state->h[1] = 0xefcdab89;
+;      state->h[2] = 0x98badcfe;
+;      state->h[3] = 0x10325476;
+;      state->h[4] = 0xc3d2e1f0;
+;      state->length = 0;
+;}
+; param1: (Func3,r24) 16-bit pointer to sha1_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha1_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha1_init_vector))
+       ldi r31, hi8((sha1_init_vector))
+       ldi r22, 5*4 /* bytes to copy */
+sha1_init_vloop:       
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha1_init_vloop
+       ldi r22, 8
+sha1_init_lloop:
+       st X+, r1
+       dec r22
+       brne sha1_init_lloop
+       ret
+       
+sha1_init_vector:
+.int 0x67452301;
+.int 0xefcdab89;
+.int 0x98badcfe;
+.int 0x10325476;
+.int 0xc3d2e1f0;
+
diff --git a/shacal1/sha1.h b/shacal1/sha1.h
new file mode 100644 (file)
index 0000000..6675d20
--- /dev/null
@@ -0,0 +1,117 @@
+/* sha1.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha1.h
+ * \author     Daniel Otte
+ * \email   daniel.otte@rub.de
+ * \date       2006-10-08
+ * \license GPLv3 or later
+ * \brief   SHA-1 declaration.
+ * \ingroup SHA-1
+ * 
+ */
+#ifndef SHA1_H_
+#define SHA1_H_
+
+#include <stdint.h>
+/** \def SHA1_HASH_BITS
+ * definees the size of a SHA-1 hash in bits 
+ */
+
+/** \def SHA1_HASH_BYTES
+ * definees the size of a SHA-1 hash in bytes 
+ */
+
+/** \def SHA1_BLOCK_BITS
+ * definees the size of a SHA-1 input block in bits 
+ */
+
+/** \def SHA1_BLOCK_BYTES
+ * definees the size of a SHA-1 input block in bytes 
+ */
+#define SHA1_HASH_BITS  160
+#define SHA1_HASH_BYTES (SHA1_HASH_BITS/8)
+#define SHA1_BLOCK_BITS 512
+#define SHA1_BLOCK_BYTES (SHA1_BLOCK_BITS/8)
+
+/** \typedef sha1_ctx_t
+ * \brief SHA-1 context type
+ * 
+ * A vatiable of this type may hold the state of a SHA-1 hashing process
+ */
+typedef struct {
+       uint32_t h[5];
+       uint64_t length;
+} sha1_ctx_t;
+
+/** \typedef sha1_hash_t
+ * \brief hash value type
+ * A variable of this type may hold a SHA-1 hash value 
+ */
+typedef uint8_t sha1_hash_t[SHA1_HASH_BITS/8];
+
+/** \fn sha1_init(sha1_ctx_t *state)
+ * \brief initializes a SHA-1 context
+ * This function sets a ::sha1_ctx_t variable to the initialization vector
+ * for SHA-1 hashing.
+ * \param state pointer to the SHA-1 context variable
+ */
+void sha1_init(sha1_ctx_t *state);
+
+/** \fn sha1_nextBlock(sha1_ctx_t *state, const void* block)
+ *  \brief process one input block
+ * This function processes one input block and updates the hash context 
+ * accordingly
+ * \param state pointer to the state variable to update
+ * \param block pointer to the message block to process
+ */
+void sha1_nextBlock (sha1_ctx_t *state, const void* block);
+
+/** \fn sha1_lastBlock(sha1_ctx_t *state, const void* block, uint16_t length_b)
+ * \brief processes the given block and finalizes the context
+ * This function processes the last block in a SHA-1 hashing process.
+ * The block should have a maximum length of a single input block.
+ * \param state pointer to the state variable to update and finalize
+ * \param block pointer to themessage block to process
+ * \param length_b length of the message block in bits  
+ */
+void sha1_lastBlock (sha1_ctx_t *state, const void* block, uint16_t length_b);
+
+/** \fn sha1_ctx2hash(sha1_hash_t *dest, sha1_ctx_t *state)
+ * \brief convert a state variable into an actual hash value
+ * Writes the hash value corresponding to the state to the memory pointed by dest.
+ * \param dest pointer to the hash value destination
+ * \param state pointer to the hash context
+ */ 
+void sha1_ctx2hash (sha1_hash_t *dest, sha1_ctx_t *state);
+
+/** \fn sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b)
+ * \brief hashing a message which in located entirely in RAM
+ * This function automatically hashes a message which is entirely in RAM with
+ * the SHA-1 hashing algorithm.
+ * \param dest pointer to the hash value destination
+ * \param msg  pointer to the message which should be hashed
+ * \param length_b length of the message in bits
+ */ 
+void sha1(sha1_hash_t *dest, const void* msg, uint32_t length_b);
+
+
+
+#endif /*SHA1_H_*/
diff --git a/shacal1/shacal1_enc.c b/shacal1/shacal1_enc.c
new file mode 100644 (file)
index 0000000..634f18d
--- /dev/null
@@ -0,0 +1,54 @@
+/* shacal1_enc.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       shacal1_enc.c
+ * \author     Daniel Otte
+ * \date       2008-05-06
+ * \par License:
+ * GPL
+ * \brief SHACAL1 encryption only implementation.
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sha1.h"
+#include "shacal1_enc.h"
+
+void shacal1_enc(void* buffer, void* key, uint16_t keysize_b){
+       sha1_ctx_t ctx, t_ctx;
+       uint8_t i;
+       memcpy(t_ctx.h, buffer, SHA1_HASH_BITS/8);
+       
+       uint8_t keybuffer[SHA1_BLOCK_BITS/8];
+       memset(keybuffer, 0, SHA1_BLOCK_BITS/8);
+       if(keysize_b>SHA1_BLOCK_BITS)
+               keysize_b=SHA1_BLOCK_BITS;
+       memcpy(keybuffer, key, (keysize_b+7)/8);
+       
+       memcpy(t_ctx.h, buffer, SHA1_HASH_BITS/8);
+       sha1_ctx2hash((sha1_hash_t*)(&(ctx.h[0])), &t_ctx);
+       memcpy(t_ctx.h, ctx.h, SHA1_HASH_BITS/8);
+       sha1_nextBlock(&ctx, keybuffer);
+       for(i=0; i<5; ++i)
+               ctx.h[i] -= t_ctx.h[i];
+       sha1_ctx2hash(buffer, &ctx);
+}
+
+
diff --git a/shacal1/shacal1_enc.h b/shacal1/shacal1_enc.h
new file mode 100644 (file)
index 0000000..e1bdd98
--- /dev/null
@@ -0,0 +1,31 @@
+/* shacal1_enc.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SHACAL1_ENC_H_
+#define SHACAL1_ENC_H_
+
+#include <stdint.h>
+
+#define SHACAL1_BLOCKSIZE 160
+#define SHACAL1_BLOCKSIZE_B ((SHACAL1_BLOCKSIZE+7)/8)
+#define SHACAL1_KEYSIZE 512
+#define SHACAL1_KEYSIZE_B ((SHACAL1_KEYSIZE+7)/8)
+
+void shacal1_enc(void* buffer, void* key, uint16_t keysize_b);
+
+#endif /*SHACAL1_ENC_H_*/
diff --git a/shacal1_enc.c b/shacal1_enc.c
deleted file mode 100644 (file)
index 634f18d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* shacal1_enc.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       shacal1_enc.c
- * \author     Daniel Otte
- * \date       2008-05-06
- * \par License:
- * GPL
- * \brief SHACAL1 encryption only implementation.
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "sha1.h"
-#include "shacal1_enc.h"
-
-void shacal1_enc(void* buffer, void* key, uint16_t keysize_b){
-       sha1_ctx_t ctx, t_ctx;
-       uint8_t i;
-       memcpy(t_ctx.h, buffer, SHA1_HASH_BITS/8);
-       
-       uint8_t keybuffer[SHA1_BLOCK_BITS/8];
-       memset(keybuffer, 0, SHA1_BLOCK_BITS/8);
-       if(keysize_b>SHA1_BLOCK_BITS)
-               keysize_b=SHA1_BLOCK_BITS;
-       memcpy(keybuffer, key, (keysize_b+7)/8);
-       
-       memcpy(t_ctx.h, buffer, SHA1_HASH_BITS/8);
-       sha1_ctx2hash((sha1_hash_t*)(&(ctx.h[0])), &t_ctx);
-       memcpy(t_ctx.h, ctx.h, SHA1_HASH_BITS/8);
-       sha1_nextBlock(&ctx, keybuffer);
-       for(i=0; i<5; ++i)
-               ctx.h[i] -= t_ctx.h[i];
-       sha1_ctx2hash(buffer, &ctx);
-}
-
-
diff --git a/shacal1_enc.h b/shacal1_enc.h
deleted file mode 100644 (file)
index e1bdd98..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* shacal1_enc.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef SHACAL1_ENC_H_
-#define SHACAL1_ENC_H_
-
-#include <stdint.h>
-
-#define SHACAL1_BLOCKSIZE 160
-#define SHACAL1_BLOCKSIZE_B ((SHACAL1_BLOCKSIZE+7)/8)
-#define SHACAL1_KEYSIZE 512
-#define SHACAL1_KEYSIZE_B ((SHACAL1_KEYSIZE+7)/8)
-
-void shacal1_enc(void* buffer, void* key, uint16_t keysize_b);
-
-#endif /*SHACAL1_ENC_H_*/
diff --git a/shacal2/sha256-asm.S b/shacal2/sha256-asm.S
new file mode 100644 (file)
index 0000000..d9eb6b6
--- /dev/null
@@ -0,0 +1,1042 @@
+/* sha256-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author:     Daniel Otte
+ *
+ * License: GPLv3 or later
+*/
+; sha-256 implementation in assembler  
+SHA256_BLOCK_BITS = 512
+SHA256_HASH_BITS = 256
+
+.macro precall
+       /* push r18 - r27, r30 - r31*/
+       push r0
+       push r1
+       push r18
+       push r19
+       push r20
+       push r21
+       push r22
+       push r23
+       push r24
+       push r25
+       push r26
+       push r27
+       push r30
+       push r31
+       clr r1
+.endm
+
+.macro postcall
+       pop r31
+       pop r30
+       pop r27
+       pop r26
+       pop r25
+       pop r24
+       pop r23
+       pop r22
+       pop r21
+       pop r20
+       pop r19
+       pop r18
+       pop r1
+       pop r0
+.endm
+
+
+.macro hexdump length
+       push r27
+       push r26
+       ldi r25, '\r'
+       mov r24, r25
+       call uart_putc
+       ldi r25, '\n'
+       mov r24, r25
+       call uart_putc
+       pop r26
+       pop r27
+       movw r24, r26
+.if \length > 16
+       ldi r22, lo8(16)
+       ldi r23, hi8(16)
+       push r27
+       push r26
+       call uart_hexdump
+       pop r26
+       pop r27
+       adiw r26, 16
+       hexdump \length-16
+.else
+       ldi r22, lo8(\length)
+       ldi r23, hi8(\length)
+       call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+       precall
+       hexdump \length
+       postcall
+.endm
+
+.section .text
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+
+
+;
+;sha256_ctx_t is:
+;
+; [h0][h1][h2][h3][h4][h5][h6][h7][length]
+; hn is 32 bit large, length is 64 bit large
+
+;###########################################################   
+
+.global sha256_ctx2hash
+; === sha256_ctx2hash ===
+; this function converts a state into a normal hash (bytestring)
+;  param1: the 16-bit destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to sha256_ctx structure
+;      given in r23,r22
+sha256_ctx2hash:
+       movw r26, r22
+       movw r30, r24
+       ldi r21, 8
+       sbiw r26, 4
+1:     
+       ldi r20, 4
+       adiw r26, 8
+2:     
+               ld r0, -X
+               st Z+, r0       
+       dec r20
+       brne 2b
+       
+       dec r21
+       brne 1b
+       
+       ret
+
+;###########################################################   
+
+.global sha256
+; === sha256 ===
+; this function calculates SHA-256 hashes from messages in RAM
+;  param1: the 16-bit hash destination pointer
+;      given in r25,r24 (r25 is most significant)
+;  param2: the 16-bit pointer to message
+;      given in r23,r22
+;  param3: 32-bit length value (length of message in bits)
+;   given in r21,r20,r19,r18
+sha256:
+sha256_prolog:
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r16
+       push r17
+       in r16, SPL
+       in r17, SPH
+       subi r16, 8*4+8 
+       sbci r17, 0     
+       in r0, SREG
+       cli
+       out SPL, r16
+       out SPH, r17
+       out SREG, r0
+       
+       push r25
+       push r24
+       inc r16
+       adc r17, r1
+       
+       movw r8, r18            /* backup of length*/
+       movw r10, r20
+       
+       movw r12, r22   /* backup pf msg-ptr */
+       
+       movw r24, r16
+       rcall sha256_init
+       /* if length >= 512 */
+1:
+       tst r11
+       brne 4f
+       tst r10
+       brne 4f
+       mov r19, r9
+       cpi r19, 0x02
+       brlo 4f
+       
+       movw r24, r16
+       movw r22, r12
+       rcall sha256_nextBlock
+       ldi r19, 0x64
+       add r22, r19
+       adc r23, r1
+       /* length -= 512 */
+       ldi r19, 0x02
+       sub r9, r19
+       sbc r10, r1
+       sbc r11, r1
+       rjmp 1b
+       
+4:
+       movw r24, r16
+       movw r22, r12
+       movw r20, r8
+       rcall sha256_lastBlock
+       
+       pop r24
+       pop r25
+       movw r22, r16
+       rcall sha256_ctx2hash   
+       
+sha256_epilog:
+       in r30, SPL
+       in r31, SPH
+       adiw r30, 8*4+8         
+       in r0, SREG
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG, r0
+       pop r17
+       pop r16
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       ret
+
+;###########################################################   
+
+
+; block MUST NOT be larger than 64 bytes
+
+.global sha256_lastBlock
+; === sha256_lastBlock ===
+; this function does padding & Co. for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+;  param3: an 16-bit integer specifing length of block in bits
+;      given in r21,r20
+sha256_lastBlock_localSpace = (SHA256_BLOCK_BITS/8+1)
+
+
+sha256_lastBlock:
+       cpi r21, 0x02
+       brlo sha256_lastBlock_prolog
+       push r25
+       push r24
+       push r23
+       push r22
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r22
+       pop r23
+       pop r24
+       pop r25
+       subi r21, 0x02
+       subi r23, -2
+       rjmp sha256_lastBlock   
+sha256_lastBlock_prolog:
+       /* allocate space on stack */
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       subi r30, lo8(64)
+       sbci r31, hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+
+       adiw r30, 1 /* SP points to next free byte on stack */
+       mov r18, r20 /* r20 = LSB(length) */
+       lsr r18
+       lsr r18
+       lsr r18
+       bst r21, 0      /* may be we should explain this ... */
+       bld r18, 5  /* now: r18 == length/8 (aka. length in bytes) */
+       
+       
+       movw r26, r22 /* X points to begin of msg */
+       tst r18
+       breq sha256_lastBlock_post_copy
+       mov r1, r18
+sha256_lastBlock_copy_loop:
+       ld r0, X+
+       st Z+, r0
+       dec r1
+       brne sha256_lastBlock_copy_loop
+sha256_lastBlock_post_copy:    
+sha256_lastBlock_insert_stuffing_bit:  
+       ldi r19, 0x80
+       mov r0,r19      
+       ldi r19, 0x07
+       and r19, r20 /* if we are in bitmode */
+       breq 2f /* no bitmode */
+1:     
+       lsr r0
+       dec r19
+       brne 1b
+       ld r19, X
+/* maybe we should do some ANDing here, just for safety */
+       or r0, r19
+2:     
+       st Z+, r0
+       inc r18
+
+/* checking stuff here */
+       cpi r18, 64-8+1
+       brsh 0f 
+       rjmp sha256_lastBlock_insert_zeros
+0:
+       /* oh shit, we landed here */
+       /* first we have to fill it up with zeros */
+       ldi r19, 64
+       sub r19, r18
+       breq 2f
+1:     
+       st Z+, r1
+       dec r19
+       brne 1b 
+2:     
+       sbiw r30, 63
+       sbiw r30,  1
+       movw r22, r30
+       
+       push r31
+       push r30
+       push r25
+       push r24
+       push r21
+       push r20
+       rcall sha256_nextBlock
+       pop r20
+       pop r21
+       pop r24
+       pop r25
+       pop r30
+       pop r31
+       
+       /* now we should subtract 512 from length */
+       movw r26, r24
+       adiw r26, 4*8+1 /* we can skip the lowest byte */
+       ld r19, X
+       subi r19, hi8(512)
+       st X+, r19
+       ldi r18, 6
+1:
+       ld r19, X
+       sbci r19, 0
+       st X+, r19
+       dec r18
+       brne 1b
+       
+;      clr r18 /* not neccessary ;-) */
+       /* reset Z pointer to begin of block */
+
+sha256_lastBlock_insert_zeros: 
+       ldi r19, 64-8
+       sub r19, r18
+       breq sha256_lastBlock_insert_length
+       clr r1
+1:
+       st Z+, r1       /* r1 is still zero */
+       dec r19
+       brne 1b
+
+;      rjmp sha256_lastBlock_epilog
+sha256_lastBlock_insert_length:
+       movw r26, r24   /* X points to state */
+       adiw r26, 8*4   /* X points to (state.length) */
+       adiw r30, 8             /* Z points one after the last byte of block */
+       ld r0, X+
+       add r0, r20
+       st -Z, r0
+       ld r0, X+
+       adc r0, r21
+       st -Z, r0
+       ldi r19, 6
+1:
+       ld r0, X+
+       adc r0, r1
+       st -Z, r0
+       dec r19
+       brne 1b
+
+       sbiw r30, 64-8
+       movw r22, r30
+       rcall sha256_nextBlock
+
+sha256_lastBlock_epilog:
+       in r30, SPL
+       in r31, SPH
+       in r1, SREG
+       adiw r30, 63 ; lo8(64)
+       adiw r30,  1  ; hi8(64)
+       cli
+       out SPL, r30
+       out SPH, r31
+       out SREG,r1
+       clr r1
+       clr r0
+       ret
+
+/**/
+;###########################################################   
+
+.global sha256_nextBlock
+; === sha256_nextBlock ===
+; this is the core function for calculating SHA-256 hashes
+;  param1: the 16-bit pointer to sha256_ctx structure
+;      given in r25,r24 (r25 is most significant)
+;  param2: an 16-bit pointer to 64 byte block to hash
+;      given in r23,r22
+sha256_nextBlock_localSpace = (64+8)*4 ; 64 32-bit values for w array and 8 32-bit values for a array (total 288 byte)
+
+Bck1 = 12
+Bck2 = 13
+Bck3 = 14
+Bck4 = 15
+Func1 = 22
+Func2 = 23
+Func3 = 24
+Func4 = 25
+Accu1 = 16
+Accu2 = 17
+Accu3 = 18
+Accu4 = 19
+XAccu1 = 8
+XAccu2 = 9
+XAccu3 = 10
+XAccu4 = 11
+T1     = 4
+T2     = 5
+T3     = 6
+T4     = 7
+LoopC = 1
+/* byteorder: high number <--> high significance */
+sha256_nextBlock:
+ ; initial, let's make some space ready for local vars
+       push r4 /* replace push & pop by mem ops? */
+       push r5
+       push r6
+       push r7
+       push r8
+       push r9
+       push r10
+       push r11
+       push r12
+       push r13
+       push r14
+       push r15
+       push r16
+       push r17
+       push r28
+       push r29
+       in r20, SPL
+       in r21, SPH
+       movw r18, r20                   ;backup SP
+;      movw r26, r20                   ; X points to free space on stack 
+       movw r30, r22                   ; Z points to message
+       subi r20, lo8(sha256_nextBlock_localSpace) ;sbiw can do only up to 63
+       sbci r21, hi8(sha256_nextBlock_localSpace)
+       movw r26, r20                   ; X points to free space on stack 
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       push r18
+       push r19
+       push r24
+       push r25 /* param1 will be needed later */
+ ; now we fill the w array with message (think about endianess)
+       adiw r26, 1 ; X++
+       ldi r20, 16
+sha256_nextBlock_wcpyloop:     
+       ld r23, Z+
+       ld r22, Z+
+       ld r19, Z+
+       ld r18, Z+
+       st X+, r18
+       st X+, r19
+       st X+, r22      
+       st X+, r23
+       dec r20
+       brne sha256_nextBlock_wcpyloop
+/*     for (i=16; i<64; ++i){
+               w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];   
+       } */
+       /* r25,r24,r23,r24 (r21,r20) are function values
+          r19,r18,r17,r16 are the accumulator
+          r15,r14,r13,rBck1 are backup1
+          r11,r10,r9 ,r8  are xor accu   
+          r1 is round counter                                                          */
+
+       ldi r20, 64-16
+       mov LoopC, r20
+sha256_nextBlock_wcalcloop:             
+       movw r30, r26 ; cp X to Z
+       sbiw r30, 63
+       sbiw r30, 1             ; substract 64 = 16*4
+       ld Accu1, Z+
+       ld Accu2, Z+
+       ld Accu3, Z+
+       ld Accu4, Z+ /* w[i] = w[i-16] */
+       ld Bck1, Z+
+       ld Bck2, Z+
+       ld Bck3, Z+
+       ld Bck4, Z+ /* backup = w[i-15] */
+       /* now sigma 0 */
+       mov Func1, Bck2
+       mov Func2, Bck3
+       mov Func3, Bck4
+       mov Func4, Bck1  /* prerotated by 8 */
+       ldi r20, 1
+       rcall bitrotl
+       movw XAccu1, Func1
+       movw XAccu3, Func3       /* store ROTR(w[i-15],7) in xor accu */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-15], 18)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 3             /* now shr3 */ /*we can destroy backup now*/
+sigma0_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2
+       ror Bck1        
+       dec Func2
+       brne sigma0_shr
+       eor XAccu1, Bck1
+       eor XAccu2, Bck2
+       eor XAccu3, Bck3
+       eor XAccu4, Bck4        /* xor SHR(w[i-15], 3)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       ldd Func1, Z+7*4  /* now accu += w[i-7] */
+       ldd Func2, Z+7*4+1
+       ldd Func3, Z+7*4+2
+       ldd Func4, Z+7*4+3
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       ldd Bck1, Z+12*4 /* now backup = w[i-2]*/
+       ldd Bck2, Z+12*4+1
+       ldd Bck3, Z+12*4+2
+       ldd Bck4, Z+12*4+3
+       /* now sigma 1 */
+       movw Func1, Bck3
+       movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 1
+       rcall bitrotr
+       movw XAccu3, Func3
+       movw XAccu1, Func1       /* store in ROTR(w[i-2], 17) xor accu */
+;      movw Func1, Bck3
+;      movw Func3, Bck1 /* prerotated by 16 */
+       ldi r20, 2
+       rcall bitrotr
+       eor XAccu1, Func1  /* xor ROTR(w[i-2], 19)*/
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       ldi Func2, 2     /* now shr10 (dirty trick, skipping a byte) */ /*we can destroy backup now*/
+sigma1_shr:
+       lsr Bck4
+       ror Bck3
+       ror Bck2        
+       dec Func2
+       brne sigma1_shr
+       eor XAccu1, Bck2
+       eor XAccu2, Bck3
+       eor XAccu3, Bck4  /* xor SHR(w[i-2], 10)*/ /* xor accu == sigma1(w[i-15]) */
+       add Accu1, XAccu1
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4 /* finished with sigma0 */
+       /* now let's store the shit */
+       st X+, Accu1
+       st X+, Accu2
+       st X+, Accu3
+       st X+, Accu4
+       dec LoopC
+       breq 3f  ; skip if zero
+       rjmp sha256_nextBlock_wcalcloop
+3:
+       /* we are finished with w array X points one byte post w */
+/* init a array */
+       pop r31
+       pop r30
+       push r30
+       push r31
+       ldi r25, 8*4 /* 8 32-bit values to copy from ctx to a array */
+init_a_array:  
+       ld r1, Z+
+       st X+, r1
+       dec r25
+       brne init_a_array
+       
+/* now the real fun begins */
+/* 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;
+               } */
+       /* Y points to a[0], Z ('cause lpm wants it) points to k[i], X points to w[i] */
+       sbiw r26, 8*4  /* X still points at a[7]+1*/
+       movw r28, r26
+       ldi r30, lo8(sha256_kv)
+       ldi r31, hi8(sha256_kv)         
+       dec r27  /* X - (64*4 == 256) */
+       ldi r25, 64
+       mov LoopC, r25
+sha256_main_loop:
+       /* now calculate t1 */
+        /*CH(x,y,z) = (x&y)^((~x)&z)*/
+       ldd T1, Y+5*4
+       ldd T2, Y+5*4+1
+       ldd T3, Y+5*4+2
+       ldd T4, Y+5*4+3 /* y in T */
+       ldd Func1, Y+4*4
+       ldd Func2, Y+4*4+1
+       ldd Func3, Y+4*4+2
+       ldd Func4, Y+4*4+3  /* x in Func */
+       ldd Bck1, Y+6*4
+       ldd Bck2, Y+6*4+1
+       ldd Bck3, Y+6*4+2
+       ldd Bck4, Y+6*4+3 /* z in Bck */
+       and T1, Func1
+       and T2, Func2
+       and T3, Func3
+       and T4, Func4
+       com Func1
+       com Func2
+       com Func3
+       com Func4
+       and Bck1, Func1
+       and Bck2, Func2
+       and Bck3, Func3
+       and Bck4, Func4
+       eor T1, Bck1
+       eor T2, Bck2
+       eor T3, Bck3
+       eor T4, Bck4 /* done, CH(x,y,z) is in T */
+       /* now SIGMA1(a[4]) */
+       ldd Bck4, Y+4*4         /* think about using it from Func reg above*/
+       ldd Bck1, Y+4*4+1       
+       ldd Bck2, Y+4*4+2
+       ldd Bck3, Y+4*4+3 /* load prerotate by 8-bit */ 
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2 
+       rcall bitrotl           /* rotr(x,6) */ 
+       movw XAccu1, Func1
+       movw XAccu3, Func3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 3 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4
+       movw Func1, Bck3 /* this prerotates furteh 16 bits*/
+       movw Func3, Bck1 /* so we have now prerotated by 24 bits*/
+       ldi r20, 1 
+       rcall bitrotr   /* rotr(x,11) */
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4 /* finished with SIGMA1, add it to T */
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4
+       /* now we've to add a[7], w[i] and k[i] */
+       ldd XAccu1, Y+4*7
+       ldd XAccu2, Y+4*7+1
+       ldd XAccu3, Y+4*7+2
+       ldd XAccu4, Y+4*7+3
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add a[7] */
+       ld XAccu1, X+
+       ld XAccu2, X+
+       ld XAccu3, X+
+       ld XAccu4, X+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add w[i] */
+       lpm XAccu1, Z+
+       lpm XAccu2, Z+
+       lpm XAccu3, Z+
+       lpm XAccu4, Z+
+       add T1, XAccu1
+       adc T2, XAccu2
+       adc T3, XAccu3
+       adc T4, XAccu4 /* add k[i] */ /* finished with t1 */
+       /*now t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]) */ /*i did to much x86 asm, i always see 4 32bit regs*/
+               /* starting with MAJ(x,y,z) */
+       ldd Func1, Y+4*0+0
+       ldd Func2, Y+4*0+1
+       ldd Func3, Y+4*0+2
+       ldd Func4, Y+4*0+3 /* load x=a[0] */
+       ldd XAccu1, Y+4*1+0
+       ldd XAccu2, Y+4*1+1
+       ldd XAccu3, Y+4*1+2
+       ldd XAccu4, Y+4*1+3 /* load y=a[1] */
+       and XAccu1, Func1
+       and XAccu2, Func2
+       and XAccu3, Func3
+       and XAccu4, Func4       /* XAccu == (x & y) */
+       ldd Bck1, Y+4*2+0
+       ldd Bck2, Y+4*2+1
+       ldd Bck3, Y+4*2+2
+       ldd Bck4, Y+4*2+3 /* load z=a[2] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == (x & y) ^ (x & z) */
+       ldd Func1, Y+4*1+0
+       ldd Func2, Y+4*1+1
+       ldd Func3, Y+4*1+2
+       ldd Func4, Y+4*1+3 /* load y=a[1] */
+       and Func1, Bck1
+       and Func2, Bck2
+       and Func3, Bck3
+       and Func4, Bck4
+       eor XAccu1, Func1
+       eor XAccu2, Func2
+       eor XAccu3, Func3
+       eor XAccu4, Func4       /* XAccu == Maj(x,y,z) == (x & y) ^ (x & z) ^ (y & z) */
+       /* SIGMA0(a[0]) */
+       ldd Bck1, Y+4*0+0 /* we should combine this with above */
+       ldd Bck2, Y+4*0+1
+       ldd Bck3, Y+4*0+2
+       ldd Bck4, Y+4*0+3
+       movw Func1, Bck1
+       movw Func3, Bck3
+       ldi r20, 2
+       rcall bitrotr
+       movw Accu1, Func1
+       movw Accu3, Func3 /* Accu = shr(a[0], 2) */
+       movw Func1, Bck3 
+       movw Func3, Bck1 /* prerotate by 16 bits */
+       ldi r20, 3
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 13) */
+       mov Func1, Bck4
+       mov Func2, Bck1
+       mov Func3, Bck2
+       mov Func4, Bck3  /* prerotate by 24 bits */
+       ldi r20, 2
+       rcall bitrotl
+       eor Accu1, Func1
+       eor Accu2, Func2
+       eor Accu3, Func3
+       eor Accu4, Func4 /* Accu ^= shr(a[0], 22) */
+       add Accu1, XAccu1 /* add previous result (MAJ)*/
+       adc Accu2, XAccu2
+       adc Accu3, XAccu3
+       adc Accu4, XAccu4
+       /* now we are finished with the computing stuff (t1 in T, t2 in Accu)*/
+       /* 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]; */
+
+       ldi r21, 7*4
+       adiw r28, 7*4
+a_shift_loop:
+       ld  r25, -Y /* warning: this is PREdecrement */
+       std Y+4, r25
+       dec r21
+       brne a_shift_loop
+
+       ldd Bck1, Y+4*4+0
+       ldd Bck2, Y+4*4+1
+       ldd Bck3, Y+4*4+2
+       ldd Bck4, Y+4*4+3
+       add Bck1, T1
+       adc Bck2, T2
+       adc Bck3, T3
+       adc Bck4, T4
+       std Y+4*4+0, Bck1
+       std Y+4*4+1, Bck2
+       std Y+4*4+2, Bck3
+       std Y+4*4+3, Bck4
+       add Accu1, T1
+       adc Accu2, T2
+       adc Accu3, T3
+       adc Accu4, T4
+       std Y+4*0+0, Accu1
+       std Y+4*0+1, Accu2
+       std Y+4*0+2, Accu3
+       std Y+4*0+3, Accu4 /* a array updated */
+       
+       
+       dec LoopC
+       breq update_state
+       rjmp sha256_main_loop ;brne sha256_main_loop
+update_state:  
+       /* update state */
+       /* pointers to state should still exist on the stack ;-) */
+       pop r31
+       pop r30
+       ldi r21, 8
+update_state_loop:
+       ldd Accu1, Z+0
+       ldd Accu2, Z+1
+       ldd Accu3, Z+2
+       ldd Accu4, Z+3 
+       ld Func1, Y+
+       ld Func2, Y+
+       ld Func3, Y+
+       ld Func4, Y+
+       add Accu1, Func1
+       adc Accu2, Func2
+       adc Accu3, Func3
+       adc Accu4, Func4
+       st Z+, Accu1
+       st Z+, Accu2
+       st Z+, Accu3
+       st Z+, Accu4
+       dec r21
+       brne update_state_loop
+       /* now we just have to update the length */
+       adiw r30, 1 /* since we add 512, we can simply skip the LSB */ 
+       ldi r21, 2
+       ldi r22, 6
+       ld r20, Z
+       add r20, r21
+       st Z+, r20      
+       clr r21
+sha256_nextBlock_fix_length:   
+       brcc sha256_nextBlock_epilog
+       ld r20, Z
+       adc r20, r21
+       st Z+, r20
+       dec r22
+       brne sha256_nextBlock_fix_length
+       
+; EPILOG
+sha256_nextBlock_epilog:
+/* now we should clean up the stack */
+       
+       pop r21
+       pop r20
+       in r0, SREG
+       cli ; we want to be uninterrupted while updating SP
+       out SPL, r20
+       out SPH, r21
+       out SREG, r0
+       
+       clr r1
+       pop r29
+       pop r28
+       pop r17
+       pop r16
+       pop r15
+       pop r14
+       pop r13
+       pop r12
+       pop r11
+       pop r10
+       pop r9
+       pop r8
+       pop r7
+       pop r6
+       pop r5
+       pop r4 
+       ret
+
+sha256_kv: ; round-key-vector stored in ProgMem 
+.word  0x2f98, 0x428a, 0x4491, 0x7137, 0xfbcf, 0xb5c0, 0xdba5, 0xe9b5, 0xc25b, 0x3956, 0x11f1, 0x59f1, 0x82a4, 0x923f, 0x5ed5, 0xab1c
+.word  0xaa98, 0xd807, 0x5b01, 0x1283, 0x85be, 0x2431, 0x7dc3, 0x550c, 0x5d74, 0x72be, 0xb1fe, 0x80de, 0x06a7, 0x9bdc, 0xf174, 0xc19b
+.word  0x69c1, 0xe49b, 0x4786, 0xefbe, 0x9dc6, 0x0fc1, 0xa1cc, 0x240c, 0x2c6f, 0x2de9, 0x84aa, 0x4a74, 0xa9dc, 0x5cb0, 0x88da, 0x76f9
+.word  0x5152, 0x983e, 0xc66d, 0xa831, 0x27c8, 0xb003, 0x7fc7, 0xbf59, 0x0bf3, 0xc6e0, 0x9147, 0xd5a7, 0x6351, 0x06ca, 0x2967, 0x1429
+.word  0x0a85, 0x27b7, 0x2138, 0x2e1b, 0x6dfc, 0x4d2c, 0x0d13, 0x5338, 0x7354, 0x650a, 0x0abb, 0x766a, 0xc92e, 0x81c2, 0x2c85, 0x9272
+.word  0xe8a1, 0xa2bf, 0x664b, 0xa81a, 0x8b70, 0xc24b, 0x51a3, 0xc76c, 0xe819, 0xd192, 0x0624, 0xd699, 0x3585, 0xf40e, 0xa070, 0x106a
+.word  0xc116, 0x19a4, 0x6c08, 0x1e37, 0x774c, 0x2748, 0xbcb5, 0x34b0, 0x0cb3, 0x391c, 0xaa4a, 0x4ed8, 0xca4f, 0x5b9c, 0x6ff3, 0x682e
+.word  0x82ee, 0x748f, 0x636f, 0x78a5, 0x7814, 0x84c8, 0x0208, 0x8cc7, 0xfffa, 0x90be, 0x6ceb, 0xa450, 0xa3f7, 0xbef9, 0x78f2, 0xc671
+
+       
+;###########################################################   
+
+.global sha256_init 
+;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);
+;}
+; param1: (r23,r24) 16-bit pointer to sha256_ctx_t struct in ram
+; modifys: Z(r30,r31), Func1, r22
+sha256_init:
+       movw r26, r24 ; (24,25) --> (26,27) load X with param1
+       ldi r30, lo8((sha256_init_vector))
+       ldi r31, hi8((sha256_init_vector))
+       ldi r22, 32+8
+sha256_init_vloop:     
+       lpm r23, Z+ 
+       st X+, r23
+       dec r22
+       brne sha256_init_vloop
+       ret
+       
+sha256_init_vector:
+.word 0xE667, 0x6A09
+.word 0xAE85, 0xBB67 
+.word 0xF372, 0x3C6E 
+.word 0xF53A, 0xA54F 
+.word 0x527F, 0x510E 
+.word 0x688C, 0x9B05 
+.word 0xD9AB, 0x1F83 
+.word 0xCD19, 0x5BE0
+.word 0x0000, 0x0000
+.word 0x0000, 0x0000
+
+;###########################################################   
+
+.global rotl32
+; === ROTL32 ===
+; function that rotates a 32 bit word to the left
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,r22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotl32:
+       cpi r20, 8
+       brlo bitrotl
+       mov r21, r25
+       mov r25, r24
+       mov r24, r23
+       mov r23, r22
+       mov r22, r21
+       subi r20, 8
+       rjmp rotl32
+bitrotl:
+       clr r21
+       clc
+bitrotl_loop:  
+       tst r20
+       breq fixrotl
+       rol r22
+       rol r23
+       rol r24
+       rol r25
+       rol r21
+       dec r20
+       rjmp bitrotl_loop
+fixrotl:
+       or r22, r21
+       ret
+       
+
+;###########################################################   
+
+.global rotr32
+; === ROTR32 ===
+; function that rotates a 32 bit word to the right
+;  param1: the 32-bit word to rotate
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  param2: an 8-bit value telling how often to rotate
+;      given in r20
+; modifys: r21, r22
+rotr32:
+       cpi r20, 8
+       brlo bitrotr
+       mov r21, r22
+       mov r22, r23
+       mov r23, r24
+       mov r24, r25
+       mov r25, r21
+       subi r20, 8
+       rjmp rotr32
+bitrotr:
+       clr r21
+       clc
+bitrotr_loop:  
+       tst r20
+       breq fixrotr
+       ror r25
+       ror r24
+       ror r23
+       ror r22
+       ror r21
+       dec r20
+       rjmp bitrotr_loop
+fixrotr:
+       or r25, r21
+       ret
+       
+       
+;###########################################################   
+       
+.global change_endian32
+; === change_endian32 ===
+; function that changes the endianess of a 32-bit word
+;  param1: the 32-bit word
+;      given in r25,r24,r23,22 (r25 is most significant)
+;  modifys: r21, r22
+change_endian32:
+       movw r20,  r22 ; (r22,r23) --> (r20,r21)
+       mov r22, r25
+       mov r23, r24
+       mov r24, r21
+       mov r25, r20 
+       ret
+
diff --git a/shacal2/sha256.h b/shacal2/sha256.h
new file mode 100644 (file)
index 0000000..24960a3
--- /dev/null
@@ -0,0 +1,122 @@
+/* sha256.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       sha256.h
+ * \author  Daniel Otte 
+ * \date    2006-05-16
+ * \license    GPLv3 or later
+ * 
+ */
+
+#ifndef SHA256_H_
+#define SHA256_H_
+
+#define __LITTLE_ENDIAN__
+
+
+#include <stdint.h>
+
+/** \def SHA256_HASH_BITS
+ * defines the size of a SHA-256 hash value in bits
+ */
+
+/** \def SHA256_HASH_BYTES
+ * defines the size of a SHA-256 hash value in bytes
+ */
+
+/** \def SHA256_BLOCK_BITS
+ * defines the size of a SHA-256 input block in bits
+ */
+
+/** \def SHA256_BLOCK_BYTES
+ * defines the size of a SHA-256 input block in bytes
+ */
+
+#define SHA256_HASH_BITS  256
+#define SHA256_HASH_BYTES (SHA256_HASH_BITS/8)
+#define SHA256_BLOCK_BITS 512
+#define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8)
+
+/** \typedef sha256_ctx_t
+ * \brief SHA-256 context type
+ * 
+ * A variable of this type may hold the state of a SHA-256 hashing process
+ */
+typedef struct {
+       uint32_t h[8];
+       uint64_t length;
+} sha256_ctx_t;
+
+/** \typedef sha256_hash_t
+ * \brief SHA-256 hash value type
+ * 
+ * A variable of this type may hold the hash value produced by the
+ * sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state) function.
+ */
+typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES];
+
+/** \fn void sha256_init(sha256_ctx_t *state)
+ * \brief initialise a SHA-256 context
+ * 
+ * This function sets a ::sha256_ctx_t to the initial values for hashing.
+ * \param state pointer to the SHA-256 hashing context
+ */
+void sha256_init(sha256_ctx_t *state);
+
+/** \fn void sha256_nextBlock (sha256_ctx_t* state, const void* block)
+ * \brief update the context with a given block
+ * 
+ * This function updates the SHA-256 hash context by processing the given block
+ * of fixed length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ */
+void sha256_nextBlock (sha256_ctx_t* state, const void* block);
+
+/** \fn void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b)
+ * \brief finalize the context with the given block 
+ * 
+ * This function finalizes the SHA-256 hash context by processing the given block
+ * of variable length.
+ * \param state pointer to the SHA-256 hash context
+ * \param block pointer to the block of fixed length (512 bit = 64 byte)
+ * \param length_b the length of the block in bits
+ */
+void sha256_lastBlock(sha256_ctx_t* state, const void* block, uint16_t length_b);
+
+/** \fn void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state)
+ * \brief convert the hash state into the hash value
+ * This function reads the context and writes the hash value to the destination
+ * \param dest pointer to the location where the hash value should be written
+ * \param state pointer to the SHA-256 hash context
+ */
+void sha256_ctx2hash(sha256_hash_t* dest, const sha256_ctx_t* state);
+
+/** \fn void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b)
+ * \brief simple SHA-256 hashing function for direct hashing
+ * 
+ * This function automaticaly hashes a given message of arbitary length with
+ * the SHA-256 hashing algorithm.
+ * \param dest pointer to the location where the hash value is going to be written to
+ * \param msg pointer to the message thats going to be hashed
+ * \param length_b length of the message in bits
+ */
+void sha256(sha256_hash_t* dest, const void* msg, uint32_t length_b);
+
+#endif /*SHA256_H_*/
diff --git a/shacal2/shacal2_enc.c b/shacal2/shacal2_enc.c
new file mode 100644 (file)
index 0000000..b5380e5
--- /dev/null
@@ -0,0 +1,57 @@
+/* shacal2_enc.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       shacal2_enc.c
+ * \author     Daniel Otte
+ * \date       2008-05-07
+ * \par License:
+ * GPL
+ * \brief SHACAL2 encryption only implementation.
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sha256.h"
+#include "shacal2_enc.h"
+
+
+void shacal2_enc(void* buffer, void* key, uint16_t keysize_b){
+       uint8_t i;
+       sha256_ctx_t ctx, t_ctx;
+       memcpy(ctx.h, buffer, SHACAL2_BLOCKSIZE_B);
+       
+       uint8_t keybuffer[SHACAL2_KEYSIZE_B];
+       memset(keybuffer, 0, SHACAL2_KEYSIZE_B);
+       if(keysize_b>SHACAL2_KEYSIZE)
+               keysize_b=SHACAL2_KEYSIZE;
+       memcpy(keybuffer, key, (keysize_b+7)/8);
+       
+       memcpy(t_ctx.h, buffer, SHACAL2_BLOCKSIZE_B);
+       sha256_ctx2hash((sha256_hash_t*)(&(ctx.h[0])), &t_ctx);
+       memcpy(t_ctx.h, ctx.h, SHACAL2_BLOCKSIZE_B);
+       sha256_nextBlock(&ctx, keybuffer);
+       for(i=0; i<SHACAL2_BLOCKSIZE/32; ++i){
+               ctx.h[i] -= t_ctx.h[i];
+       }
+       sha256_ctx2hash(buffer, &ctx);
+}
+
+
+
diff --git a/shacal2/shacal2_enc.h b/shacal2/shacal2_enc.h
new file mode 100644 (file)
index 0000000..ffa277c
--- /dev/null
@@ -0,0 +1,33 @@
+/* shacal2_enc.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SHACAL2_ENC_H_
+#define SHACAL2_ENC_H_
+
+#include <stdint.h>
+#include "sha256.h"
+
+#define SHACAL2_BLOCKSIZE  SHA256_HASH_BITS
+#define SHACAL2_BLOCKSIZE_B ((SHACAL2_BLOCKSIZE+7)/8)
+#define SHACAL2_KEYSIZE SHA256_BLOCK_BITS
+#define SHACAL2_KEYSIZE_B ((SHACAL2_KEYSIZE+7)/8)
+
+void shacal2_enc(void* buffer, void* key, uint16_t keysize_b);
+
+
+#endif /*SHACAL2_ENC_H_*/
diff --git a/shacal2_enc.c b/shacal2_enc.c
deleted file mode 100644 (file)
index b5380e5..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* shacal2_enc.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file       shacal2_enc.c
- * \author     Daniel Otte
- * \date       2008-05-07
- * \par License:
- * GPL
- * \brief SHACAL2 encryption only implementation.
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "sha256.h"
-#include "shacal2_enc.h"
-
-
-void shacal2_enc(void* buffer, void* key, uint16_t keysize_b){
-       uint8_t i;
-       sha256_ctx_t ctx, t_ctx;
-       memcpy(ctx.h, buffer, SHACAL2_BLOCKSIZE_B);
-       
-       uint8_t keybuffer[SHACAL2_KEYSIZE_B];
-       memset(keybuffer, 0, SHACAL2_KEYSIZE_B);
-       if(keysize_b>SHACAL2_KEYSIZE)
-               keysize_b=SHACAL2_KEYSIZE;
-       memcpy(keybuffer, key, (keysize_b+7)/8);
-       
-       memcpy(t_ctx.h, buffer, SHACAL2_BLOCKSIZE_B);
-       sha256_ctx2hash((sha256_hash_t*)(&(ctx.h[0])), &t_ctx);
-       memcpy(t_ctx.h, ctx.h, SHACAL2_BLOCKSIZE_B);
-       sha256_nextBlock(&ctx, keybuffer);
-       for(i=0; i<SHACAL2_BLOCKSIZE/32; ++i){
-               ctx.h[i] -= t_ctx.h[i];
-       }
-       sha256_ctx2hash(buffer, &ctx);
-}
-
-
-
diff --git a/shacal2_enc.h b/shacal2_enc.h
deleted file mode 100644 (file)
index ffa277c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* shacal2_enc.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef SHACAL2_ENC_H_
-#define SHACAL2_ENC_H_
-
-#include <stdint.h>
-#include "sha256.h"
-
-#define SHACAL2_BLOCKSIZE  SHA256_HASH_BITS
-#define SHACAL2_BLOCKSIZE_B ((SHACAL2_BLOCKSIZE+7)/8)
-#define SHACAL2_KEYSIZE SHA256_BLOCK_BITS
-#define SHACAL2_KEYSIZE_B ((SHACAL2_KEYSIZE+7)/8)
-
-void shacal2_enc(void* buffer, void* key, uint16_t keysize_b);
-
-
-#endif /*SHACAL2_ENC_H_*/
diff --git a/skipjack.c b/skipjack.c
deleted file mode 100644 (file)
index 04eb437..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* skipjack.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * 
- * 
- * 
- * 
- * 
- */
-
-
-#include <stdint.h>
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-
-#define SKIPJACK_CNT_BIG
-
-#ifdef SKIPJACK_CNT_BIG
-  #define SKIPJACK_CNT_SHIFT <<8
-#else
-  #define SKIPJACK_CNT_SHIFT
-#endif
-
-/*****************************************************************************/
-
-uint8_t skipjack_ftable[] PROGMEM ={ 
-       0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 
-       0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, 
-       0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 
-       0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, 
-       0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 
-       0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, 
-       0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 
-       0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, 
-       0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 
-       0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, 
-       0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 
-       0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, 
-       0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 
-       0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, 
-       0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 
-       0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, 
-       0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 
-       0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, 
-       0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 
-       0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, 
-       0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 
-       0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, 
-       0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 
-       0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, 
-       0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 
-       0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, 
-       0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 
-       0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, 
-       0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 
-       0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, 
-       0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 
-       0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46
-};
-
-/*****************************************************************************/
-
-uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
-       #define G1 (((uint8_t*)&g)[0])
-       #define G2 (((uint8_t*)&g)[1])
-       /* this could also be rolled up */
-       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
-       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
-       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
-       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
-       return g;       
-}
-
-/*****************************************************************************/
-
-uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
-//     #define G1 (((uint8_t)&g)[1])
-//     #define G2 (((uint8_t)&g)[0])
-       /* this could also be rolled up */
-       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
-       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
-       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
-       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
-       return g;       
-}
-
-/*****************************************************************************/
-
-void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
-       uint16_t t;
-
-       t = w[3];
-       w[3] = w[2];
-       w[2] = w[1];
-       w[1] = skipjack_g(w[0],k-1,key);
-       w[0] = t ^ w[1] ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
-}
-
-/*****************************************************************************/
-
-void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
-       uint16_t t;
-       t = w[0] ^ w[1];
-       w[0] = skipjack_g_inv(w[1],k-1,key);
-       w[1] = w[2];
-       w[2] = w[3];
-       w[3] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
-}
-
-/*****************************************************************************/
-
-void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
-       uint16_t t;
-       t = w[0];
-       w[0] = w[3];
-       w[3] = w[2];
-       w[2] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT) ^ w[1];
-       w[1] = skipjack_g(t,k-1,key);
-}
-
-/*****************************************************************************/
-
-void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
-       uint16_t t;
-       t = w[2];
-       w[2] = w[3];
-       w[3] = w[0];
-       w[0] = skipjack_g_inv(w[1],k-1,key);
-       w[1] = w[0] ^ t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
-}
-
-/*****************************************************************************/
-/**
- * block is 64 bits (=8 bytes) in size, key is 80 bits (=10 bytes) in size.
- * 
- */
-void skipjack_enc(void* block, void* key){
-       uint8_t k;
-       for(k=0; k<32; ++k){
-               if(k & 0x08){
-                       skipjack_b((uint16_t*)block, k+1, key);
-               } else {
-                       skipjack_a((uint16_t*)block, k+1, key);
-               }
-       }
-}
-
-/*****************************************************************************/
-/**
- * block is 64 bits (=8 bytes) in size, key is 80 bits (=10 bytes) in size.
- * 
- */
-void skipjack_dec(void* block, void* key){
-       int8_t k;
-       for(k=31; k>=0; --k){
-               if(k & 0x08){
-                       skipjack_b_inv((uint16_t*)block, k+1, key);
-               } else {
-                       skipjack_a_inv((uint16_t*)block, k+1, key);
-               }
-       }
-}
-
-
-
-
-
diff --git a/skipjack.h b/skipjack.h
deleted file mode 100644 (file)
index 00f033d..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* skipjack.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef SKIPJACK_H_
-#define SKIPJACK_H_
-
-/** 
- * \file      skipjack.h
- * \author    Daniel Otte
- * \date      2006-11-01
- * \license   GPLv3 or later
- * \brief     Implementation of the serpent sbox function.
- * 
- */
-
-
-#include <stdint.h>
-
-/** \fn void skipjack_enc(void* block, void* key)
- * \brief skipjack encryption function
- * 
- * This function encrypts a block of plaintext with the Skipjac encryption
- * algorithm. The block is 64 bit (8 byte) long, the key is 80 bit (10 byte)
- * long.
- * \param block pointer to the 64 bit (8 byte) block to encrypt
- * \param key   pointer to the 80 bit (10 byte) key 
- */
-void skipjack_enc(void* block, void* key);
-
-/** \fn void skipjack_dec(void* block, void* key)
- * \brief skipjack decryption function
- * 
- * This function decrypts a block of ciphertext encrypted with the Skipjac
- * encryption algorithm. 
- * The block is 64 bit (8 byte) long, the key is 80 bit (10 byte) long.
- * \param block pointer to the 64 bit (8 byte) block to decrypt
- * \param key   pointer to the 80 bit (10 byte) key 
- */
-void skipjack_dec(void* block, void* key);
-
-#endif /*SKIPJACK_H_*/
diff --git a/skipjack/skipjack.c b/skipjack/skipjack.c
new file mode 100644 (file)
index 0000000..04eb437
--- /dev/null
@@ -0,0 +1,184 @@
+/* skipjack.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * 
+ * 
+ * 
+ * 
+ * 
+ */
+
+
+#include <stdint.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+#define SKIPJACK_CNT_BIG
+
+#ifdef SKIPJACK_CNT_BIG
+  #define SKIPJACK_CNT_SHIFT <<8
+#else
+  #define SKIPJACK_CNT_SHIFT
+#endif
+
+/*****************************************************************************/
+
+uint8_t skipjack_ftable[] PROGMEM ={ 
+       0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, 
+       0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, 
+       0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, 
+       0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, 
+       0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, 
+       0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, 
+       0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, 
+       0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, 
+       0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, 
+       0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, 
+       0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, 
+       0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, 
+       0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, 
+       0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, 
+       0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, 
+       0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, 
+       0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, 
+       0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, 
+       0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, 
+       0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, 
+       0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, 
+       0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, 
+       0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, 
+       0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, 
+       0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, 
+       0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, 
+       0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, 
+       0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, 
+       0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, 
+       0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, 
+       0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, 
+       0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46
+};
+
+/*****************************************************************************/
+
+uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
+       #define G1 (((uint8_t*)&g)[0])
+       #define G2 (((uint8_t*)&g)[1])
+       /* this could also be rolled up */
+       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
+       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
+       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
+       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
+       return g;       
+}
+
+/*****************************************************************************/
+
+uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
+//     #define G1 (((uint8_t)&g)[1])
+//     #define G2 (((uint8_t)&g)[0])
+       /* this could also be rolled up */
+       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
+       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
+       G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
+       G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
+       return g;       
+}
+
+/*****************************************************************************/
+
+void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
+       uint16_t t;
+
+       t = w[3];
+       w[3] = w[2];
+       w[2] = w[1];
+       w[1] = skipjack_g(w[0],k-1,key);
+       w[0] = t ^ w[1] ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+}
+
+/*****************************************************************************/
+
+void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
+       uint16_t t;
+       t = w[0] ^ w[1];
+       w[0] = skipjack_g_inv(w[1],k-1,key);
+       w[1] = w[2];
+       w[2] = w[3];
+       w[3] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+}
+
+/*****************************************************************************/
+
+void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
+       uint16_t t;
+       t = w[0];
+       w[0] = w[3];
+       w[3] = w[2];
+       w[2] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT) ^ w[1];
+       w[1] = skipjack_g(t,k-1,key);
+}
+
+/*****************************************************************************/
+
+void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
+       uint16_t t;
+       t = w[2];
+       w[2] = w[3];
+       w[3] = w[0];
+       w[0] = skipjack_g_inv(w[1],k-1,key);
+       w[1] = w[0] ^ t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+}
+
+/*****************************************************************************/
+/**
+ * block is 64 bits (=8 bytes) in size, key is 80 bits (=10 bytes) in size.
+ * 
+ */
+void skipjack_enc(void* block, void* key){
+       uint8_t k;
+       for(k=0; k<32; ++k){
+               if(k & 0x08){
+                       skipjack_b((uint16_t*)block, k+1, key);
+               } else {
+                       skipjack_a((uint16_t*)block, k+1, key);
+               }
+       }
+}
+
+/*****************************************************************************/
+/**
+ * block is 64 bits (=8 bytes) in size, key is 80 bits (=10 bytes) in size.
+ * 
+ */
+void skipjack_dec(void* block, void* key){
+       int8_t k;
+       for(k=31; k>=0; --k){
+               if(k & 0x08){
+                       skipjack_b_inv((uint16_t*)block, k+1, key);
+               } else {
+                       skipjack_a_inv((uint16_t*)block, k+1, key);
+               }
+       }
+}
+
+
+
+
+
diff --git a/skipjack/skipjack.h b/skipjack/skipjack.h
new file mode 100644 (file)
index 0000000..00f033d
--- /dev/null
@@ -0,0 +1,56 @@
+/* skipjack.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SKIPJACK_H_
+#define SKIPJACK_H_
+
+/** 
+ * \file      skipjack.h
+ * \author    Daniel Otte
+ * \date      2006-11-01
+ * \license   GPLv3 or later
+ * \brief     Implementation of the serpent sbox function.
+ * 
+ */
+
+
+#include <stdint.h>
+
+/** \fn void skipjack_enc(void* block, void* key)
+ * \brief skipjack encryption function
+ * 
+ * This function encrypts a block of plaintext with the Skipjac encryption
+ * algorithm. The block is 64 bit (8 byte) long, the key is 80 bit (10 byte)
+ * long.
+ * \param block pointer to the 64 bit (8 byte) block to encrypt
+ * \param key   pointer to the 80 bit (10 byte) key 
+ */
+void skipjack_enc(void* block, void* key);
+
+/** \fn void skipjack_dec(void* block, void* key)
+ * \brief skipjack decryption function
+ * 
+ * This function decrypts a block of ciphertext encrypted with the Skipjac
+ * encryption algorithm. 
+ * The block is 64 bit (8 byte) long, the key is 80 bit (10 byte) long.
+ * \param block pointer to the 64 bit (8 byte) block to decrypt
+ * \param key   pointer to the 80 bit (10 byte) key 
+ */
+void skipjack_dec(void* block, void* key);
+
+#endif /*SKIPJACK_H_*/
index dfbcead79a50e047614332c00c7c560ad35f11e1..f61e1191ad28107d0d92a8acfc8c0770bd9b5c93 100644 (file)
 
 #include "md5.h"
 #include "hmac-md5.h"
+/*
 #include "base64_enc.h"
 #include "base64_dec.h"
-
+*/
 #include "nessie_mac_test.h"
 
 #include <stdint.h>
@@ -109,6 +110,7 @@ void strhexdump(char* dest, void* src, uint16_t length){
        }
 }
 
+/*
 void cram_md5_interactive(void){
        char key[101];
        char msg_b64[101];
@@ -137,9 +139,9 @@ void cram_md5_interactive(void){
        cli_putstr_P(PSTR("\r\nresponse: "));
        cli_hexdump(hmac, HMAC_MD5_BYTES);
        cli_putstr_P(PSTR("\r\nresponse (b64): "));
-       cli_putstr(msg_b64);
-       
+       cli_putstr(msg_b64);    
 }
+*/
 
 
 void md5_interactive(void){
@@ -164,7 +166,7 @@ const char test_str[]        PROGMEM = "test";
 /* const char performance_str[] PROGMEM = "performance"; */
 const char echo_str[]        PROGMEM = "echo";
 const char hmd5i_str[]       PROGMEM = "hmac-md5";
-const char crammd5i_str[]    PROGMEM = "cram-md5";
+/* const char crammd5i_str[]    PROGMEM = "cram-md5"; */
 const char md5i_str[]        PROGMEM = "md5";
 
 
@@ -172,7 +174,7 @@ cmdlist_entry_t cmdlist[] PROGMEM = {
        { nessie_str,      NULL, testrun_nessie_hmacmd5},
        { test_str,        NULL, testrun_test_hmacmd5},
        { hmd5i_str,       NULL, hmacmd5_interactive},
-       { crammd5i_str,    NULL, cram_md5_interactive},
+/*     { crammd5i_str,    NULL, cram_md5_interactive},        */
        { md5i_str,        NULL, md5_interactive},
 /*     { performance_str, NULL, testrun_performance_hmacmd5}, */
        { echo_str,    (void*)1, (void_fpt)echo_ctrl},
diff --git a/trivium.c b/trivium.c
deleted file mode 100644 (file)
index 3ac69c3..0000000
--- a/trivium.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* trivium.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * 
- * author: Daniel Otte
- * email:  daniel.otte@rub.de
- * license: GPLv3
- * 
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "trivium.h"
-
-#define S(i) ((((*ctx)[(i)/8])>>((i)%8))&1)
-uint8_t trivium_enc(trivium_ctx_t* ctx){
-       uint8_t t1,t2,t3,z;
-       
-       t1 = S(65)  ^ S(92);
-       t2 = S(161) ^ S(176);
-       t3 = S(242) ^ S(287);
-       z  = t1^t2^t3;
-       t1 ^= (S(90)  & S(91))  ^ S(170);
-       t2 ^= (S(174) & S(175)) ^ S(263);
-       t3 ^= (S(285) & S(286)) ^ S(68);
-       
-       /* shift whole state and insert ts later */
-       uint8_t i,c1=0,c2;
-       for(i=0; i<36; ++i){
-               c2=(((*ctx)[i])>>7);
-               (*ctx)[i] = (((*ctx)[i])<<1)|c1;
-               c1=c2;
-       }
-       /* insert ts */
-       (*ctx)[0] = (((*ctx)[0])&0xFE)| t3; /* s0*/
-       (*ctx)[93/8] = (((*ctx)[93/8])& (~(1<<(93%8)))) | (t1<<(93%8)); /* s93 */
-       (*ctx)[177/8] = (((*ctx)[177/8])& (~(1<<(177%8)))) | (t2<<(177%8));/* s177 */
-       
-       return z;
-}
-
-#define KEYSIZE_B ((keysize_b+7)/8)
-#define IVSIZE_B  ((ivsize_b +7)/8)
-
-void trivium_init(const void* key, uint8_t keysize_b, 
-                  const void* iv,  uint8_t ivsize_b,
-                  trivium_ctx_t* ctx){
-       uint16_t i;
-       uint8_t c1=0,c2;
-
-       memset((*ctx)+KEYSIZE_B, 0, 35-KEYSIZE_B);
-       memcpy((*ctx), key, KEYSIZE_B);
-       memcpy((*ctx)+12, iv, IVSIZE_B); /* iv0 is at s96, must shift to s93 */
-       
-       for(i=12+IVSIZE_B; i>10; --i){
-               c2=(((*ctx)[i])<<5);
-               (*ctx)[i] = (((*ctx)[i])>>3)|c1;
-               c1=c2;
-       }
-       (*ctx)[35]=0xE0;
-       
-       for(i=0; i<4*288; ++i){
-               trivium_enc(ctx);
-       }
-}
-
-
diff --git a/trivium.h b/trivium.h
deleted file mode 100644 (file)
index 14a005f..0000000
--- a/trivium.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* trivium.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef TRIVIUM_H_
-#define TRIVIUM_H_
-
-typedef uint8_t trivium_ctx_t[36]; /* 288bit */
-
-uint8_t trivium_enc(trivium_ctx_t* ctx);
-void trivium_init(const void* key, uint8_t keysize_b, 
-                  const void* iv,  uint8_t ivsize_b,
-                  trivium_ctx_t* ctx);
-
-#endif /*TRIVIUM_H_*/
diff --git a/trivium/trivium.c b/trivium/trivium.c
new file mode 100644 (file)
index 0000000..3ac69c3
--- /dev/null
@@ -0,0 +1,84 @@
+/* trivium.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * 
+ * author: Daniel Otte
+ * email:  daniel.otte@rub.de
+ * license: GPLv3
+ * 
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "trivium.h"
+
+#define S(i) ((((*ctx)[(i)/8])>>((i)%8))&1)
+uint8_t trivium_enc(trivium_ctx_t* ctx){
+       uint8_t t1,t2,t3,z;
+       
+       t1 = S(65)  ^ S(92);
+       t2 = S(161) ^ S(176);
+       t3 = S(242) ^ S(287);
+       z  = t1^t2^t3;
+       t1 ^= (S(90)  & S(91))  ^ S(170);
+       t2 ^= (S(174) & S(175)) ^ S(263);
+       t3 ^= (S(285) & S(286)) ^ S(68);
+       
+       /* shift whole state and insert ts later */
+       uint8_t i,c1=0,c2;
+       for(i=0; i<36; ++i){
+               c2=(((*ctx)[i])>>7);
+               (*ctx)[i] = (((*ctx)[i])<<1)|c1;
+               c1=c2;
+       }
+       /* insert ts */
+       (*ctx)[0] = (((*ctx)[0])&0xFE)| t3; /* s0*/
+       (*ctx)[93/8] = (((*ctx)[93/8])& (~(1<<(93%8)))) | (t1<<(93%8)); /* s93 */
+       (*ctx)[177/8] = (((*ctx)[177/8])& (~(1<<(177%8)))) | (t2<<(177%8));/* s177 */
+       
+       return z;
+}
+
+#define KEYSIZE_B ((keysize_b+7)/8)
+#define IVSIZE_B  ((ivsize_b +7)/8)
+
+void trivium_init(const void* key, uint8_t keysize_b, 
+                  const void* iv,  uint8_t ivsize_b,
+                  trivium_ctx_t* ctx){
+       uint16_t i;
+       uint8_t c1=0,c2;
+
+       memset((*ctx)+KEYSIZE_B, 0, 35-KEYSIZE_B);
+       memcpy((*ctx), key, KEYSIZE_B);
+       memcpy((*ctx)+12, iv, IVSIZE_B); /* iv0 is at s96, must shift to s93 */
+       
+       for(i=12+IVSIZE_B; i>10; --i){
+               c2=(((*ctx)[i])<<5);
+               (*ctx)[i] = (((*ctx)[i])>>3)|c1;
+               c1=c2;
+       }
+       (*ctx)[35]=0xE0;
+       
+       for(i=0; i<4*288; ++i){
+               trivium_enc(ctx);
+       }
+}
+
+
diff --git a/trivium/trivium.h b/trivium/trivium.h
new file mode 100644 (file)
index 0000000..14a005f
--- /dev/null
@@ -0,0 +1,29 @@
+/* trivium.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef TRIVIUM_H_
+#define TRIVIUM_H_
+
+typedef uint8_t trivium_ctx_t[36]; /* 288bit */
+
+uint8_t trivium_enc(trivium_ctx_t* ctx);
+void trivium_init(const void* key, uint8_t keysize_b, 
+                  const void* iv,  uint8_t ivsize_b,
+                  trivium_ctx_t* ctx);
+
+#endif /*TRIVIUM_H_*/
diff --git a/xtea-asm.S b/xtea-asm.S
deleted file mode 100644 (file)
index 826f123..0000000
+++ /dev/null
@@ -1,585 +0,0 @@
-/* xtea-asm.S */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/* xtea-asm.S 
- * Author:      Daniel Otte
- * Date:        2006-06-06
- * License:     GPLv3 or later
- *  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 /* r0 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
deleted file mode 100644 (file)
index 4605cb0..0000000
--- a/xtea.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* xtea.c */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** 
- * \file       xtea.c
- * \brief      XTEA implemantation 
- *   copy'n'pasted from http://en.wikipedia.org/wiki/XTEA
- *   and slightly modified
- */
-#include <stdint.h> 
-
-void xtea_enc(void* dest, const void* v, const void* k) {
-    uint8_t i;
-    uint32_t v0=((uint32_t*)v)[0], v1=((uint32_t*)v)[1];
-    uint32_t sum=0, delta=0x9E3779B9;
-    for(i=0; i<32; i++) {
-        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((uint32_t*)k)[sum & 3]);
-        sum += delta;
-        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((uint32_t*)k)[sum>>11 & 3]);
-    }
-    ((uint32_t*)dest)[0]=v0; ((uint32_t*)dest)[1]=v1;
-}
-
-void xtea_dec(void* dest, const void* v, const void* k) {
-    uint8_t i;
-    uint32_t v0=((uint32_t*)v)[0], v1=((uint32_t*)v)[1];
-    uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
-    for(i=0; i<32; i++) {
-        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((uint32_t*)k)[sum>>11 & 3]);
-        sum -= delta;
-        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((uint32_t*)k)[sum & 3]);
-    }
-    ((uint32_t*)dest)[0]=v0; ((uint32_t*)dest)[1]=v1;
-}
-
-
diff --git a/xtea.h b/xtea.h
deleted file mode 100644 (file)
index b753bf7..0000000
--- a/xtea.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* xtea.h */
-/*
-    This file is part of the AVR-Crypto-Lib.
-    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * 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
- * 
- */
-#define XTEA_BLOCKSIZE 64
-#define XTEA_BLOCKSIZEB ((XTEA_BLOCKSIZE+7)/8)
-#define XTEA_KEYSIZE 128
-#define XTEA_KEYSIZEB ((XTEA_KEYSIZE+7)/8)
-
-
-/*
- * 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(void* dest, const void* v, const void* k);
-void xtea_dec(void* dest, const void* v, const void* k);
-
-
-#endif /*XTEA_H_*/
diff --git a/xtea/xtea-asm.S b/xtea/xtea-asm.S
new file mode 100644 (file)
index 0000000..826f123
--- /dev/null
@@ -0,0 +1,585 @@
+/* xtea-asm.S */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/* xtea-asm.S 
+ * Author:      Daniel Otte
+ * Date:        2006-06-06
+ * License:     GPLv3 or later
+ *  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 /* r0 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/xtea.c b/xtea/xtea.c
new file mode 100644 (file)
index 0000000..4605cb0
--- /dev/null
@@ -0,0 +1,53 @@
+/* xtea.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** 
+ * \file       xtea.c
+ * \brief      XTEA implemantation 
+ *   copy'n'pasted from http://en.wikipedia.org/wiki/XTEA
+ *   and slightly modified
+ */
+#include <stdint.h> 
+
+void xtea_enc(void* dest, const void* v, const void* k) {
+    uint8_t i;
+    uint32_t v0=((uint32_t*)v)[0], v1=((uint32_t*)v)[1];
+    uint32_t sum=0, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((uint32_t*)k)[sum & 3]);
+        sum += delta;
+        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((uint32_t*)k)[sum>>11 & 3]);
+    }
+    ((uint32_t*)dest)[0]=v0; ((uint32_t*)dest)[1]=v1;
+}
+
+void xtea_dec(void* dest, const void* v, const void* k) {
+    uint8_t i;
+    uint32_t v0=((uint32_t*)v)[0], v1=((uint32_t*)v)[1];
+    uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
+    for(i=0; i<32; i++) {
+        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((uint32_t*)k)[sum>>11 & 3]);
+        sum -= delta;
+        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((uint32_t*)k)[sum & 3]);
+    }
+    ((uint32_t*)dest)[0]=v0; ((uint32_t*)dest)[1]=v1;
+}
+
+
diff --git a/xtea/xtea.h b/xtea/xtea.h
new file mode 100644 (file)
index 0000000..b753bf7
--- /dev/null
@@ -0,0 +1,49 @@
+/* xtea.h */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * 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
+ * 
+ */
+#define XTEA_BLOCKSIZE 64
+#define XTEA_BLOCKSIZEB ((XTEA_BLOCKSIZE+7)/8)
+#define XTEA_KEYSIZE 128
+#define XTEA_KEYSIZEB ((XTEA_KEYSIZE+7)/8)
+
+
+/*
+ * 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(void* dest, const void* v, const void* k);
+void xtea_dec(void* dest, const void* v, const void* k);
+
+
+#endif /*XTEA_H_*/