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
/*******************************************************************************
/*
* 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
# 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"
--- /dev/null
+# 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"
+
# 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"
--- /dev/null
+# 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"
+
--- /dev/null
+# 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"
+
--- /dev/null
+# 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"
+
# 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"
--- /dev/null
+# 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"
+
#include "nessie_hash_test.h"
#include "performance_test.h"
+#include <util/delay.h>
+
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
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";
}
twister224_ctx2hash(hash, &ctx);
uart_hexdump(hash, 224/8);
+#endif
}
char str[16];
uint8_t data[64];
twister_state_t ctx;
-
+ volatile uint16_t i;
calibrateTimer();
print_overhead();
ultoa((unsigned long)t, str, 10);
uart_putstr(str);
+ i=3000;
+ while(i--)
+ _delay_ms(1);
startTimer(1);
twister_small_nextBlock(&ctx, data);
ultoa((unsigned long)t, str, 10);
uart_putstr(str);
+ i=3000;
+ while(i--)
+ _delay_ms(1);
startTimer(1);
twister_small_lastBlock(&ctx, data, 0);
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();
ultoa((unsigned long)t, str, 10);
uart_putstr(str);
+ i=3000;
+ while(i--)
+ _delay_ms(1);
+
uart_putstr_P(PSTR("\r\n"));
}
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";
}
twister256_ctx2hash(hash, &ctx);
print_hash(hash);
+#endif
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/*
+ * 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 <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#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");
+ }
+}
+
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";
}
twister512_ctx2hash(hash, &ctx);
print_hash(hash);
+#endif
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
+
+
+
+
+
+
+
+
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
#undef DEBUG
#define DEBUG
+/*********************************************************************/
+/*********************************************************************/
+
#ifdef DEBUG
#include <avr/pgmspace.h>
#include "uart.h"
}
}
+/*********************************************************************/
+
void print_matrix(void* m, PGM_P s){
uint8_t i;
uart_putstr_P(PSTR("\r\n"));
}
}
+/*********************************************************************/
+
#define DEBUG_CHKSUM(a,s) print_checksum((a),PSTR(s))
#else
#define DEBUG_CHKSUM(a,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"));
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);
#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){
// 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);
ctx->state.length_counter_b = 0;
}
+/*********************************************************************/
+
void twister_big_nextBlock(twister_big_ctx_t* ctx, void* msg){
uint8_t tmp[8][8];
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){
// 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);
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);
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);
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);
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
--- /dev/null
+/* twister-small.c */
+
+#include <stdint.h>
+#include <string.h>
+#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
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;
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);
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#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
*((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] ) ;
}
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
+
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
+
+
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \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
--- /dev/null
+/******************************************************************
+ ** Header File for the Reference Implementation of Twister
+ **
+ ** Author: Ewan Fleischmann <ewan.fleischmann@uni-weimar.de> 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 <stdint.h>
+#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_ */