From: bg Date: Sun, 10 Aug 2008 14:04:06 +0000 (+0000) Subject: advances in serpent asm implementation X-Git-Url: https://git.cryptolib.org/?a=commitdiff_plain;h=c1553054f9455c2f88d6b3cb44de1cc25674a528;p=avr-crypto-lib.git advances in serpent asm implementation --- diff --git a/avr-makefile.inc b/avr-makefile.inc index abe498f..3ecc159 100644 --- a/avr-makefile.inc +++ b/avr-makefile.inc @@ -16,10 +16,10 @@ TESTLOG_DIR = testlog/ TESTPREFIX = nessie- CC = avr-gcc -override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.c,%.d,$(patsubst $(TESTSRC_DIR)%,%,$<)) -I. -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) +override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.c,%.d,$(patsubst $(TESTSRC_DIR)%,%,$<)) -I. -gdwarf-2 -pedantic -std=c99 -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) -override LDFLAGS = -Wl,-Map, -override ASFLAGS = -mmcu=$(MCU_TARGET) +override LDFLAGS = -gdwarf-2 -Wl,-Map, +override ASFLAGS = -mmcu=$(MCU_TARGET) -gdwarf-2 SIZESTAT_FILE = sizestats.txt diff --git a/memxor.S b/memxor.S index 0e04198..2e82237 100644 --- a/memxor.S +++ b/memxor.S @@ -20,9 +20,9 @@ /* * File: memxor.S * Author: Daniel Otte - * Date: 2006-07-06 + * Date: 2008-08-07 * License: GPLv3 or later - * Description: Implementation of the ARCFOUR (RC4 compatible) stream cipher algorithm. + * Description: memxor, XORing one block into another * */ diff --git a/mkfiles/serpent.mk b/mkfiles/serpent.mk deleted file mode 100644 index 5959aea..0000000 --- a/mkfiles/serpent.mk +++ /dev/null @@ -1,13 +0,0 @@ -# Makefile for serpent -ALGO_NAME := SERPENT - -# comment out the following line for removement of serpent from the build process -BLOCK_CIPHERS += $(ALGO_NAME) - - -$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes.o memxor.o -$(ALGO_NAME)_TEST_BIN := main-serpent-test.o debug.o uart.o serial-tools.o \ - nessie_bc_test.o nessie_common.o cli.o performance_test.o -$(ALGO_NAME)_NESSIE_TEST := "nessie" -$(ALGO_NAME)_PEROFRMANCE_TEST := "performance" - diff --git a/mkfiles/serpent_asm_fast.mk b/mkfiles/serpent_asm_fast.mk new file mode 100644 index 0000000..45070aa --- /dev/null +++ b/mkfiles/serpent_asm_fast.mk @@ -0,0 +1,13 @@ +# Makefile for serpent +ALGO_NAME := SERPENT_ASM_FAST + +# comment out the following line for removement of serpent from the build process +BLOCK_CIPHERS += $(ALGO_NAME) + + +$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes-fast.o memxor.o +$(ALGO_NAME)_TEST_BIN := main-serpent-test.o debug.o uart.o serial-tools.o \ + nessie_bc_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PEROFRMANCE_TEST := "performance" + diff --git a/mkfiles/serpent_asm_small.mk b/mkfiles/serpent_asm_small.mk new file mode 100644 index 0000000..c37017b --- /dev/null +++ b/mkfiles/serpent_asm_small.mk @@ -0,0 +1,13 @@ +# Makefile for serpent +ALGO_NAME := SERPENT_ASM_SMALL + +# comment out the following line for removement of serpent from the build process +BLOCK_CIPHERS += $(ALGO_NAME) + + +$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes-small.o memxor.o +$(ALGO_NAME)_TEST_BIN := main-serpent-test.o debug.o uart.o serial-tools.o \ + nessie_bc_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PEROFRMANCE_TEST := "performance" + diff --git a/mkfiles/serpent_c.mk b/mkfiles/serpent_c.mk new file mode 100644 index 0000000..11291b9 --- /dev/null +++ b/mkfiles/serpent_c.mk @@ -0,0 +1,13 @@ +# Makefile for serpent +ALGO_NAME := SERPENT_C + +# comment out the following line for removement of serpent from the build process +BLOCK_CIPHERS += $(ALGO_NAME) + + +$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes_c.o memxor.o +$(ALGO_NAME)_TEST_BIN := main-serpent-test.o debug.o uart.o serial-tools.o \ + nessie_bc_test.o nessie_common.o cli.o performance_test.o +$(ALGO_NAME)_NESSIE_TEST := "nessie" +$(ALGO_NAME)_PEROFRMANCE_TEST := "performance" + diff --git a/serpent-sboxes-fast.S b/serpent-sboxes-fast.S new file mode 100644 index 0000000..d3756df --- /dev/null +++ b/serpent-sboxes-fast.S @@ -0,0 +1,289 @@ +/* serpent-sboxes-fast.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-lib. + Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * File: serpent-sboxes-fast.S + * Author: Daniel Otte + * Date: 2008-08-07 + * License: GPLv3 or later + * Description: Implementation of the serpent sbox function. + * + */ + +#include + +/******************************************************************************* +* MACRO SECTION * +*******************************************************************************/ + +.macro push_ p1:req, p2:vararg + push \p1 +.ifnb \p2 + push_ \p2 +.endif +.endm + +.macro pop_ p1:req, p2:vararg + pop \p1 +.ifnb \p2 + pop_ \p2 +.endif +.endm + +.macro push_range from:req, to:req + push \from +.if \to-\from + push_range "(\from+1)",\to +.endif +.endm + +.macro pop_range from:req, to:req + pop \to +.if \to-\from + pop_range \from,"(\to-1)" +.endif +.endm + +.macro stack_alloc size:req, reg1=r30, reg2=r31 + in r0, _SFR_IO_ADDR(SREG) + cli + in \reg1, _SFR_IO_ADDR(SPL) + in \reg2, _SFR_IO_ADDR(SPH) + sbiw \reg1, \size + out _SFR_IO_ADDR(SPH), \reg2 + out _SFR_IO_ADDR(SPL), \reg1 + out _SFR_IO_ADDR(SREG), r0 +.endm + +.macro stack_free size:req, reg1=r30, reg2=r31 + in r0, _SFR_IO_ADDR(SREG) + cli + in \reg1, _SFR_IO_ADDR(SPL) + in \reg2, _SFR_IO_ADDR(SPH) + adiw \reg1, \size + out _SFR_IO_ADDR(SPH), \reg2 + out _SFR_IO_ADDR(SPL), \reg1 + out _SFR_IO_ADDR(SREG), r0 +.endm + +/******************************************************************************* +* END of MACRO SECTION * +*******************************************************************************/ + +serpent_sbox_fast: + .byte 0x33, 0x88, 0xFF, 0x11, 0xAA, 0x66, 0x55, 0xBB + .byte 0xEE, 0xDD, 0x44, 0x22, 0x77, 0x00, 0x99, 0xCC + .byte 0xFF, 0xCC, 0x22, 0x77, 0x99, 0x00, 0x55, 0xAA + .byte 0x11, 0xBB, 0xEE, 0x88, 0x66, 0xDD, 0x33, 0x44 + .byte 0x88, 0x66, 0x77, 0x99, 0x33, 0xCC, 0xAA, 0xFF + .byte 0xDD, 0x11, 0xEE, 0x44, 0x00, 0xBB, 0x55, 0x22 + .byte 0x00, 0xFF, 0xBB, 0x88, 0xCC, 0x99, 0x66, 0x33 + .byte 0xDD, 0x11, 0x22, 0x44, 0xAA, 0x77, 0x55, 0xEE + .byte 0x11, 0xFF, 0x88, 0x33, 0xCC, 0x00, 0xBB, 0x66 + .byte 0x22, 0x55, 0x44, 0xAA, 0x99, 0xEE, 0x77, 0xDD + .byte 0xFF, 0x55, 0x22, 0xBB, 0x44, 0xAA, 0x99, 0xCC + .byte 0x00, 0x33, 0xEE, 0x88, 0xDD, 0x66, 0x77, 0x11 + .byte 0x77, 0x22, 0xCC, 0x55, 0x88, 0x44, 0x66, 0xBB + .byte 0xEE, 0x99, 0x11, 0xFF, 0xDD, 0x33, 0xAA, 0x00 + .byte 0x11, 0xDD, 0xFF, 0x00, 0xEE, 0x88, 0x22, 0xBB + .byte 0x77, 0x44, 0xCC, 0xAA, 0x99, 0x33, 0x55, 0x66 + +serpent_sbox_inv_fast: + .byte 0xDD, 0x33, 0xBB, 0x00, 0xAA, 0x66, 0x55, 0xCC + .byte 0x11, 0xEE, 0x44, 0x77, 0xFF, 0x99, 0x88, 0x22 + .byte 0x55, 0x88, 0x22, 0xEE, 0xFF, 0x66, 0xCC, 0x33 + .byte 0xBB, 0x44, 0x77, 0x99, 0x11, 0xDD, 0xAA, 0x00 + .byte 0xCC, 0x99, 0xFF, 0x44, 0xBB, 0xEE, 0x11, 0x22 + .byte 0x00, 0x33, 0x66, 0xDD, 0x55, 0x88, 0xAA, 0x77 + .byte 0x00, 0x99, 0xAA, 0x77, 0xBB, 0xEE, 0x66, 0xDD + .byte 0x33, 0x55, 0xCC, 0x22, 0x44, 0x88, 0xFF, 0x11 + .byte 0x55, 0x00, 0x88, 0x33, 0xAA, 0x99, 0x77, 0xEE + .byte 0x22, 0xCC, 0xBB, 0x66, 0x44, 0xFF, 0xDD, 0x11 + .byte 0x88, 0xFF, 0x22, 0x99, 0x44, 0x11, 0xDD, 0xEE + .byte 0xBB, 0x66, 0x55, 0x33, 0x77, 0xCC, 0xAA, 0x00 + .byte 0xFF, 0xAA, 0x11, 0xDD, 0x55, 0x33, 0x66, 0x00 + .byte 0x44, 0x99, 0xEE, 0x77, 0x22, 0xCC, 0x88, 0xBB + .byte 0x33, 0x00, 0x66, 0xDD, 0x99, 0xEE, 0xFF, 0x88 + .byte 0x55, 0xCC, 0xBB, 0x77, 0xAA, 0x11, 0x44, 0x22 + + +/* + * void ip(uint32_t *i, uint8_t *o){ + */ +/* + * param i is given in r24:r25 + * parma o is given in r22:r23 + */ +.global serpent_ip +serpent_ip: + push_range 2, 17 + movw r26, r24 + ldi r24, 16 + clr r31 + ldi r30, 2 +1: + ld r25, X+ + st Z+, r25 + dec r24 + brne 1b + /* now the whole input is loaded in r2-r18 */ + movw r26, r22 + ldi r21, 4 +4: + ldi r20, 8 +2: + lsr r2 + ror r19 + lsr r6 + ror 19 + lsr r10 + ror r19 + lsr r14 + ror 19 + sbrc r20, 0 + st X+, r19 + dec r20 + brne 2b + + ldi r20, 15 + ldi r30, 2 +3: + ldd r19, Z+1 + st Z+, r19 + dec r20 + brne 3b + + dec r21 + brne 4b + pop_range 2, 17 + ret + +/* + * void serpent_fp(uint32_t *i, uint8_t *o){ + */ +/* + * param i is given in r24:r25 + * parma o is given in r22:r23 + */ +.global serpent_fp +serpent_fp: + movw r26, r24 + movw r30, r22 + ldi r18, 4 +1: + ldi r19, 8 +2: + sbrs r19, 0 + ld r24, X+ +3: + lsr r24 + ror r20 + lsr r24 + ror r21 + lsr r24 + ror r22 + lsr r24 + ror r23 + dec r19 + brne 2b + + st Z+, r20 + std Z+3, r21 + std Z+7, r22 + std Z+11, r23 + + dec r18 + brne 1b + ret + + +/* + * void inv_sbox128(void * w, uint8_t box) + */ +.global inv_sbox128 +inv_sbox128: + andi r22, 0x07 + ori r22, 0x08 + rjmp sbox128x_fast + +/* + * void sbox128(void * w, uint8_t box); + */ +/* + * param w is passed in r24:r25 + * param box is passed in r22 + */ +.global sbox128 +sbox128: + andi r22, 0x07 + +sbox128x_fast: + stack_alloc 16 + adiw r30, 1 + push_ r24, r25, r22, r30, r31 + movw r22, r30 /* Z points to the stack buffer */ + rcall serpent_ip + pop_ r27, r26, r22 + ldi r25, hi8(serpent_sbox_fast) + ldi r24, lo8(serpent_sbox_fast) + swap r22 /* r22 *= 16 */ + add r24, r22 + adc r25, r1 + /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */ + ldi r22, 16 +1: + movw r30, r24 + ld r18, X + mov r20, r18 + andi r18, 0x0f + add r30, r18 + adc r31, r1 + lpm r19, Z +2: + swap r20 + andi r20, 0x0f + movw r30, r24 + add r30, r20 + adc r31, r1 + lpm r21, Z +3: + andi r19, 0x0F + andi r21, 0xF0 + or r19, r21 + st X+, r19 + dec r22 + brne 1b + + pop_ r23, r22 + movw r24, r26 + sbiw r24, 16 + + rcall serpent_fp + + stack_free 16 + ret + + + + + + + + + diff --git a/serpent-sboxes-small.S b/serpent-sboxes-small.S new file mode 100644 index 0000000..cc9da3c --- /dev/null +++ b/serpent-sboxes-small.S @@ -0,0 +1,286 @@ +/* serpent_sboxes.S */ +/* + This file is part of the Crypto-avr-lib/microcrypt-lib. + Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * File: serpent_sboxes.S + * Author: Daniel Otte + * Date: 2008-08-07 + * License: GPLv3 or later + * Description: Implementation of the serpent sbox function. + * + */ + +#include + +/******************************************************************************* +* MACRO SECTION * +*******************************************************************************/ + +.macro push_ p1:req, p2:vararg + push \p1 +.ifnb \p2 + push_ \p2 +.endif +.endm + +.macro pop_ p1:req, p2:vararg + pop \p1 +.ifnb \p2 + pop_ \p2 +.endif +.endm + +.macro push_range from:req, to:req + push \from +.if \to-\from + push_range "(\from+1)",\to +.endif +.endm + +.macro pop_range from:req, to:req + pop \to +.if \to-\from + pop_range \from,"(\to-1)" +.endif +.endm + +.macro stack_alloc size:req, reg1=r30, reg2=r31 + in r0, _SFR_IO_ADDR(SREG) + cli + in \reg1, _SFR_IO_ADDR(SPL) + in \reg2, _SFR_IO_ADDR(SPH) + sbiw \reg1, \size + out _SFR_IO_ADDR(SPH), \reg2 + out _SFR_IO_ADDR(SPL), \reg1 + out _SFR_IO_ADDR(SREG), r0 +.endm + +.macro stack_free size:req, reg1=r30, reg2=r31 + in r0, _SFR_IO_ADDR(SREG) + cli + in \reg1, _SFR_IO_ADDR(SPL) + in \reg2, _SFR_IO_ADDR(SPH) + adiw \reg1, \size + out _SFR_IO_ADDR(SPH), \reg2 + out _SFR_IO_ADDR(SPL), \reg1 + out _SFR_IO_ADDR(SREG), r0 +.endm + +/******************************************************************************* +* END of MACRO SECTION * +*******************************************************************************/ +serpent_sbox: + .byte 0x83, 0x1F, 0x6A, 0xB5, 0xDE, 0x24, 0x07, 0xC9 + .byte 0xCF, 0x72, 0x09, 0xA5, 0xB1, 0x8E, 0xD6, 0x43 + .byte 0x68, 0x97, 0xC3, 0xFA, 0x1D, 0x4E, 0xB0, 0x25 + .byte 0xF0, 0x8B, 0x9C, 0x36, 0x1D, 0x42, 0x7A, 0xE5 + .byte 0xF1, 0x38, 0x0C, 0x6B, 0x52, 0xA4, 0xE9, 0xD7 + .byte 0x5F, 0xB2, 0xA4, 0xC9, 0x30, 0x8E, 0x6D, 0x17 + .byte 0x27, 0x5C, 0x48, 0xB6, 0x9E, 0xF1, 0x3D, 0x0A + .byte 0xD1, 0x0F, 0x8E, 0xB2, 0x47, 0xAC, 0x39, 0x65 + +serpent_sbox_inv: + .byte 0x3D, 0x0B, 0x6A, 0xC5, 0xE1, 0x74, 0x9F, 0x28 + .byte 0x85, 0xE2, 0x6F, 0x3C, 0x4B, 0x97, 0xD1, 0x0A + .byte 0x9C, 0x4F, 0xEB, 0x21, 0x30, 0xD6, 0x85, 0x7A + .byte 0x90, 0x7A, 0xEB, 0xD6, 0x53, 0x2C, 0x84, 0x1F + .byte 0x05, 0x38, 0x9A, 0xE7, 0xC2, 0x6B, 0xF4, 0x1D + .byte 0xF8, 0x92, 0x14, 0xED, 0x6B, 0x35, 0xC7, 0x0A + .byte 0xAF, 0xD1, 0x35, 0x06, 0x94, 0x7E, 0xC2, 0xB8 + .byte 0x03, 0xD6, 0xE9, 0x8F, 0xC5, 0x7B, 0x1A, 0x24 + +/* + * void ip(uint32_t *i, uint8_t *o){ + */ +/* + * param i is given in r24:r25 + * parma o is given in r22:r23 + */ +.global serpent_ip +serpent_ip: + push_range 2, 17 + movw r26, r24 + ldi r24, 16 + clr r31 + ldi r30, 2 +1: + ld r25, X+ + st Z+, r25 + dec r24 + brne 1b + /* now the whole input is loaded in r2-r18 */ + movw r26, r22 + ldi r21, 4 +4: + ldi r20, 8 +2: + lsr r2 + ror r19 + lsr r6 + ror 19 + lsr r10 + ror r19 + lsr r14 + ror 19 + sbrc r20, 0 + st X+, r19 + dec r20 + brne 2b + + ldi r20, 15 + ldi r30, 2 +3: + ldd r19, Z+1 + st Z+, r19 + dec r20 + brne 3b + + dec r21 + brne 4b + pop_range 2, 17 + ret + +/* + * void serpent_fp(uint32_t *i, uint8_t *o){ + */ +/* + * param i is given in r24:r25 + * parma o is given in r22:r23 + */ +.global serpent_fp +serpent_fp: + movw r26, r24 + movw r30, r22 + ldi r18, 4 +1: + ldi r19, 8 +2: + sbrs r19, 0 + ld r24, X+ +3: + lsr r24 + ror r20 + lsr r24 + ror r21 + lsr r24 + ror r22 + lsr r24 + ror r23 + dec r19 + brne 2b + + st Z+, r20 + std Z+3, r21 + std Z+7, r22 + std Z+11, r23 + + dec r18 + brne 1b + + ret +/* + * void inv_sbox128(void * w, uint8_t box) + */ +.global inv_sbox128 +inv_sbox128: + andi r22, 0x07 + ori r22, 0x08 + rjmp sbox128x + +/* + * void sbox128(void * w, uint8_t box); + */ +/* + * param w is passed in r24:r25 + * param box is passed in r22 + */ +.global sbox128 +sbox128: + andi r22, 0x07 + +/* + * void sbox128x(void * w, uint8_t box); + */ +/* + * param w is passed in r24:r25 + * param box is passed in r22 + */ + +.global sbox128x +sbox128x: + stack_alloc 16 + adiw r30, 1 + push_ r24, r25, r22, r30, r31 + movw r22, r30 /* Z points to the stack buffer */ + rcall serpent_ip + pop_ r27, r26, r22 + ldi r25, hi8(serpent_sbox) + ldi r24, lo8(serpent_sbox) + swap r22 + lsr r22 /* r22 *= 8 */ + add r24, r22 + adc r25, r1 + /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */ + ldi r22, 16 +1: + movw r30, r24 + ld r18, X + mov r20, r18 + andi r18, 0x0f + bst r18, 0 + lsr r18 + add r30, r18 + adc r31, r1 + lpm r19, Z + brtc 2f + swap r19 +2: + swap r20 + andi r20, 0x0f + bst r20, 0 + lsr r20 + movw r30, r24 + add r30, r20 + adc r31, r1 + lpm r21, Z + brts 3f + swap r21 +3: + andi r19, 0x0F + andi r21, 0xF0 + or r19, r21 + st X+, r19 + dec r22 + brne 1b + + pop_ r23, r22 + movw r24, r26 + sbiw r24, 16 + + rcall serpent_fp + + stack_free 16 + ret + + + + + + + diff --git a/serpent-sboxes.c b/serpent-sboxes.c deleted file mode 100644 index 3898f43..0000000 --- a/serpent-sboxes.c +++ /dev/null @@ -1,126 +0,0 @@ -/* serpent-sboxes.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 . -*/ -/* serpent-sboxes.c - * a non-bitsliced implementation of the serpent sboxes - * author: Daniel Otte - * email: daniel.otte@rub.de - * license: GPLv3 - */ - -#include -#include /* memset() */ -#include -#include "serpent-sboxes.h" - -uint8_t sbox[] PROGMEM = { - 0x38, 0xF1, 0xA6, 0x5B, 0xED, 0x42, 0x70, 0x9C, - 0xFC, 0x27, 0x90, 0x5A, 0x1B, 0xE8, 0x6D, 0x34, - 0x86, 0x79, 0x3C, 0xAF, 0xD1, 0xE4, 0x0B, 0x52, - 0x0F, 0xB8, 0xC9, 0x63, 0xD1, 0x24, 0xA7, 0x5E, - 0x1F, 0x83, 0xC0, 0xB6, 0x25, 0x4A, 0x9E, 0x7D, - 0xF5, 0x2B, 0x4A, 0x9C, 0x03, 0xE8, 0xD6, 0x71, - 0x72, 0xC5, 0x84, 0x6B, 0xE9, 0x1F, 0xD3, 0xA0, - 0x1D, 0xF0, 0xE8, 0x2B, 0x74, 0xCA, 0x93, 0x56, -/* now the inverted sboxes */ - 0xD3, 0xB0, 0xA6, 0x5C, 0x1E, 0x47, 0xF9, 0x82, - 0x58, 0x2E, 0xF6, 0xC3, 0xB4, 0x79, 0x1D, 0xA0, - 0xC9, 0xF4, 0xBE, 0x12, 0x03, 0x6D, 0x58, 0xA7, - 0x09, 0xA7, 0xBE, 0x6D, 0x35, 0xC2, 0x48, 0xF1, - 0x50, 0x83, 0xA9, 0x7E, 0x2C, 0xB6, 0x4F, 0xD1, - 0x8F, 0x29, 0x41, 0xDE, 0xB6, 0x53, 0x7C, 0xA0, - 0xFA, 0x1D, 0x53, 0x60, 0x49, 0xE7, 0x2C, 0x8B, - 0x30, 0x6D, 0x9E, 0xF8, 0x5C, 0xB7, 0xA1, 0x42 -}; - - -#define SHR_O(a) c=(a)&1; ((a) = (a)>>1) -#define SHR_I(a) ((a) = (c?0x80:0x00)| ((a)>>1)) - -static void ip(uint8_t *o, uint32_t *i){ - uint8_t c; // carry - uint8_t n,m; - memset(o, 0, 16); - for(n=0; n<16; ++n){ - for(m=0; m<2; ++m){ - SHR_O(i[0]); - SHR_I(o[n]); - SHR_O(i[1]); - SHR_I(o[n]); - SHR_O(i[2]); - SHR_I(o[n]); - SHR_O(i[3]); - SHR_I(o[n]); - } - } -} - -#undef SHR_I -#define SHR_I(a) ((a) = (c?0x80000000L:0x00L)| ((a)>>1)) /* we use 32-bit words here */ - - -static void fp(uint32_t *o, uint32_t *i){ - uint8_t c; // carry - uint8_t n,m; - memset(o, 0, 16); - for(n=0; n<4; ++n){ - for(m=0; m<8; ++m){ - SHR_O(i[n]); - SHR_I(o[0]); - SHR_O(i[n]); - SHR_I(o[1]); - SHR_O(i[n]); - SHR_I(o[2]); - SHR_O(i[n]); - SHR_I(o[3]); - } - } -} - -/******************************************************************************/ - -static void sbox128x(uint8_t box, void* w){ - uint8_t sb[16]; - uint8_t i,t,x; - box &= 0x0f; - /* load sbox */ - for(i=0; i<8; ++i){ - t = pgm_read_byte(sbox + box*8 + i); - sb[2*i+0]=t>>4; - sb[2*i+1]=t&0xf; - } - uint8_t o[16]; - ip(o, w); - - for(i=0; i<16; ++i){ - t = ((uint8_t*)o)[i]; - x = sb[t>>4]; - x <<= 4; - x |= sb[t&0xf]; - ((uint8_t*)o)[i] = x; - } - fp(w, (uint32_t*)o); -} - -void sbox128(void * w, uint8_t box){ - sbox128x(box&0x7, w); -} - -void inv_sbox128(void * w, uint8_t box){ - sbox128x(((box&0x7)|0x8), w); -} diff --git a/serpent-sboxes_c.c b/serpent-sboxes_c.c new file mode 100644 index 0000000..5cfc706 --- /dev/null +++ b/serpent-sboxes_c.c @@ -0,0 +1,128 @@ +/* serpent-sboxes.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 . +*/ +/* serpent-sboxes.c + * a non-bitsliced implementation of the serpent sboxes + * author: Daniel Otte + * email: daniel.otte@rub.de + * license: GPLv3 + */ + +#include +#include /* memset() */ +#include +#include "serpent-sboxes.h" + +uint8_t sbox[] PROGMEM = { + 0x38, 0xF1, 0xA6, 0x5B, 0xED, 0x42, 0x70, 0x9C, + 0xFC, 0x27, 0x90, 0x5A, 0x1B, 0xE8, 0x6D, 0x34, + 0x86, 0x79, 0x3C, 0xAF, 0xD1, 0xE4, 0x0B, 0x52, + 0x0F, 0xB8, 0xC9, 0x63, 0xD1, 0x24, 0xA7, 0x5E, + 0x1F, 0x83, 0xC0, 0xB6, 0x25, 0x4A, 0x9E, 0x7D, + 0xF5, 0x2B, 0x4A, 0x9C, 0x03, 0xE8, 0xD6, 0x71, + 0x72, 0xC5, 0x84, 0x6B, 0xE9, 0x1F, 0xD3, 0xA0, + 0x1D, 0xF0, 0xE8, 0x2B, 0x74, 0xCA, 0x93, 0x56, +/* now the inverted sboxes */ + 0xD3, 0xB0, 0xA6, 0x5C, 0x1E, 0x47, 0xF9, 0x82, + 0x58, 0x2E, 0xF6, 0xC3, 0xB4, 0x79, 0x1D, 0xA0, + 0xC9, 0xF4, 0xBE, 0x12, 0x03, 0x6D, 0x58, 0xA7, + 0x09, 0xA7, 0xBE, 0x6D, 0x35, 0xC2, 0x48, 0xF1, + 0x50, 0x83, 0xA9, 0x7E, 0x2C, 0xB6, 0x4F, 0xD1, + 0x8F, 0x29, 0x41, 0xDE, 0xB6, 0x53, 0x7C, 0xA0, + 0xFA, 0x1D, 0x53, 0x60, 0x49, 0xE7, 0x2C, 0x8B, + 0x30, 0x6D, 0x9E, 0xF8, 0x5C, 0xB7, 0xA1, 0x42 +}; + + +#define SHR_O(a) c=(a)&1; ((a) = (a)>>1) +#define SHR_I(a) ((a) = (c?0x80:0x00)| ((a)>>1)) + +static void serpent_ip(uint32_t *i, uint8_t *o){ + uint8_t c; // carry + uint8_t n,m; + memset(o, 0, 16); + for(n=0; n<16; ++n){ + for(m=0; m<2; ++m){ + SHR_O(i[0]); + SHR_I(o[n]); + SHR_O(i[1]); + SHR_I(o[n]); + SHR_O(i[2]); + SHR_I(o[n]); + SHR_O(i[3]); + SHR_I(o[n]); + } + } +} + +#undef SHR_I +#define SHR_I(a) ((a) = (c?0x80000000L:0x00L)| ((a)>>1)) /* we use 32-bit words here */ + +static void serpent_fp(uint32_t *i, uint32_t *o){ + uint8_t c; // carry + uint8_t n,m; + memset(o, 0, 16); + for(n=0; n<4; ++n){ + for(m=0; m<8; ++m){ + SHR_O(i[n]); + SHR_I(o[0]); + SHR_O(i[n]); + SHR_I(o[1]); + SHR_O(i[n]); + SHR_I(o[2]); + SHR_O(i[n]); + SHR_I(o[3]); + } + } +} + +/******************************************************************************/ +static void sbox128x(uint8_t box, void* w){ + uint8_t sb[16]; + uint8_t i,t,x; + box &= 0x0f; + /* load sbox */ + for(i=0; i<8; ++i){ + t = pgm_read_byte(sbox + box*8 + i); + sb[2*i+0]=t>>4; + sb[2*i+1]=t&0xf; + } + uint8_t o[16]; + serpent_ip(w,o); + + for(i=0; i<16; ++i){ + t = ((uint8_t*)o)[i]; + x = sb[t>>4]; + x <<= 4; + x |= sb[t&0xf]; + ((uint8_t*)o)[i] = x; + } + serpent_fp((uint32_t*)o, w); +} + +void sbox128(void * w, uint8_t box){ + sbox128x(box&0x7, w); +} + + +void inv_sbox128(void * w, uint8_t box){ + sbox128x(((box&0x7)|0x8), w); +} + + + diff --git a/serpent.c b/serpent.c index 8056eb4..c90b099 100644 --- a/serpent.c +++ b/serpent.c @@ -111,28 +111,28 @@ void serpent_init(const void* key, uint16_t keysize, serpent_ctx_t* ctx){ void serpent_enc(void* buffer, const serpent_ctx_t* ctx){ uint8_t i; for(i=0; i<31; ++i){ - memxor((uint8_t*)buffer, ctx->k[i], 16); + memxor(buffer, ctx->k[i], 16); sbox128(buffer, i); lt((uint8_t*)buffer); } - memxor((uint8_t*)buffer, ctx->k[i], 16); + memxor(buffer, ctx->k[i], 16); sbox128(buffer, i); ++i; - memxor((uint8_t*)buffer, ctx->k[i], 16); + memxor(buffer, ctx->k[i], 16); } void serpent_dec(void* buffer, const serpent_ctx_t* ctx){ int8_t i=32; - memxor((uint8_t*)buffer, ctx->k[i], 16); + memxor(buffer, ctx->k[i], 16); --i; inv_sbox128(buffer, i); memxor((uint8_t*)buffer, ctx->k[i], 16); --i; for(; i>=0; --i){ - inv_lt((uint8_t*)buffer); + inv_lt(buffer); inv_sbox128(buffer, i); - memxor((uint8_t*)buffer, ctx->k[i], 16); + memxor(buffer, ctx->k[i], 16); } }