diff --git a/avr-asm-macros.S b/avr-asm-macros.S index 4991cee..698e23e 100644 --- a/avr-asm-macros.S +++ b/avr-asm-macros.S @@ -107,6 +107,18 @@ out _SFR_IO_ADDR(SPL), \reg1 .endm +.macro stack_free_large2 size:req, reg1=r30, reg2=r31 + in r0, _SFR_IO_ADDR(SREG) + in \reg1, _SFR_IO_ADDR(SPL) + in \reg2, _SFR_IO_ADDR(SPH) + adiw \reg1, 63 + adiw \reg1, 63 + adiw \reg1, (\size-63*2) + cli + out _SFR_IO_ADDR(SPH), \reg2 + out _SFR_IO_ADDR(SREG), r0 + out _SFR_IO_ADDR(SPL), \reg1 +.endm /******************************************************************************* diff --git a/gf256mul.S b/gf256mul.S index 5a47f4e..6e5c3b8 100644 --- a/gf256mul.S +++ b/gf256mul.S @@ -31,17 +31,17 @@ /* * param a: r24 - * param b; r22 + * param b: r22 * param reducer: r20 */ -A = 21 +A = 23 B = 22 P = 24 .global gf256mul #ifdef OPTIMIZE_SMALL_A gf256mul: - mov r21, r24 + mov A, r24 clr r24 1: lsr A diff --git a/mkfiles/twister224.mk b/mkfiles/twister224.mk index b3a4e3d..18addb5 100644 --- a/mkfiles/twister224.mk +++ b/mkfiles/twister224.mk @@ -4,7 +4,7 @@ ALGO_NAME := TWISTER224 # comment out the following line for removement of TWISTER-224 from the build process HASHES += $(ALGO_NAME) -$(ALGO_NAME)_OBJ := twister.o twister-small.o memxor.o gf256mul.o +$(ALGO_NAME)_OBJ := twister-small-asm.o twister-asm.o twister224.o $(ALGO_NAME)_TEST_BIN := main-twister224-test.o debug.o uart.o serial-tools.o \ nessie_hash_test.o nessie_common.o cli.o performance_test.o $(ALGO_NAME)_NESSIE_TEST := "nessie" diff --git a/mkfiles/twister224_c.mk b/mkfiles/twister224_c.mk new file mode 100644 index 0000000..fd4945c --- /dev/null +++ b/mkfiles/twister224_c.mk @@ -0,0 +1,12 @@ +# Makefile for TWISTER-224 +ALGO_NAME := TWISTER224_C + +# comment out the following line for removement of TWISTER-224 from the build process +HASHES += $(ALGO_NAME) + +$(ALGO_NAME)_OBJ := twister.o twister-small.o memxor.o gf256mul.o +$(ALGO_NAME)_TEST_BIN := main-twister224-test.o debug.o uart.o serial-tools.o \ + nessie_hash_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PERFORMANCE_TEST := "performance" + diff --git a/mkfiles/twister256.mk b/mkfiles/twister256.mk index 3fc1672..260bb24 100644 --- a/mkfiles/twister256.mk +++ b/mkfiles/twister256.mk @@ -4,7 +4,7 @@ ALGO_NAME := TWISTER256 # comment out the following line for removement of TWISTER-256 from the build process HASHES += $(ALGO_NAME) -$(ALGO_NAME)_OBJ := twister.o twister-small.o memxor.o gf256mul.o +$(ALGO_NAME)_OBJ := twister-asm.o twister-small-asm.o twister256.o $(ALGO_NAME)_TEST_BIN := main-twister256-test.o debug.o uart.o serial-tools.o \ nessie_hash_test.o nessie_common.o cli.o performance_test.o $(ALGO_NAME)_NESSIE_TEST := "nessie" diff --git a/mkfiles/twister256_c.mk b/mkfiles/twister256_c.mk new file mode 100644 index 0000000..0ea4df1 --- /dev/null +++ b/mkfiles/twister256_c.mk @@ -0,0 +1,12 @@ +# Makefile for TWISTER-256 +ALGO_NAME := TWISTER256_C + +# comment out the following line for removement of TWISTER-256 from the build process +HASHES += $(ALGO_NAME) + +$(ALGO_NAME)_OBJ := twister.o twister-small.o memxor.o gf256mul.o +$(ALGO_NAME)_TEST_BIN := main-twister256-test.o debug.o uart.o serial-tools.o \ + nessie_hash_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PERFORMANCE_TEST := "performance" + diff --git a/mkfiles/twister384.mk b/mkfiles/twister384.mk new file mode 100644 index 0000000..dacd8f1 --- /dev/null +++ b/mkfiles/twister384.mk @@ -0,0 +1,12 @@ +# Makefile for TWISTER-384 +ALGO_NAME := TWISTER384 + +# comment out the following line for removement of TWISTER-384 from the build process +HASHES += $(ALGO_NAME) + +$(ALGO_NAME)_OBJ := twister-asm.o twister-big-asm.o twister384.o +$(ALGO_NAME)_TEST_BIN := main-twister384-test.o debug.o uart.o serial-tools.o \ + nessie_hash_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PERFORMANCE_TEST := "performance" + diff --git a/mkfiles/twister384_c.mk b/mkfiles/twister384_c.mk new file mode 100644 index 0000000..d478f5e --- /dev/null +++ b/mkfiles/twister384_c.mk @@ -0,0 +1,12 @@ +# Makefile for TWISTER-384 +ALGO_NAME := TWISTER384_C + +# comment out the following line for removement of TWISTER-384 from the build process +HASHES += $(ALGO_NAME) + +$(ALGO_NAME)_OBJ := twister.o twister-big.o memxor.o gf256mul.o +$(ALGO_NAME)_TEST_BIN := main-twister384-test.o debug.o uart.o serial-tools.o \ + nessie_hash_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PERFORMANCE_TEST := "performance" + diff --git a/mkfiles/twister512.mk b/mkfiles/twister512.mk index a0ce47b..cfbc341 100644 --- a/mkfiles/twister512.mk +++ b/mkfiles/twister512.mk @@ -4,7 +4,7 @@ ALGO_NAME := TWISTER512 # comment out the following line for removement of TWISTER-512 from the build process HASHES += $(ALGO_NAME) -$(ALGO_NAME)_OBJ := twister.o twister-big.o memxor.o gf256mul.o +$(ALGO_NAME)_OBJ := twister-asm.o twister-big-asm.o twister512.o $(ALGO_NAME)_TEST_BIN := main-twister512-test.o debug.o uart.o serial-tools.o \ nessie_hash_test.o nessie_common.o cli.o performance_test.o $(ALGO_NAME)_NESSIE_TEST := "nessie" diff --git a/mkfiles/twister512_c.mk b/mkfiles/twister512_c.mk new file mode 100644 index 0000000..e13306f --- /dev/null +++ b/mkfiles/twister512_c.mk @@ -0,0 +1,12 @@ +# Makefile for TWISTER-512 +ALGO_NAME := TWISTER512_C + +# comment out the following line for removement of TWISTER-512 from the build process +HASHES += $(ALGO_NAME) + +$(ALGO_NAME)_OBJ := twister.o twister-big.o memxor.o gf256mul.o +$(ALGO_NAME)_TEST_BIN := main-twister512-test.o debug.o uart.o serial-tools.o \ + nessie_hash_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PERFORMANCE_TEST := "performance" + diff --git a/test_src/main-twister224-test.c b/test_src/main-twister224-test.c index a812e2f..40bb11e 100644 --- a/test_src/main-twister224-test.c +++ b/test_src/main-twister224-test.c @@ -30,6 +30,8 @@ #include "nessie_hash_test.h" #include "performance_test.h" +#include + #include #include #include @@ -105,7 +107,7 @@ void testrun_twister224(void){ twister224(&hash, &(stestv[i]), stestl[i]); uart_hexdump(hash, 224/8); } - +#ifdef TWISTER_LONGTEST uart_putstr_P(PSTR("\r\n\r\n=== TWISTER-224 test suit (long test) ===")); char* ltest= "abcdefghbcdefghicdefghijdefghijk" "efghijklfghijklmghijklmnhijklmno"; @@ -119,6 +121,7 @@ void testrun_twister224(void){ } twister224_ctx2hash(hash, &ctx); uart_hexdump(hash, 224/8); +#endif } @@ -127,7 +130,7 @@ void testrun_performance_twister224(void){ char str[16]; uint8_t data[64]; twister_state_t ctx; - + volatile uint16_t i; calibrateTimer(); print_overhead(); @@ -140,6 +143,9 @@ void testrun_performance_twister224(void){ ultoa((unsigned long)t, str, 10); uart_putstr(str); + i=3000; + while(i--) + _delay_ms(1); startTimer(1); twister_small_nextBlock(&ctx, data); @@ -148,6 +154,9 @@ void testrun_performance_twister224(void){ ultoa((unsigned long)t, str, 10); uart_putstr(str); + i=3000; + while(i--) + _delay_ms(1); startTimer(1); twister_small_lastBlock(&ctx, data, 0); @@ -155,7 +164,11 @@ void testrun_performance_twister224(void){ uart_putstr_P(PSTR("\r\n\tlast block time: ")); ultoa((unsigned long)t, str, 10); uart_putstr(str); - + + i=3000; + while(i--) + _delay_ms(1); + startTimer(1); twister_small_ctx2hash(data, &ctx, 224); t = stopTimer(); @@ -163,6 +176,10 @@ void testrun_performance_twister224(void){ ultoa((unsigned long)t, str, 10); uart_putstr(str); + i=3000; + while(i--) + _delay_ms(1); + uart_putstr_P(PSTR("\r\n")); } diff --git a/test_src/main-twister256-test.c b/test_src/main-twister256-test.c index 9467456..e9d3c59 100644 --- a/test_src/main-twister256-test.c +++ b/test_src/main-twister256-test.c @@ -110,7 +110,8 @@ void testrun_twister256(void){ twister256(&hash, &(stestv[i]), stestl[i]); print_hash(hash); } - + +#ifdef TWISTER_LONGTEST uart_putstr_P(PSTR("\r\n\r\n=== TWISTER-256 test suit (long test) ===")); char* ltest= "abcdefghbcdefghicdefghijdefghijk" "efghijklfghijklmghijklmnhijklmno"; @@ -124,6 +125,7 @@ void testrun_twister256(void){ } twister256_ctx2hash(hash, &ctx); print_hash(hash); +#endif } diff --git a/test_src/main-twister384-test.c b/test_src/main-twister384-test.c new file mode 100644 index 0000000..87adf5e --- /dev/null +++ b/test_src/main-twister384-test.c @@ -0,0 +1,210 @@ +/* main-twister384-test.c */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/* + * twister test suit + * +*/ + +#include "config.h" +#include "serial-tools.h" +#include "uart.h" +#include "debug.h" + +#include "twister-big.h" +#include "nessie_hash_test.h" +#include "performance_test.h" + +#include +#include +#include +#include "cli.h" + +char* algo_name = "TWISTER-384"; + +/***************************************************************************** + * additional validation-functions * + *****************************************************************************/ +void twister384_init_dummy(void* ctx){ + twister_big_init(ctx, 384); +} + +void twister384_next_dummy(void* buffer, void* ctx){ + twister_big_nextBlock(ctx, buffer); +} + +void twister384_last_dummy(void* buffer, uint16_t size_b, void* ctx){ + twister_big_lastBlock(ctx, buffer, size_b); +} + +void twister384_ctx2hash_dummy(void* buffer, void* ctx){ + twister_big_ctx2hash(buffer, ctx, 384); +} + + +void testrun_nessie_twister384(void){ + nessie_hash_ctx.hashsize_b = 384; + nessie_hash_ctx.blocksize_B = 512/8; + nessie_hash_ctx.ctx_size_B = sizeof(twister_big_ctx_t); + nessie_hash_ctx.name = algo_name; + nessie_hash_ctx.hash_init = (nessie_hash_init_fpt)twister384_init_dummy; + nessie_hash_ctx.hash_next = (nessie_hash_next_fpt)twister384_next_dummy; + nessie_hash_ctx.hash_last = (nessie_hash_last_fpt)twister384_last_dummy; + nessie_hash_ctx.hash_conv = (nessie_hash_conv_fpt)twister384_ctx2hash_dummy; + + nessie_hash_run(); +} + +/****************************************************************************** + * selftests + ******************************************************************************/ + +void print_hash(void* hash){ + uart_hexdump(hash, 256/8); + uart_putstr_P(PSTR("\r\n\t")); + uart_hexdump((uint8_t*)hash+256/8, 128/8); + +} + +void testrun_twister384(void){ + twister384_hash_t hash; + char* testv[]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + uint32_t i; + + uart_putstr_P(PSTR("\r\n=== TWISTER-384 test suit (MD5 test values) ===")); + for(i=0; i<7; ++i){ + uart_putstr_P(PSTR("\r\n TWISTER-384 (\"")); + uart_putstr(testv[i]); + uart_putstr_P(PSTR("\") = \r\n\t")); + twister384(&hash, testv[i], strlen(testv[i])*8); + print_hash(hash); + // return; + } + + uart_putstr_P(PSTR("\r\n\r\n=== TWISTER-384 test suit (short test values) ===")); + uint8_t stestv[]= {0x00, 0x00, 0xC0, 0xC0, 0x80, 0x48, 0x50}; + uint8_t stestl[]= { 0, 1, 2, 3, 4, 5, 6}; + for(i=0; i<7; ++i){ + uart_putstr_P(PSTR("\r\n TWISTER-384 (\"")); + uart_hexdump(&(stestv[i]), 1); + uart_putstr_P(PSTR("\") = \r\n\t")); + twister384(hash, &(stestv[i]), stestl[i]); + print_hash(hash); + } + +#ifdef TWISTER_LONGTEST + uart_putstr_P(PSTR("\r\n\r\n=== TWISTER-384 test suit (long test) ===")); + char* ltest= "abcdefghbcdefghicdefghijdefghijk" + "efghijklfghijklmghijklmnhijklmno"; + twister384_ctx_t ctx; + twister384_init(&ctx); + uart_putstr_P(PSTR("\r\n TWISTER-384 ( 16777216 x \"")); + uart_putstr(ltest); + uart_putstr_P(PSTR("\") = \r\n\t")); + for(i=0; i<16777216; ++i){ + twister384_nextBlock(&ctx, ltest); + } + twister384_ctx2hash(hash, &ctx); + print_hash(hash); +#endif +} + + +void testrun_performance_twister384(void){ + uint64_t t; + char str[16]; + uint8_t data[64]; + twister_big_ctx_t ctx; + + calibrateTimer(); + print_overhead(); + + memset(data, 0, 64); + + startTimer(1); + twister_big_init(&ctx, 384); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tctx-gen time: ")); + ultoa((unsigned long)t, str, 10); + uart_putstr(str); + + + startTimer(1); + twister_big_nextBlock(&ctx, data); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tone-block time: ")); + ultoa((unsigned long)t, str, 10); + uart_putstr(str); + + + startTimer(1); + twister_big_lastBlock(&ctx, data, 0); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tlast block time: ")); + ultoa((unsigned long)t, str, 10); + uart_putstr(str); + + startTimer(1); + twister_big_ctx2hash(data, &ctx, 384); + t = stopTimer(); + uart_putstr_P(PSTR("\r\n\tctx2hash time: ")); + ultoa((unsigned long)t, str, 10); + uart_putstr(str); + + uart_putstr_P(PSTR("\r\n")); +} + + +/***************************************************************************** + * main + * + *****************************************************************************/ + +int main (void){ + char str[20]; + + + DEBUG_INIT(); + uart_putstr_P(PSTR("\r\n")); + + uart_putstr_P(PSTR("\r\n\r\nCrypto-VS (")); + uart_putstr(algo_name); + uart_putstr_P(PSTR(")\r\nloaded and running\r\n")); + PGM_P u = PSTR("nessie\0test\0performance\0"); + void_fpt v[] = { testrun_nessie_twister384, + testrun_twister384, + testrun_performance_twister384 }; + + while(1){ + if (!getnextwordn(str,20)){DEBUG_S("DBG: W1\r\n"); goto error;} + if(execcommand_d0_P(str, u, v)<0){ + uart_putstr_P(PSTR("\r\nunknown command\r\n")); + } + continue; + error: + uart_putstr("ERROR\r\n"); + } +} + diff --git a/test_src/main-twister512-test.c b/test_src/main-twister512-test.c index 22309d0..c9cc667 100644 --- a/test_src/main-twister512-test.c +++ b/test_src/main-twister512-test.c @@ -113,7 +113,8 @@ void testrun_twister512(void){ twister512(hash, &(stestv[i]), stestl[i]); print_hash(hash); } - + +#ifdef TWISTER_LONGTEST uart_putstr_P(PSTR("\r\n\r\n=== TWISTER-512 test suit (long test) ===")); char* ltest= "abcdefghbcdefghicdefghijdefghijk" "efghijklfghijklmghijklmnhijklmno"; @@ -127,6 +128,7 @@ void testrun_twister512(void){ } twister512_ctx2hash(hash, &ctx); print_hash(hash); +#endif } diff --git a/twister-asm.S b/twister-asm.S new file mode 100644 index 0000000..9e948a4 --- /dev/null +++ b/twister-asm.S @@ -0,0 +1,604 @@ +/* twister-asm.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister-asm.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-22 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" + +twister_sbox: +.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 +.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 +.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 +.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 +.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc +.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 +.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a +.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 +.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 +.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 +.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b +.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf +.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 +.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 +.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 +.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 +.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 +.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 +.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 +.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb +.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c +.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 +.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 +.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 +.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 +.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a +.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e +.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e +.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 +.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf +.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 +.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + +/* + * param ctx: r24:r25 + * param msg: r22:r23 + */ +.global twister_mini_round +twister_mini_round: + movw r26, r24 + movw r30, r22 + adiw r26, 8*7 + adiw r30, 8 + ldi r21, 8 +1: + ld r22, X + ld r23, -Z + eor r22, r23 + st X+, r22 + dec r21 + brne 1b + +/* + * param ctx: r24:r25 + * + */ +X_SAVE0 = 4 +X_SAVE1 = 5 +Y_SAVE0 = 6 +Y_SAVE1 = 7 +MDS0 = 8 +MDS1 = 9 +MDS2 = 10 +MDS3 = 11 +MDS4 = 12 +MDS5 = 13 +MDS6 = 14 +MDS7 = 15 + + +.global twister_blank_round +twister_blank_round: + push_range 4, 17 + push r28 + push r29 + stack_alloc_large 64, r28, r29 + + movw X_SAVE0, r24 + movw r30, r24 + adiw r30, 63 + adiw r30, 1+8 /* Z points behind counter */ + movw r26, r24 + adiw r26, 1 + ldi r22, 8 +1: /* "add" counter */ + ld r16, -Z + ld r21, X + eor r21, r16 + st X, r21 + adiw r26, 8 + dec r22 + brne 1b + + /* decrement counter */ + subi r16, 1 + st Z+, r16 + ldi r17, 7 +1: + ld r16, Z + sbci r16, 0 + st Z+, r16 + dec r17 + brne 1b + + movw r26, r24 + adiw r28, 1 /* Y points to stack memory */ + movw Y_SAVE0, r28 + movw r24, r28 + ldi r20, lo8(twister_sbox) + ldi r21, hi8(twister_sbox) + ldi r18, 8 +1: + ldi r19, 0 + +2: /* sbox substitution */ + ld r0, X+ + movw r30, r20 + add r30, r0 + adc r31, r1 + lpm r0, Z + movw r28, r24 + mov r16, r18 + add r16, r19 + andi r16, 0x07 + add r28, r16 + adc r29, r1 + st Y, r0 + inc r19 + cpi r19, 8 + brne 2b + adiw r24, 8 + dec r18 + brne 1b + + /* load MDS-Table to MDS0:MDS7 */ + ldi r18, 1 + mov MDS1, r18 + mov MDS2, r18 + mov MDS7, r18 + ldi r18, 2 + mov MDS0, r18 + ldi r18, 5 + mov MDS3, r18 + ldi r18, 6 + mov MDS6, r18 + ldi r18, 7 + mov MDS4, r18 + ldi r18, 8 + mov MDS5, r18 + + ldi r20, 0x4D /* reducer for gf256mul*/ + ldi r16, 0 + +1: + movw r26, X_SAVE0 + add r26, r16 + adc r27, r1 + ldi r17, 8 +2: + mov r24, MDS0 + movw r28, Y_SAVE0 + add r28, r16 + adc r29, r1 + ld r22, Y + rcall gf256mul + mov r0, r24 + + mov r24, MDS1 + ldd r22, Y+8 + rcall gf256mul + eor r0, r24 + + mov r24, MDS2 + ldd r22, Y+8*2 + rcall gf256mul + eor r0, r24 + + mov r24, MDS3 + ldd r22, Y+8*3 + rcall gf256mul + eor r0, r24 + + mov r24, MDS4 + ldd r22, Y+8*4 + rcall gf256mul + eor r0, r24 + + mov r24, MDS5 + ldd r22, Y+8*5 + rcall gf256mul + eor r0, r24 + + mov r24, MDS6 + ldd r22, Y+8*6 + rcall gf256mul + eor r0, r24 + + mov r24, MDS7 + ldd r22, Y+8*7 + rcall gf256mul + eor r0, r24 + + st X, r0 + adiw r26, 8 + + mov r0, MDS7 + mov MDS7, MDS6 + mov MDS6, MDS5 + mov MDS5, MDS4 + mov MDS4, MDS3 + mov MDS3, MDS2 + mov MDS2, MDS1 + mov MDS1, MDS0 + mov MDS0, r0 + + dec r17 + brne 2b +8: + inc r16 + cpi r16, 8 + brne 1b + +9: + stack_free_large 64 + pop r29 + pop r28 + pop_range 4, 17 + ret + +/*********************************************************************/ +A = 23 +B = 22 +P = 24 + +gf256mul: + mov A, r24 + clr P +1: + lsr A + breq 4f + brcc 2f + eor P, B +2: + lsl B + brcc 3f + eor B, r20 +3: + rjmp 1b +4: + brcc 2f + eor P, B +2: + ret + +/*********************************************************************/ +/* twister_ctx2hash */ +/* + * param dest: r24:r25 + * param ctx: r22:r23 + * param hashsize_b: r20:r21 + */ +DEST_SAVE0 = 10 +DEST_SAVE1 = 11 +CTX_SAVE0 = 12 +CTX_SAVE1 = 13 +LEN_SAVE = 14 +LEN32_SAVE = 15 +TMP_SAVE0 = 16 +TMP_SAVE1 = 17 + + +.global twister_ctx2hash +.global twister_small_ctx2hash +.global twister_big_ctx2hash +.global twister224_ctx2hash +.global twister256_ctx2hash +.global twister384_ctx2hash +.global twister512_ctx2hash + +twister224_ctx2hash: + ldi r20, lo8(224) + ldi r21, hi8(224) + rjmp twister_ctx2hash + +twister256_ctx2hash: + ldi r20, lo8(256) + ldi r21, hi8(256) + rjmp twister_ctx2hash + +twister384_ctx2hash: + ldi r20, lo8(384) + ldi r21, hi8(384) + rjmp twister_ctx2hash + +twister512_ctx2hash: + ldi r20, lo8(512) + ldi r21, hi8(512) +; rjmp twister_ctx2hash + +twister_big_ctx2hash: +twister_small_ctx2hash: +twister_ctx2hash: + push_range 10, 17 + push r28 + push r29 + stack_alloc_large 64 + movw DEST_SAVE0, r24 + movw CTX_SAVE0, r22 + clr LEN32_SAVE + sbrc r20, 5 + inc LEN32_SAVE + lsr r21 + ror r20 + lsr r21 + ror r20 /* length is max 512 so we now only have to shift r20 */ + swap r20 /* this is faster than 4 shifts */ + andi r20, 0x0f + add r20, LEN32_SAVE + mov LEN_SAVE, r20 + + adiw r30, 1 + movw TMP_SAVE0, r30 +1: + dec LEN_SAVE + brmi 9f + /* tmp <- ctx-s */ + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r20, 64/4 +3: + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + dec r20 + brne 3b + + movw r24, CTX_SAVE0 + rcall twister_blank_round + /* ctx-s ^= tmp */ + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r20, 64 +3: + ld r0, X + ld r21, Z+ + eor r0, r21 + st X+, r0 + dec r20 + brne 3b + + movw r24, CTX_SAVE0 + rcall twister_blank_round + + + movw r26, CTX_SAVE0 + + tst LEN_SAVE + brne 2f + tst LEN32_SAVE + brne 5f +2: + adiw r26, 8*7 + movw r30, TMP_SAVE0 + adiw r30, 8*7 + movw r28, DEST_SAVE0 + ldi r20, 8 +3: + ld r0, Z + ld r21, X + eor r0, r21 + st Y+, r0 + sbiw r26, 8 + sbiw r30, 8 + dec r20 + brne 3b + movw DEST_SAVE0, r28 +7: + rjmp 1b + +5: + adiw r26, 8*3 + movw r30, TMP_SAVE0 + adiw r30, 8*3 + movw r28, DEST_SAVE0 + ldi r20, 4 +3: + ld r0, Z + ld r21, X + eor r0, r21 + st Y+, r0 + sbiw r26, 8 + sbiw r30, 8 + dec r20 + brne 3b + +9: + stack_free_large 64 + pop r29 + pop r28 + pop_range 10, 17 + ret + + + +/*********************************************************************/ +/* void twister_small_nextBlock(twister_state_t* ctx, void* msg) */ +/* + * param ctx: r24:r25 + * param msg: r22:r23 + */ +CTX_SAVE0 = 14 +CTX_SAVE1 = 15 +TMP_SAVE0 = 12 +TMP_SAVE1 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 +.global twister_small_nextBlock +.global twister224_nextBlock +.global twister256_nextBlock + +twister224_nextBlock: +twister256_nextBlock: +twister_small_nextBlock: + push_range 12, 15 + push r28 + push r29 + stack_alloc_large 64 + adiw r30, 1 + movw TMP_SAVE0, r30 + movw CTX_SAVE0, r24 + movw MSG_SAVE0, r22 + movw r26, CTX_SAVE0 + ldi r18, 64/8 +1: + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + dec r18 + brne 1b + + rcall twister_mini_round + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z + eor r0, r23 + st X+, r0 + st Z+, r0 + dec r18 + brne 1b + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z + eor r0, r23 + st X+, r0 + st Z+, r0 + dec r18 + brne 1b + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + rcall twister_blank_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z+ + eor r0, r23 + st X+, r0 + dec r18 + brne 1b + + adiw r26, 9 + ldi r19, 2 + ld r0, X + add r0, r19 + st X+, r0 + + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + + stack_free_large 64 + pop r29 + pop r28 + pop_range 12, 15 + ret + + + + + + + + diff --git a/twister-big-asm.S b/twister-big-asm.S new file mode 100644 index 0000000..c296e59 --- /dev/null +++ b/twister-big-asm.S @@ -0,0 +1,513 @@ +/* twister-big-asm.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister-big-asm.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-27 + * \license GPLv3 or later + * + */ + + #include "avr-asm-macros.S" + +/* void checksum_update(twister_big_ctx_t* ctx, uint8_t col) */ +/* + * param ctx: r24:r25 + * param col: r22 + */ +checksum_update: + push r16 + push r28 + push r29 + lsl r22 + lsl r22 + lsl r22 + mov r16, r22 + movw r30, r24 /* X points to ctx->state.s */ + + ldd r18, Z+7*8 + ldd r19, Z+6*8 + ldd r20, Z+5*8 + ldd r21, Z+4*8 + ldd r22, Z+3*8 + ldd r23, Z+2*8 + ldd r24, Z+1*8 + ldd r25, Z+0*8 + + adiw r30, 63 + adiw r30, 1+3*8 /* Z points at ctx->checksum[0][8] */ + movw r28, r30 /* Y points at ctx->checksum[0][8] */ + andi r16, 63 + add r30, r16 /* Z points at ctx->checksum[col][8]*/ + adc r31, r1 + ldi r26, 8 + add r16, r26 + andi r16, 63 + add r28, r16 + adc r29, r1 /* Y points at ctx->checksum[(col+1)%8][8]*/ + + ld r0, -Y + add r18, r0 + ld r0, -Z + eor r0, r18 + st Z, r0 + + ld r0, -Y + adc r19, r0 + ld r0, -Z + eor r0, r19 + st Z, r0 + + ld r0, -Y + adc r20, r0 + ld r0, -Z + eor r0, r20 + st Z, r0 + + ld r0, -Y + adc r21, r0 + ld r0, -Z + eor r0, r21 + st Z, r0 + + ld r0, -Y + adc r22, r0 + ld r0, -Z + eor r0, r22 + st Z, r0 + + ld r0, -Y + adc r23, r0 + ld r0, -Z + eor r0, r23 + st Z, r0 + + ld r0, -Y + adc r24, r0 + ld r0, -Z + eor r0, r24 + st Z, r0 + + ld r0, -Y + adc r25, r0 + ld r0, -Z + eor r0, r25 + st Z, r0 + + pop r29 + pop r28 + pop r16 + ret + +/*********************************************************************/ +/* void twister_big_init(twister_big_ctx_t* ctx, uint16_t hashsize_b)*/ +/* + * param ctx: r24:r25 + * param hashsize_b: r22:r23 + */ +.global twister384_init +twister384_init: + ldi r22, lo8(384) + ldi r23, hi8(384) + rjmp twister_big_init + +.global twister512_init +twister512_init: + ldi r22, lo8(512) + ldi r23, hi8(512) + +.global twister_big_init +twister_big_init: + movw r30, r24 + ldi r24, 64 +1: + st Z+, r1 + dec r24 + brne 1b + + dec r1 + ldi r24, 8 +1: + st Z+, r1 + dec r24 + brne 1b + + inc r1 + ldi r24, 8+64 +1: + st Z+, r1 + dec r24 + brne 1b + + subi r30, lo8(1+8+8+8*7+64) + sbci r31, hi8(1+8+8+8*7+64) + st Z, r23 + std Z+8, r22 + ret + +/*********************************************************************/ +/* void twister_big_nextBlock(twister_state_t* ctx, void* msg) */ +/* + * param ctx: r24:r25 + * param msg: r22:r23 + */ +CTX_SAVE0 = 14 +CTX_SAVE1 = 15 +TMP_SAVE0 = 12 +TMP_SAVE1 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 +.global twister_big_nextBlock +.global twister384_nextBlock +.global twister512_nextBlock + +twister384_nextBlock: +twister512_nextBlock: +twister_big_nextBlock: + push_range 12, 15 + push r28 + push r29 + stack_alloc_large 64 + adiw r30, 1 + movw TMP_SAVE0, r30 + movw CTX_SAVE0, r24 + movw MSG_SAVE0, r22 + movw r26, CTX_SAVE0 + ldi r18, 64/8 +1: + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + ld r0, X+ + st Z+, r0 + dec r18 + brne 1b + /* maxi round 1 */ + movw r24, CTX_SAVE0 + ldi r22, 0 + rcall checksum_update + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + ldi r22, 1 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + ldi r22, 2 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z + eor r0, r23 + st X+, r0 + st Z+, r0 + dec r18 + brne 1b + /* maxi round 2 */ + movw r24, CTX_SAVE0 + ldi r22, 3 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + rcall twister_blank_round + + movw r24, CTX_SAVE0 + ldi r22, 4 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z + eor r0, r23 + st X+, r0 + st Z+, r0 + dec r18 + brne 1b + /* maxi round 3 */ + movw r24, CTX_SAVE0 + ldi r22, 5 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + ldi r22, 6 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + ldi r22, 7 + rcall checksum_update + adiw MSG_SAVE0, 8 + movw r22, MSG_SAVE0 + movw r24, CTX_SAVE0 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + rcall twister_blank_round + + movw r30, TMP_SAVE0 + movw r26, CTX_SAVE0 + ldi r18, 64 +1: + ld r0, X + ld r23, Z+ + eor r0, r23 + st X+, r0 + dec r18 + brne 1b + + adiw r26, 9 + ldi r19, 2 + ld r0, X + add r0, r19 + st X+, r0 + + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + ld r0, X + adc r0, r1 + st X+, r0 + + stack_free_large 64 + pop r29 + pop r28 + pop_range 12, 15 + ret + +/*********************************************************************/ +/* void twister_big_lastBlock(twister_state_t* ctx, void* msg, uint16_t length_b) */ +/* + * param ctx: r24:r25 + * param msg: r22:r23 + * param length_b: r20:r21 + */ +TMP_SAVE0 = 12 +TMP_SAVE1 = 13 +CTX_SAVE0 = 14 +CTX_SAVE1 = 15 +LEN_SAVE0 = 16 +LEN_SAVE1 = 17 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 +.global twister_big_lastBlock +.global twister384_lastBlock +.global twister512_lastBlock + +twister384_lastBlock: +twister512_lastBlock: +twister_big_lastBlock: + push_range 12, 17 + push r28 + push r29 + stack_alloc_large 64 + adiw r30, 1 + movw TMP_SAVE0, r30 + movw CTX_SAVE0, r24 + movw MSG_SAVE0, r22 + movw LEN_SAVE0, r20 +1: + cpi LEN_SAVE1, 2 + brmi 2f + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_big_nextBlock + adiw MSG_SAVE0, 8 + subi LEN_SAVE1, 2 + rjmp 1b +2: + movw r18, LEN_SAVE0 + lsr r19 + ror r18 + lsr r18 + lsr r18 + ldi r19, 63 + movw r26, MSG_SAVE0 + movw r30, TMP_SAVE0 + ldi r20, 0x80 + sub r19, r18 /* r18: bytes to copy, r19: bytes to clear */ + + ld r0, X+ +3: + tst r18 + breq 4f + st Z+, r0 + ld r0, X+ + dec r18 + +4: + mov r18, LEN_SAVE0 + andi r18, 0x07 + ldi r20, 0x80 + breq 5f +4: + lsr r20 + dec r18 + brne 4b + or r20, r0 + rjmp 5f + +5: + st Z+, r20 +6: + st Z+, r1 + dec r19 + brne 6b + + movw r24, CTX_SAVE0 + movw r22, TMP_SAVE0 + rcall twister_big_nextBlock + + ldi r19, 2 + clr r18 + + sub r18, LEN_SAVE0 + sbc r19, LEN_SAVE1 + movw r26, CTX_SAVE0 + adiw r26, 63 + adiw r26, 1+8 + + ld r0, X + sub r0, r18 + st X+, r0 + ld r0, X + sbc r0, r19 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + + sbiw r26, 8 + movw r24, CTX_SAVE0 + movw r22, r26 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + movw r22, CTX_SAVE0 + ldi r16, 64+8+8 + add r22, r16 + adc r23, r1 + movw r30, r22 + ldi r26, 8 +1: + ld r12, Z+ + ld r13, Z+ + ld r16, Z+ + ld r17, Z+ + ld r18, Z+ + ld r19, Z+ + ld r20, Z+ + ld r21, Z+ + st -Z, r12 + st -Z, r13 + st -Z, r16 + st -Z, r17 + st -Z, r18 + st -Z, r19 + st -Z, r20 + st -Z, r21 + adiw r30, 8 + dec r26 + brne 1b + + movw r24, CTX_SAVE0 + movw r22, CTX_SAVE0 + ldi r26, 64+2*8 + add r22, r26 + adc r23, r1 + rcall twister_small_nextBlock + + stack_free_large 64 + pop r29 + pop r28 + pop_range 12, 17 + ret diff --git a/twister-big.c b/twister-big.c index 9c8cef7..9eea966 100644 --- a/twister-big.c +++ b/twister-big.c @@ -9,6 +9,9 @@ #undef DEBUG #define DEBUG +/*********************************************************************/ +/*********************************************************************/ + #ifdef DEBUG #include #include "uart.h" @@ -24,6 +27,8 @@ void print_checksum(twister_big_ctx_t* ctx, PGM_P s){ } } +/*********************************************************************/ + void print_matrix(void* m, PGM_P s){ uint8_t i; uart_putstr_P(PSTR("\r\n")); @@ -36,6 +41,8 @@ void print_matrix(void* m, PGM_P s){ } } +/*********************************************************************/ + #define DEBUG_CHKSUM(a,s) print_checksum((a),PSTR(s)) #else #define DEBUG_CHKSUM(a,s) @@ -50,6 +57,8 @@ void print_matrix(void* m, PGM_P s){ #ifdef DEBUG +/*********************************************************************/ + void print_twister_state(twister_state_t* ctx){ uint8_t i; uart_putstr_P(PSTR("\r\nState:\r\n matrix:\r\n")); @@ -66,6 +75,8 @@ void print_twister_state(twister_state_t* ctx){ uart_putstr_P(PSTR("\r\n")); } +/*********************************************************************/ + void debug_print(twister_state_t* ctx, PGM_P msg){ uart_putstr_P(PSTR("\r\n")); uart_putstr_P(msg); @@ -74,14 +85,7 @@ void debug_print(twister_state_t* ctx, PGM_P msg){ #endif -void transp_matrix(void* dest, void* src){ - uint8_t i,j; - for(i=0; i<8; i++){ - for(j=0; j<8; ++j){ - ((uint8_t*)dest)[i*8+j] = ((uint8_t*)src)[j*8+i]; - } - } -} +/*********************************************************************/ static void checksum_update(twister_big_ctx_t* ctx, uint8_t col){ @@ -103,6 +107,8 @@ void checksum_update(twister_big_ctx_t* ctx, uint8_t col){ // DEBUG_CHKSUM(ctx, "post run"); } +/*********************************************************************/ + void twister_big_init(twister_big_ctx_t* ctx, uint16_t hashsize_b){ memset(ctx->state.s, 0, 64); memset(ctx->checksum, 0, 64); @@ -112,6 +118,8 @@ void twister_big_init(twister_big_ctx_t* ctx, uint16_t hashsize_b){ ctx->state.length_counter_b = 0; } +/*********************************************************************/ + void twister_big_nextBlock(twister_big_ctx_t* ctx, void* msg){ uint8_t tmp[8][8]; @@ -161,11 +169,15 @@ void twister_big_nextBlock(twister_big_ctx_t* ctx, void* msg){ ctx->state.length_counter_b += 512; } +/*********************************************************************/ + void twister_inject_chksum(twister_big_ctx_t* ctx, uint8_t col){ *((uint64_t*)(&ctx->state.s[7][0])) ^= *((uint64_t*)(&ctx->checksum[col][0])); twister_blank_round(&ctx->state); } +/*********************************************************************/ + void twister_big_lastBlock(twister_big_ctx_t* ctx, void* msg, uint16_t length_b){ uint8_t tmp[64]; while(length_b>512){ @@ -204,29 +216,39 @@ void twister_big_lastBlock(twister_big_ctx_t* ctx, void* msg, uint16_t length_b) // DEBUG_PRINT(&(ctx->state), "post check-round"); } +/*********************************************************************/ + void twister_big_ctx2hash(void* dest, twister_big_ctx_t* ctx, uint16_t hashsize_b){ twister_ctx2hash(dest, &(ctx->state), hashsize_b); } -/******************************************************************************/ -/******************************************************************************/ +/*********************************************************************/ +/*********************************************************************/ void twister384_init(twister384_ctx_t* ctx){ twister_big_init(ctx, 384); } +/*********************************************************************/ + void twister384_nextBlock(twister384_ctx_t* ctx, void* msg){ twister_big_nextBlock(ctx, msg); } +/*********************************************************************/ + void twister384_lastBlock(twister384_ctx_t* ctx, void* msg, uint16_t length_b){ twister_big_lastBlock(ctx, msg, length_b); } +/*********************************************************************/ + void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx){ twister_big_ctx2hash(dest, ctx, 384); } +/*********************************************************************/ + void twister384(void* dest, void* msg, uint32_t msg_length_b){ twister_big_ctx_t ctx; twister_big_init(&ctx, 384); @@ -239,24 +261,34 @@ void twister384(void* dest, void* msg, uint32_t msg_length_b){ twister_big_ctx2hash(dest, &ctx, 384); } -/******************************************************************************/ +/*********************************************************************/ +/*********************************************************************/ + void twister512_init(twister512_ctx_t* ctx){ twister_big_init(ctx, 512); } +/*********************************************************************/ + void twister512_nextBlock(twister512_ctx_t* ctx, void* msg){ twister_big_nextBlock(ctx, msg); } +/*********************************************************************/ + void twister512_lastBlock(twister512_ctx_t* ctx, void* msg, uint16_t length_b){ twister_big_lastBlock(ctx, msg, length_b); } +/*********************************************************************/ + void twister512_ctx2hash(void* dest, twister512_ctx_t* ctx){ twister_big_ctx2hash(dest, ctx, 512); } +/*********************************************************************/ + void twister512(void* dest, void* msg, uint32_t msg_length_b){ twister_big_ctx_t ctx; twister_big_init(&ctx, 512); diff --git a/twister-big.h b/twister-big.h index 69be069..dd9c1fc 100644 --- a/twister-big.h +++ b/twister-big.h @@ -17,11 +17,14 @@ typedef struct { typedef twister_big_ctx_t twister384_ctx_t; typedef twister_big_ctx_t twister512_ctx_t; +/*********************************************************************/ + void twister_big_nextBlock(twister_big_ctx_t* ctx, void* msg); void twister_big_init(twister_big_ctx_t* ctx, uint16_t hashsize_b); void twister_big_lastBlock(twister_big_ctx_t* ctx, void* msg, uint16_t length_b); void twister_big_ctx2hash(void* dest, twister_big_ctx_t* ctx, uint16_t hashsize_b); +/*********************************************************************/ void twister384_init(twister384_ctx_t* ctx); void twister384_nextBlock(twister384_ctx_t* ctx, void* msg); @@ -29,6 +32,8 @@ void twister384_lastBlock(twister384_ctx_t* ctx, void* msg, uint16_t length_b); void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx); void twister384(void* dest, void* msg, uint32_t msg_length_b); +/*********************************************************************/ + void twister512_init(twister512_ctx_t* ctx); void twister512_nextBlock(twister512_ctx_t* ctx, void* msg); void twister512_lastBlock(twister512_ctx_t* ctx, void* msg, uint16_t length_b); diff --git a/twister-small-asm.S b/twister-small-asm.S new file mode 100644 index 0000000..e1ee310 --- /dev/null +++ b/twister-small-asm.S @@ -0,0 +1,206 @@ +/* twister-small-asm.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister-small-asm.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-26 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" + +/* void twister_small_init(twister_state_t* ctx, uint16_t hashsize_b)*/ +/* + * param ctx: r24:r25 + * param hashsize_b: r22:r23 + */ +.global twister224_init +twister224_init: + ldi r22, lo8(224) + ldi r23, hi8(224) + rjmp 1f + +.global twister256_init +twister256_init: + ldi r22, lo8(256) + ldi r23, hi8(256) + +.global twister_small_init +twister_small_init: + movw r30, r24 + ldi r24, 64 +1: + st Z+, r1 + dec r24 + brne 1b + + dec r1 + ldi r24, 8 +1: + st Z+, r1 + dec r24 + brne 1b + + inc r1 + ldi r24, 8 +1: + st Z+, r1 + dec r24 + brne 1b + + sbiw r30, 1+8+8 + sbiw r30, 8*7 + st Z, r23 + std Z+8, r22 + ret +#if 1 +/*********************************************************************/ +/* void twister_small_lastBlock(twister_state_t* ctx, void* msg, uint16_t length_b) */ +/* + * param ctx: r24:r25 + * param msg: r22:r23 + * param length_b: r20:r21 + */ +TMP_SAVE0 = 12 +TMP_SAVE1 = 13 +CTX_SAVE0 = 14 +CTX_SAVE1 = 15 +LEN_SAVE0 = 16 +LEN_SAVE1 = 17 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 +.global twister_small_lastBlock +.global twister224_lastBlock +.global twister256_lastBlock + +twister224_lastBlock: +twister256_lastBlock: +twister_small_lastBlock: + push_range 12, 17 + push r28 + push r29 + stack_alloc_large 64 + adiw r30, 1 + movw TMP_SAVE0, r30 + movw CTX_SAVE0, r24 + movw MSG_SAVE0, r22 + movw LEN_SAVE0, r20 +1: + cpi LEN_SAVE1, 2 + brmi 2f + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_small_nextBlock + adiw MSG_SAVE0, 8 + subi LEN_SAVE1, 2 + rjmp 1b +2: + movw r18, LEN_SAVE0 + lsr r19 + ror r18 + lsr r18 + lsr r18 + ldi r19, 63 + movw r26, MSG_SAVE0 + movw r30, TMP_SAVE0 + ldi r20, 0x80 + sub r19, r18 /* r18: bytes to copy, r19: bytes to clear */ + + ld r0, X+ +3: + tst r18 + breq 4f + st Z+, r0 + ld r0, X+ + dec r18 + +4: + mov r18, LEN_SAVE0 + andi r18, 0x07 + ldi r20, 0x80 + breq 5f +4: + lsr r20 + dec r18 + brne 4b + or r20, r0 + rjmp 5f + +5: + st Z+, r20 +6: + st Z+, r1 + dec r19 + brne 6b + + movw r24, CTX_SAVE0 + movw r22, TMP_SAVE0 + rcall twister_small_nextBlock + + ldi r19, 2 + clr r18 + + sub r18, LEN_SAVE0 + sbc r19, LEN_SAVE1 + movw r26, CTX_SAVE0 + adiw r26, 63 + adiw r26, 1+8 + + ld r0, X + sub r0, r18 + st X+, r0 + ld r0, X + sbc r0, r19 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + ld r0, X + sbc r0, r1 + st X+, r0 + + sbiw r26, 8 + movw r24, CTX_SAVE0 + movw r22, r26 + rcall twister_mini_round + + movw r24, CTX_SAVE0 + rcall twister_blank_round + + stack_free_large 64 + pop r29 + pop r28 + pop_range 12, 17 + ret + +#endif diff --git a/twister-small-stub.c b/twister-small-stub.c new file mode 100644 index 0000000..9eb4112 --- /dev/null +++ b/twister-small-stub.c @@ -0,0 +1,167 @@ +/* twister-small.c */ + +#include +#include +#include "memxor.h" +#include "twister-small.h" + +/*********************************************************************/ +#if 0 +void twister_small_init(twister_state_t* ctx, uint16_t hashsize_b){ + memset(ctx->s, 0, 64); + ctx->counter=0xffffffffffffffffLL; + ctx->s[0][7] = hashsize_b>>8; + ctx->s[1][7] = hashsize_b&0xff; + ctx->length_counter_b = 0; +} + +/*********************************************************************/ + +void twister_small_nextBlock(twister_state_t* ctx, void* msg){ + uint8_t tmp[8][8]; + /* round 1 */ + memcpy(tmp, ctx->s, 64); + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + memxor(ctx->s, tmp, 64); + + /* round 2 */ + memcpy(tmp, ctx->s, 64); + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + memxor(ctx->s, tmp, 64); + + /* round 3 */ + memcpy(tmp, ctx->s, 64); + twister_mini_round(ctx, msg); + msg = ((uint8_t*)msg) + 8; + twister_mini_round(ctx, msg); + twister_blank_round(ctx); + memxor(ctx->s, tmp, 64); + ctx->length_counter_b += 512; +} +#endif +/*********************************************************************/ +#if 0 +void twister_small_lastBlock(twister_state_t* ctx, void* msg, uint16_t length_b){ + uint8_t tmp[64]; + while(length_b>512){ + twister_small_nextBlock(ctx, msg); + msg = ((uint8_t*)msg)+64; + length_b -= 512; + } + memset(tmp, 0, 64); + memcpy(tmp, msg, (length_b+7)/8); + tmp[length_b/8] |= 0x80 >> (length_b&0x07); + twister_small_nextBlock(ctx, tmp); + ctx->length_counter_b -= 512 - length_b; + twister_mini_round(ctx, &(ctx->length_counter_b)); + twister_blank_round(ctx); +} + + +void twister256_lastBlock(twister256_ctx_t* ctx, void* msg, uint16_t length_b){ + twister_small_lastBlock(ctx, msg, length_b); +} + + +void twister224_lastBlock(twister224_ctx_t* ctx, void* msg, uint16_t length_b){ + twister_small_lastBlock(ctx, msg, length_b); +} + +#endif +#if 0 +/*********************************************************************/ + +void twister_small_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b){ + twister_ctx2hash(dest, ctx, hashsize_b); +} + +/*********************************************************************/ +/*********************************************************************/ + +#ifndef NO_TWISTER_256 + +void twister256_init(twister256_ctx_t* ctx){ + twister_small_init(ctx, 256); +} + +/*********************************************************************/ + +void twister256_nextBlock(twister256_ctx_t* ctx, void* msg){ + twister_small_nextBlock(ctx, msg); +} + +/*********************************************************************/ + +/*********************************************************************/ + +void twister256_ctx2hash(void* dest, twister256_ctx_t* ctx){ + twister_ctx2hash(dest, ctx, 256); +} + +/*********************************************************************/ + +void twister256(void* dest, void* msg, uint32_t msg_length_b){ + twister_state_t ctx; + twister_small_init(&ctx, 256); + while(msg_length_b >=512){ + twister_small_nextBlock(&ctx, msg); + msg = (uint8_t*)msg + 512/8; + msg_length_b -= 512; + } + twister_small_lastBlock(&ctx, msg, msg_length_b); + twister_ctx2hash(dest, &ctx, 256); +} + +/*********************************************************************/ + +#endif + +/*********************************************************************/ +/*********************************************************************/ + +#ifndef NO_TWISTER_224 + +void twister224_init(twister224_ctx_t* ctx){ + twister_small_init(ctx, 224); +} + +/*********************************************************************/ + +void twister224_nextBlock(twister224_ctx_t* ctx, void* msg){ + twister_small_nextBlock(ctx, msg); +} + +/*********************************************************************/ + +/*********************************************************************/ + +void twister224_ctx2hash(void* dest, twister224_ctx_t* ctx){ + twister_ctx2hash(dest, ctx, 224); +} + +/*********************************************************************/ + +void twister224(void* dest, void* msg, uint32_t msg_length_b){ + twister_state_t ctx; + twister_small_init(&ctx, 224); + while(msg_length_b >=512){ + twister_small_nextBlock(&ctx, msg); + msg = (uint8_t*)msg + 512/8; + msg_length_b -= 512; + } + twister_small_lastBlock(&ctx, msg, msg_length_b); + twister_ctx2hash(dest, &ctx, 224); +} + +#endif +#endif diff --git a/twister-small.c b/twister-small.c index 68e8e82..2f46af0 100644 --- a/twister-small.c +++ b/twister-small.c @@ -53,6 +53,7 @@ void twister_small_nextBlock(twister_state_t* ctx, void* msg){ void twister_small_lastBlock(twister_state_t* ctx, void* msg, uint16_t length_b){ uint8_t tmp[64]; + uint8_t i; while(length_b>512){ twister_small_nextBlock(ctx, msg); msg = ((uint8_t*)msg)+64; @@ -63,6 +64,7 @@ void twister_small_lastBlock(twister_state_t* ctx, void* msg, uint16_t length_b) tmp[length_b/8] |= 0x80 >> (length_b&0x07); twister_small_nextBlock(ctx, tmp); ctx->length_counter_b -= 512 - length_b; + twister_mini_round(ctx, &(ctx->length_counter_b)); twister_blank_round(ctx); } diff --git a/twister-stub.c b/twister-stub.c new file mode 100644 index 0000000..d5bd6f6 --- /dev/null +++ b/twister-stub.c @@ -0,0 +1,159 @@ +/* twister.c */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ + +#include "config.h" +#include +#include +#include +#include "twister.h" +#include "twister_tables.h" +#include "memxor.h" + +#ifndef TWISTER_MUL_TABLE +# include "gf256mul.h" +#endif + +#undef DEBUG + +#ifdef DEBUG +# include "uart.h" +#endif + +#ifdef DEBUG +# define DEBUG_PRINT(ctx, msg) debug_print((ctx), PSTR(msg)) +#else +# define DEBUG_PRINT(ctx, msg) +#endif + +#ifdef DEBUG + +void print_twister_state(twister_state_t* ctx){ + uint8_t i; + uart_putstr_P(PSTR("\r\nState:\r\n matrix:\r\n")); + for(i=0; i<8; ++i){ + uart_putstr_P(PSTR("\t[ ")); + uart_hexdump(&(ctx->s[i][0]), 8); + uart_putstr_P(PSTR("]\r\n")); + } + uart_putstr_P(PSTR("counter: ")); + uart_hexdump(&(ctx->counter), 8); + + uart_putstr_P(PSTR("\r\nlength_counter_b: ")); + uart_hexdump(&(ctx->length_counter_b), 8); + uart_putstr_P(PSTR("\r\n")); +} + +void debug_print(twister_state_t* ctx, PGM_P msg){ + uart_putstr_P(PSTR("\r\n")); + uart_putstr_P(msg); + print_twister_state(ctx); +} + +#endif + +static +void shiftrow(void* row, uint8_t shift){ + *((uint64_t*)row) = *((uint64_t*)row)>>(8*shift) | *((uint64_t*)row)<<(64-8*shift); +} + +#define MDS(a,b) pgm_read_byte(&(twister_mds[(a)][(b)])) + +#ifdef TWISTER_MUL_TABLE +# define MULT(a,b) pgm_read_byte(&(twister_multab[a][b])) +#else +# define MULT(a,b) gf256mul((a),(b), 0x4D) +#endif +void twister_blank_round(twister_state_t* ctx){ + uint8_t i,j,k=0; + uint8_t tmp[8][8]; + DEBUG_PRINT(ctx, "blank init"); + /* add twist counter */ + for(i=0; i<8; ++i){ + ctx->s[i][1] ^= ((uint8_t*)&(ctx->counter))[7-i]; + } + ctx->counter--; +// DEBUG_PRINT(ctx, "counter added"); + /* sub bytes */ + for(i=0; i<8; ++i){ + for(j=0;j<8;++j){ + tmp[i][j] = pgm_read_byte(twister_sbox+ctx->s[i][j]); + } + } + /* shift rows */ +// for(i=1;i<8; ++i){ +// shiftrow(&(tmp[i][0]), i); +// } + /* mix columns */ + for( i=0; i<8; i++ ){ + // multiply with mds matrix + for( j=0; j<8; j++ ){ + k=(i+1)&7; + ctx->s[j][i] = + MULT( MDS(j,0), tmp[0][i] ) ^ + MULT( MDS(j,1), tmp[1][k] ) ^ + MULT( MDS(j,2), tmp[2][(++k)&7] ) ^ + MULT( MDS(j,3), tmp[3][(++k)&7] ) ^ + MULT( MDS(j,4), tmp[4][(++k)&7] ) ^ + MULT( MDS(j,5), tmp[5][(++k)&7] ) ^ + MULT( MDS(j,6), tmp[6][(++k)&7] ) ^ + MULT( MDS(j,7), tmp[7][(++k)&7] ) ; + + } + } + DEBUG_PRINT(ctx, "post MDS"); +} + +void twister_mini_round(twister_state_t* ctx, void* msg){ + /* inject message */ + uint8_t i; + for(i=0; i<8; ++i){ + ctx->s[7][7-i] ^= *((uint8_t*)msg); + msg = (uint8_t*)msg +1; + } + twister_blank_round(ctx); +} +#if 0 +void twister_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b){ + uint8_t tmp[8][8]; + uint8_t j; + uint16_t i=hashsize_b; + while(i>=64){ + i-=64; + memcpy(tmp,ctx->s, 64); + twister_blank_round(ctx); + memxor(ctx->s, tmp, 64); + twister_blank_round(ctx); + for(j=0; j<8; ++j){ + *((uint8_t*)dest) = ctx->s[7-j][0] ^ tmp[7-j][0]; + dest = (uint8_t*)dest + 1; + } + } + if(i>=32){ + memcpy(tmp,ctx->s, 64); + twister_blank_round(ctx); + memxor(ctx->s, tmp, 64); + twister_blank_round(ctx); + for(j=0; j<4; ++j){ + *((uint8_t*)dest) = ctx->s[3-j][0] ^ tmp[3-j][0]; + dest = (uint8_t*)dest + 1; + } + } +} + +#endif diff --git a/twister.c b/twister.c index f57ca32..af82c13 100644 --- a/twister.c +++ b/twister.c @@ -72,43 +72,47 @@ void shiftrow(void* row, uint8_t shift){ *((uint64_t*)row) = *((uint64_t*)row)>>(8*shift) | *((uint64_t*)row)<<(64-8*shift); } -#define MDS(a,b) pgm_read_byte(&(twister_mds[a][b])) +#define MDS(a,b) pgm_read_byte(&(twister_mds[(a)][(b)])) #ifdef TWISTER_MUL_TABLE # define MULT(a,b) pgm_read_byte(&(twister_multab[a][b])) #else -# define MULT(a,b) gf256mul(a,b, 0x4D) +# define MULT(a,b) gf256mul((a),(b), 0x4D) #endif void twister_blank_round(twister_state_t* ctx){ - uint8_t i,j; + uint8_t i,j,k=0; uint8_t tmp[8][8]; DEBUG_PRINT(ctx, "blank init"); /* add twist counter */ - for(i=0; i<8; ++i) + for(i=0; i<8; ++i){ ctx->s[i][1] ^= ((uint8_t*)&(ctx->counter))[7-i]; + } ctx->counter--; // DEBUG_PRINT(ctx, "counter added"); /* sub bytes */ - for(i=0; i<8; ++i) - for(j=0;j<8;++j) + for(i=0; i<8; ++i){ + for(j=0;j<8;++j){ tmp[i][j] = pgm_read_byte(twister_sbox+ctx->s[i][j]); - /* shift rows */ - for(i=1;i<8; ++i){ - shiftrow(&(tmp[i][0]), i); + } } + /* shift rows */ +// for(i=1;i<8; ++i){ +// shiftrow(&(tmp[i][0]), i); +// } /* mix columns */ for( i=0; i<8; i++ ){ // multiply with mds matrix for( j=0; j<8; j++ ){ + k=(i+1)&7; ctx->s[j][i] = MULT( MDS(j,0), tmp[0][i] ) ^ - MULT( MDS(j,1), tmp[1][i] ) ^ - MULT( MDS(j,2), tmp[2][i] ) ^ - MULT( MDS(j,3), tmp[3][i] ) ^ - MULT( MDS(j,4), tmp[4][i] ) ^ - MULT( MDS(j,5), tmp[5][i] ) ^ - MULT( MDS(j,6), tmp[6][i] ) ^ - MULT( MDS(j,7), tmp[7][i] ) ; + MULT( MDS(j,1), tmp[1][k] ) ^ + MULT( MDS(j,2), tmp[2][(++k)&7] ) ^ + MULT( MDS(j,3), tmp[3][(++k)&7] ) ^ + MULT( MDS(j,4), tmp[4][(++k)&7] ) ^ + MULT( MDS(j,5), tmp[5][(++k)&7] ) ^ + MULT( MDS(j,6), tmp[6][(++k)&7] ) ^ + MULT( MDS(j,7), tmp[7][(++k)&7] ) ; } } diff --git a/twister224.S b/twister224.S new file mode 100644 index 0000000..60c7864 --- /dev/null +++ b/twister224.S @@ -0,0 +1,98 @@ +/* twister224.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister224.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-28 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" +/*********************************************************************/ +/* void twister224(void* dest, void* msg, uint32_t msg_length_b) */ +/* + * param dest: r24:r25 + * param msg: r22:r23 + * param msg_length_b: r18:r21 + */ + +CTX_SAVE0 = 10 +CTX_SAVE1 = 11 +DST_SAVE0 = 14 +DST_SAVE1 = 15 +MSG_LEN0 = 16 +MSG_LEN1 = 17 +MSG_LEN2 = 12 +MSG_LEN3 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 + +.global twister224 +twister224: + push_range 10, 17 + push r28 + push r29 + stack_alloc_large 64+2*8 + adiw r30, 1 + movw CTX_SAVE0, r30 + movw DST_SAVE0, r24 + movw MSG_SAVE0, r22 + movw MSG_LEN0, r18 + movw MSG_LEN2, r20 + movw r24, CTX_SAVE0 + ldi r22, lo8(224) + ldi r23, hi8(224) + rcall twister_small_init +1: + tst MSG_LEN3 + brne 2f + tst MSG_LEN2 + brne 2f + cpi MSG_LEN1, 2 + brmi 3f +2: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_small_nextBlock + adiw MSG_SAVE0, 63 + adiw MSG_SAVE0, 1 + subi MSG_LEN1, 2 + sbc MSG_LEN2, r1 + sbc MSG_LEN3, r1 + rjmp 1b +3: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + movw r20, MSG_LEN0 + rcall twister_small_lastBlock + + movw r24, DST_SAVE0 + movw r22, CTX_SAVE0 + ldi r20, lo8(224) + ldi r21, hi8(224) + rcall twister_small_ctx2hash + + stack_free_large 64+2*8 + pop r29 + pop r28 + pop_range 10, 17 + ret + diff --git a/twister256.S b/twister256.S new file mode 100644 index 0000000..eaadd5d --- /dev/null +++ b/twister256.S @@ -0,0 +1,99 @@ +/* twister256.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister256.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-28 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" +/*********************************************************************/ +/* void twister256(void* dest, void* msg, uint32_t msg_length_b) */ +/* + * param dest: r24:r25 + * param msg: r22:r23 + * param msg_length_b: r18:r21 + */ + +CTX_SAVE0 = 10 +CTX_SAVE1 = 11 +DST_SAVE0 = 14 +DST_SAVE1 = 15 +MSG_LEN0 = 16 +MSG_LEN1 = 17 +MSG_LEN2 = 12 +MSG_LEN3 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 + +.global twister256 +twister256: + push_range 10, 17 + push r28 + push r29 + stack_alloc_large 64+2*8 + adiw r30, 1 + movw CTX_SAVE0, r30 + movw DST_SAVE0, r24 + movw MSG_SAVE0, r22 + movw MSG_LEN0, r18 + movw MSG_LEN2, r20 + movw r24, CTX_SAVE0 + ldi r22, lo8(256) + ldi r23, hi8(256) + rcall twister_small_init +1: + tst MSG_LEN3 + brne 2f + tst MSG_LEN2 + brne 2f + cpi MSG_LEN1, 2 + brmi 3f +2: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_small_nextBlock + adiw MSG_SAVE0, 63 + adiw MSG_SAVE0, 1 + subi MSG_LEN1, 2 + sbc MSG_LEN2, r1 + sbc MSG_LEN3, r1 + rjmp 1b +3: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + movw r20, MSG_LEN0 + rcall twister_small_lastBlock + + movw r24, DST_SAVE0 + movw r22, CTX_SAVE0 + ldi r20, lo8(256) + ldi r21, hi8(256) + rcall twister_small_ctx2hash + + stack_free_large 64+2*8 + pop r29 + pop r28 + pop_range 10, 17 + ret + + diff --git a/twister384.S b/twister384.S new file mode 100644 index 0000000..57b04e9 --- /dev/null +++ b/twister384.S @@ -0,0 +1,97 @@ +/* twister384.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister384.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-28 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" +/*********************************************************************/ +/* void twister384(void* dest, void* msg, uint32_t msg_length_b) */ +/* + * param dest: r24:r25 + * param msg: r22:r23 + * param msg_length_b: r18:r21 + */ + +CTX_SAVE0 = 10 +CTX_SAVE1 = 11 +DST_SAVE0 = 14 +DST_SAVE1 = 15 +MSG_LEN0 = 16 +MSG_LEN1 = 17 +MSG_LEN2 = 12 +MSG_LEN3 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 + +.global twister384 +twister384: + push_range 10, 17 + push r28 + push r29 + stack_alloc_large 64+2*8+64 + adiw r30, 1 + movw CTX_SAVE0, r30 + movw DST_SAVE0, r24 + movw MSG_SAVE0, r22 + movw MSG_LEN0, r18 + movw MSG_LEN2, r20 + movw r24, CTX_SAVE0 + ldi r22, lo8(384) + ldi r23, hi8(384) + rcall twister_big_init +1: + tst MSG_LEN3 + brne 2f + tst MSG_LEN2 + brne 2f + cpi MSG_LEN1, 2 + brmi 3f +2: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_big_nextBlock + adiw MSG_SAVE0, 63 + adiw MSG_SAVE0, 1 + subi MSG_LEN1, 2 + sbc MSG_LEN2, r1 + sbc MSG_LEN3, r1 + rjmp 1b +3: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + movw r20, MSG_LEN0 + rcall twister_big_lastBlock + + movw r24, DST_SAVE0 + movw r22, CTX_SAVE0 + ldi r20, lo8(384) + ldi r21, hi8(384) + rcall twister_big_ctx2hash + + stack_free_large2 64+2*8+64 + pop r29 + pop r28 + pop_range 10, 17 + ret diff --git a/twister512.S b/twister512.S new file mode 100644 index 0000000..2952ad4 --- /dev/null +++ b/twister512.S @@ -0,0 +1,97 @@ +/* twister512.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-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 . +*/ +/** + * \file twister512.S + * \email daniel.otte@rub.de + * \author Daniel Otte + * \date 2008-12-28 + * \license GPLv3 or later + * + */ + +#include "avr-asm-macros.S" +/*********************************************************************/ +/* void twister384(void* dest, void* msg, uint32_t msg_length_b) */ +/* + * param dest: r24:r25 + * param msg: r22:r23 + * param msg_length_b: r18:r21 + */ + +CTX_SAVE0 = 10 +CTX_SAVE1 = 11 +DST_SAVE0 = 14 +DST_SAVE1 = 15 +MSG_LEN0 = 16 +MSG_LEN1 = 17 +MSG_LEN2 = 12 +MSG_LEN3 = 13 +MSG_SAVE0 = 28 +MSG_SAVE1 = 29 + +.global twister512 +twister512: + push_range 10, 17 + push r28 + push r29 + stack_alloc_large 64+2*8+64 + adiw r30, 1 + movw CTX_SAVE0, r30 + movw DST_SAVE0, r24 + movw MSG_SAVE0, r22 + movw MSG_LEN0, r18 + movw MSG_LEN2, r20 + movw r24, CTX_SAVE0 + ldi r22, lo8(512) + ldi r23, hi8(512) + rcall twister_big_init +1: + tst MSG_LEN3 + brne 2f + tst MSG_LEN2 + brne 2f + cpi MSG_LEN1, 2 + brmi 3f +2: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + rcall twister_big_nextBlock + adiw MSG_SAVE0, 63 + adiw MSG_SAVE0, 1 + subi MSG_LEN1, 2 + sbc MSG_LEN2, r1 + sbc MSG_LEN3, r1 + rjmp 1b +3: + movw r24, CTX_SAVE0 + movw r22, MSG_SAVE0 + movw r20, MSG_LEN0 + rcall twister_big_lastBlock + + movw r24, DST_SAVE0 + movw r22, CTX_SAVE0 + ldi r20, lo8(512) + ldi r21, hi8(512) + rcall twister_big_ctx2hash + + stack_free_large2 64+2*8+64 + pop r29 + pop r28 + pop_range 10, 17 + ret diff --git a/twister_ref.h b/twister_ref.h new file mode 100644 index 0000000..1a5e05a --- /dev/null +++ b/twister_ref.h @@ -0,0 +1,90 @@ +/****************************************************************** + ** Header File for the Reference Implementation of Twister + ** + ** Author: Ewan Fleischmann 2008 + ** + ** This algorithm and source code is released into the public domain. + ** + *******************************************************************/ + +#ifndef TWISTER_REF_H_ +#define TWISTER_REF_H_ + +#define DEBUG + +#define MIN(a,b) ((a)>(b)?(b):(a)) +/* state matrix has size of 8x8 BYTES i.e. 8 rows and 8 columns*/ +#define NUMROWSCOLUMNS 8 +#define STATESIZE NUMROWSCOLUMNS * NUMROWSCOLUMNS + +/* blocksize in BITS, i.e. size of an input message block for a compression function call*/ +#define BLOCKSIZE 512 + +/* unit64 def for ANSIC/GNUC <-> MSVC */ +#ifdef __GNUC__ +#include +#else +typedef unsigned __int64 uint64_t; +#endif + +/* multiplication in F_256 */ +#define MULT(a,b) (multab[a-1][b]) + +/* NIST requirements definitions */ +typedef unsigned char BitSequence; +typedef uint64_t DataLength; +typedef enum {SUCCESS=0, FAIL=1, BAD_HASHBITLEN=2 } HashReturn; +typedef enum {FULL = 0, NOT_FULL = 1 } INTERMEDIATE_RESULT; + +typedef struct { + /* statematrix[Y][X] */ + unsigned char hs_State[NUMROWSCOLUMNS][NUMROWSCOLUMNS]; + + /* matrix for checksum */ + unsigned char hs_Checksum[NUMROWSCOLUMNS][NUMROWSCOLUMNS]; + + /* Processed message bits */ + DataLength hs_ProcessedMsgLen; + + /* Unprocessed message block */ + BitSequence hs_Data[STATESIZE]; + + /* size of data hs_Data, in bits*/ + uint64_t hs_DataBitLen; + + /* Twist counter, prevents slide attacks, counts the number of twist operations */ + uint64_t hs_Counter; + + /* output hash bit length, in bits */ + uint64_t hs_HashBitLen; + +} hashState; + + +/******************************************************************/ +/************************* N I S T A P I ***********************/ +/******************************************************************/ + +/* Initiate Twister */ +HashReturn Init(hashState *state, int hashbitlen); + +/* Process the supplied data */ +HashReturn Update(hashState *state, const BitSequence *data, + DataLength databitlen); + +/* Perform any post processing and output filtering */ +HashReturn Final(hashState *state, BitSequence *hashval); + +/* Hash the supplied data and provie the resulting hash value */ +HashReturn Hash(int hashbitlen, const BitSequence *data, + DataLength databitlen, BitSequence *hashval); + + +/* only for testing */ +INTERMEDIATE_RESULT fill_intermediate_state( hashState *state, const BitSequence *data, DataLength *databitlen, DataLength *processed ); +void twist( hashState *state, uint64_t *data ); +void twist_mini_round( hashState *state ); +void checksum( hashState *state, int col ); + + +#endif /* TWISTER_REF_H_ */