twister now in ASM

This commit is contained in:
bg 2008-12-28 20:20:22 +00:00
parent 0076b72ccd
commit 288c82e97b
28 changed files with 2514 additions and 38 deletions

View File

@ -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
/*******************************************************************************

View File

@ -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

View File

@ -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"

12
mkfiles/twister224_c.mk Normal file
View File

@ -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"

View File

@ -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"

12
mkfiles/twister256_c.mk Normal file
View File

@ -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"

12
mkfiles/twister384.mk Normal file
View File

@ -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"

12
mkfiles/twister384_c.mk Normal file
View File

@ -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"

View File

@ -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"

12
mkfiles/twister512_c.mk Normal file
View File

@ -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"

View File

@ -30,6 +30,8 @@
#include "nessie_hash_test.h"
#include "performance_test.h"
#include <util/delay.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
@ -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"));
}

View File

@ -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
}

View File

@ -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 <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");
}
}

View File

@ -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
}

604
twister-asm.S Normal file
View File

@ -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 <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

513
twister-big-asm.S Normal file
View File

@ -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 <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

View File

@ -9,6 +9,9 @@
#undef DEBUG
#define DEBUG
/*********************************************************************/
/*********************************************************************/
#ifdef DEBUG
#include <avr/pgmspace.h>
#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);

View File

@ -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);

206
twister-small-asm.S Normal file
View File

@ -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 <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

167
twister-small-stub.c Normal file
View File

@ -0,0 +1,167 @@
/* 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

View File

@ -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);
}

159
twister-stub.c Normal file
View File

@ -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 <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

View File

@ -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] ) ;
}
}

98
twister224.S Normal file
View File

@ -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 <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

99
twister256.S Normal file
View File

@ -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 <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

97
twister384.S Normal file
View File

@ -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 <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

97
twister512.S Normal file
View File

@ -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 <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

90
twister_ref.h Normal file
View File

@ -0,0 +1,90 @@
/******************************************************************
** 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_ */