# author: Daniel Otte
SHELL = sh
-BLOCK_CIPHERS :=
-STREAM_CIPHERS :=
+BLOCK_CIPHERS :=
+STREAM_CIPHERS :=
HASHES :=
MACS :=
-PRNGS :=
+PRNGS :=
ENCODINGS :=
AUX :=
# we use the gnu make standard library
include gmsl
include avr-makefile.inc
+
+#-------------------------------------------------------------------------------
+# inclusion of make stubs
include mkfiles/*.mk
-ALGORITHMS = $(BLOCK_CIPHERS) $(STREAM_CIPHERS) $(HASHES) $(PRNGS) $(MACS) $(ENCODINGS) $(AUX)
+#-------------------------------------------------------------------------------
+ALGORITHMS = $(BLOCK_CIPHERS) $(STREAM_CIPHERS) $(HASHES) $(PRNGS) $(MACS) \
+ $(ENCODINGS) $(AUX)
ALGORITHMS_OBJ = $(patsubst %,%_OBJ, $(ALGORITHMS))
ALGORITHMS_TEST_BIN = $(patsubst %,%_TEST_BIN, $(ALGORITHMS))
-define OBJinBINDIR_TEMPLATE
+#-------------------------------------------------------------------------------
+# define binary object in $(BIN_DIR)$(ALGO)/<obj>
+define Assert_Template
$(1) = $(2)
endef
-$(foreach a, $(ALGORITHMS_OBJ), $(eval $(call OBJinBINDIR_TEMPLATE, $(a), $(patsubst %.o,$(BIN_DIR)%.o,$($(a))))))
-
-$(foreach a, $(ALGORITHMS_TEST_BIN), $(eval $(call OBJinBINDIR_TEMPLATE, $(a), $(patsubst %.o,$(TESTBIN_DIR)%.o,$($(a))))))
-
-
-#ALGORITHMS_TEST_BIN_IMM = $(foreach a, $(ALGORITHMS_TEST_BIN), $($(a)))
-ALGORITHMS_NESSIE_TEST = $(patsubst %,%_NESSIE_TEST, $(ALGORITHMS))
-ALGORITHMS_PERFORMANCE_TEST = $(patsubst %,%_PERORMANCE_TEST, $(ALGORITHMS))
-
-ALGORITHMS_LC = $(call lc,$(ALGORITHMS))
-
-ALGORITHMS_TEST_TARGET_ELF = $(patsubst %, $(TESTBIN_DIR)main-%-test.elf, $(ALGORITHMS_LC))
-ALGORITHMS_TEST_TARGET_HEX = $(patsubst %, $(TESTBIN_DIR)main-%-test.hex, $(ALGORITHMS_LC))
-
+$(foreach a, $(ALGORITHMS), $(eval $(call Assert_Template, \
+ $(a)_BINOBJ, \
+ $(addprefix $(BIN_DIR)$(call lc,$(a))/,$($(a)_OBJ)) \
+)))
+
+$(foreach a, $(ALGORITHMS), $(eval $(call Assert_Template, \
+ $(a)_TESTBINOBJ, \
+ $(addprefix $(BIN_DIR)$(call lc,$(a))/$(TEST_DIR),$($(a)_TEST_BIN)) \
+)))
+
+
+#$(foreach a, $(ALGORITHMS), \
+# $(if $(def $(a)_DIR), \
+# $(eval $(call Assert_Template, \
+# $(a)_DIR, \
+# . \
+# ) \
+# )) \
+#)
+#
+#$(foreach a, $(ALGORITHMS), \
+# $(if $(call seq($(strip($($(a)_DIR))),)), \
+# $(eval $(call Assert_Template, \
+# $(a)_DIR, \
+# . \
+# ) \
+# )) \
+#)
#-------------------------------------------------------------------------------
-
-all: $(foreach algo, $(ALGORITHMS), $(algo)_OBJ)
-
-#-------------------------------------------------------------------------------
-
-define MAIN_OBJ_TEMPLATE
-$(2): $(3) $(4)
- @echo "[ld] : $$@"
-# echo $$^
- @$(CC) $(CFLAGS) $(LDFLAGS)$(patsubst %.elf,%.map,$(2)) -o \
- $(2) \
- $(3) $(4) \
- $(LIBS)
+#
+### ifeq 'blafoo' ''
+### $(error no source ($(2)) for $(1) in TargetSource_Template)
+### endif
+
+define TargetSource_Template
+$(1): $(2)
+ @echo "[cc]: $(1) <-- $(2)"
+ @mkdir -p $(dir $(1))
+ @$(CC) $(CFLAGS_A) -I./$(strip $(3)) -c -o $(1) $(2)
endef
-$(foreach algo, $(ALGORITHMS), $(eval $(call MAIN_OBJ_TEMPLATE, \
- $(algo), \
- $(TESTBIN_DIR)main-$(call lc,$(algo))-test.elf, \
- $(patsubst %.o,%.o,$($(algo)_TEST_BIN)), \
- $(patsubst %.o,%.o,$($(algo)_OBJ)) )))
-
-
-
-
+$(foreach a, $(ALGORITHMS), \
+ $(foreach b, $($(a)_OBJ), \
+ $(eval $(call TargetSource_Template, \
+ $(BIN_DIR)$(call lc, $(a))/$(b), \
+ $(filter %.S %.c, $(wildcard $($(a)_DIR)$(notdir $(patsubst %.o,%,$(b))).*)), \
+ $($(a)_DIR) \
+ )) \
+ ) \
+)
+
+$(foreach a, $(ALGORITHMS), \
+ $(foreach b, $($(a)_TEST_BIN), \
+ $(eval $(call TargetSource_Template, \
+ $(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)$(b), \
+ $(if $(call sne,$(strip $(filter %.S %.c, $(wildcard $(TESTSRC_DIR)$(notdir $(patsubst %.o,%,$(b))).*))),), \
+ $(filter %.S %.c, $(wildcard $(TESTSRC_DIR)$(notdir $(patsubst %.o,%,$(b))).*)), \
+ $(filter %.S %.c, $(wildcard ./$(notdir $(patsubst %.o,%,$(b))).*))\
+ ), \
+ $($(a)_DIR) \
+ )) \
+ ) \
+)
#-------------------------------------------------------------------------------
-.PHONY: help
-help: info
-
-info:
- @echo "infos on AVR-Crypto-lib:"
- @echo " block ciphers:"
- @echo " $(BLOCK_CIPHERS)"
- @echo " stream ciphers:"
- @echo " $(STREAM_CIPHERS)"
- @echo " hash functions:"
- @echo " $(HASHES)"
- @echo " MAC functions:"
- @echo " $(MACS)"
- @echo " PRNG functions:"
- @echo " $(PRNGS)"
- @echo " encodings:"
- @echo " $(ENCODINGS)"
-# @echo " ALGORITHMS_TEST_BIN:"
-# @echo " $(ALGORITHMS_TEST_BIN)"
-# @echo " ALGORITHMS_TEST_TARGET_ELF:"
-# @echo " $(ALGORITHMS_TEST_TARGET_ELF)"
- @echo " targets:"
- @echo " all - all algorithm cores"
- @echo " cores - all algorithm cores"
- @echo " listings - all algorithm core listings"
- @echo " tests - all algorithm test programs"
- @echo " stats - all algorithm size statistics"
- @echo " blockciphers - all blockcipher cores"
- @echo " streamciphers - all streamcipher cores"
- @echo " hashes - all hash cores"
- @echo " macs - all MAC cores"
- @echo " prngs - all PRNG cores"
- @echo " all_testrun - testrun all algorithms"
- @echo " docu - build doxygen documentation"
- @echo " clean - remove a lot of builded files"
- @echo " xclean - also remove dependency files"
- @echo " *_TEST_BIN - build test program"
- @echo " *_TESTRUN - run nessie test"
- @echo " *_OBJ - build algorithm core"
- @echo " *_FLASH - flash test program"
- @echo " *_LIST - build assembler listing"
-#-------------------------------------------------------------------------------
-
-define SOURCEFILE_TEMPLATE
-$(BIN_DIR)$(1): $(2)/$(3).c
- $(CC) $(CFLAGS) -c -o $@ $<
+define MainTestElf_Template
+$(1): $(2) $(3)
+ @echo "[ld]: $(1)"
+ @$(CC) $(CFLAGS_A) $(LDFLAGS)$(patsubst %.elf,%.map,$(1)) -o \
+ $(1) \
+ $(2) $(3) \
+ $(LIBS)
endef
-#-------------------------------------------------------------------------------
-$(BIN_DIR)%.o: %.c
- @echo "[gcc]: $@"
- @$(CC) $(CFLAGS) -c -o $@ $<
-
-$(BIN_DIR)%.o: %.S
- @echo "[as] : $@"
- @$(CC) $(ASFLAGS) -c -o $@ $<
-
-$(TESTBIN_DIR)%.o: $(TESTSRC_DIR)%.c
- @echo "[gcc]: $@"
- @$(CC) $(CFLAGS) -c -o $@ $<
-
-$(TESTBIN_DIR)%.o: $(TESTSRC_DIR)%.S
- @echo "[as] : $@"
- @$(CC) $(ASFLAGS) -c -o $@ $<
-
-$(TESTBIN_DIR)%.o: %.c
- @echo "[gcc]: $@"
- @$(CC) $(CFLAGS) -c -o $@ $<
-
-$(TESTBIN_DIR)%.o: %.S
- @echo "[as] : $@"
- @$(CC) $(ASFLAGS) -c -o $@ $<
-
-
-
-%.o: %.c
- @echo "[gcc]: $@"
- @$(CC) $(CFLAGS) -c -o $@ $<
-
-%.o: %.S
- @echo "[as] : $@"
- @$(CC) $(ASFLAGS) -c -o $@ $<
+$(foreach a, $(ALGORITHMS), \
+ $(eval $(call MainTestElf_Template, \
+ $(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)main-$(call lc, $(a))-test.elf, \
+ $($(a)_BINOBJ), \
+ $($(a)_TESTBINOBJ) \
+ )) \
+)
#-------------------------------------------------------------------------------
-
-define OBJ_TEMPLATE
-$(1)_OBJ: $(2)
-# @echo " ALGO: $(1)"
-# @echo " REQ: $(2)"
-endef
-
-$(foreach algo, $(ALGORITHMS), $(eval $(call OBJ_TEMPLATE, $(algo), $($(algo)_OBJ))))
+all: $(foreach algo, $(ALGORITHMS), $($(algo)_BINOBJ))
#-------------------------------------------------------------------------------
-define TESTBIN_TEMPLATE
+define TestBin_TEMPLATE
$(1)_TEST_BIN: $(2)
endef
-$(foreach algo, $(ALGORITHMS), $(eval $(call TESTBIN_TEMPLATE, $(algo), $($(algo)_TEST_BIN))))
+$(foreach algo, $(ALGORITHMS), $(eval $(call TestBin_TEMPLATE, \
+ $(algo), \
+ $(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.elf \
+)))
#-------------------------------------------------------------------------------
-$(BLOCK_CIPHERS_OBJ): $(patsubst %,%_OBJ, $(BLOCK_CIPHERS))
-$(STREAM_CIPHERS_OBJ): $(patsubst %,%_OBJ, $(STREAM_CIPHERS))
-$(HASHES_OBJ): $(patsubst %,%_OBJ, $(HASHES))
-$(PRNGS_OBJ): $(patsubst %,%_OBJ, $(PRNGS))
-$(MACS_OBJ): $(patsubst %,%_OBJ, $(MACS))
-$(ENCODINGS_OBJ): $(patsubst %,%_OBJ, $(ENCODINGS))
-
-#-------------------------------------------------------------------------------
-
-define SIZE_TEMPLATE
-$(1)_size.txt: $(2)
- @echo "[size]: $(1)_size.txt"
- @$(SIZE) $(2) > $(1)_size.txt
-endef
-
-$(foreach algo, $(ALGORITHMS), $(eval $(call SIZE_TEMPLATE, $(STAT_DIR)$(call lc,$(algo)), $($(algo)_OBJ))))
+%.hex: %.elf
+ @echo "[objcopy]: $@"
+ @$(OBJCOPY) -j .text -j .data -O ihex $< $@
#-------------------------------------------------------------------------------
-define FLASH_TEMPLATE
+define Flash_Template
$(1)_FLASH: $(2)
@echo "[flash]: $(2)"
@$(FLASHCMD)$(call first,$(2))
endef
-$(foreach algo, $(ALGORITHMS),$(eval $(call FLASH_TEMPLATE, $(algo), $(TESTBIN_DIR)main-$(call lc,$(algo))-test.hex) ))
+$(foreach algo, $(ALGORITHMS), $(eval $(call Flash_Template, \
+ $(algo), \
+ $(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.hex \
+)))
#-------------------------------------------------------------------------------
-define TESTRUN_TEMPLATE
+.PHONY: tests
+tests: $(foreach a, $(ALGORITHMS), $(a)_TEST_BIN)
+
+#-------------------------------------------------------------------------------
+
+define TestRun_Template
$(1)_TESTRUN: $(1)_FLASH
@echo "[test]: $(1)"
- $(RUBY) $(GET_TEST) $(TESTPORT) $(TESTPORTBAUDR) 8 1 nessie $(TESTLOG_DIR)$(TESTPREFIX) $(2)
+ $(RUBY) $(GET_TEST) $(TESTPORT) $(TESTPORTBAUDR) 8 1 nessie $(TESTLOG_DIR)$(TESTPREFIX) $(2)
endef
-$(foreach algo, $(ALGORITHMS),$(eval $(call TESTRUN_TEMPLATE, $(algo), $(call lc,$(algo)) )))
+$(foreach algo, $(ALGORITHMS),$(eval $(call TestRun_Template, $(algo), $(call lc,$(algo)) )))
all_testrun: $(foreach algo, $(ALGORITHMS), $(algo)_TESTRUN)
#-------------------------------------------------------------------------------
-define TESTSPEED_TEMPLATE
-$(1)_TESTSPEED: $(1)_FLASH
- @echo "[speed]: $(1)"
- $(RUBY) $(GET_PERFORMANCE) $(TESTPORT) $(TESTPORTBAUDR) 8 1 performance $(SPEEDLOG_DIR)$(SPEEDPREFIX) $(2)
+define Obj_Template
+$(1)_OBJ: $(2)
endef
-$(foreach algo, $(ALGORITHMS),$(eval $(call TESTSPEED_TEMPLATE, $(algo), $(call lc,$(algo)) )))
-
-all_testspeed: $(foreach algo, $(ALGORITHMS), $(algo)_TESTSPEED)
-hash_testspeed: $(foreach algo, $(HASHES), $(algo)_TESTSPEED)
+$(foreach algo, $(ALGORITHMS), \
+ $(eval $(call Obj_Template, \
+ $(algo), \
+ $($(algo)_BINOBJ)\
+ ))\
+)
+.PHONY: cores
+cores: $(foreach algo, $(ALGORITHMS), $(algo)_OBJ)
-#-------------------------------------------------------------------------------
+.PHONY: blockchiphers
+blockciphers: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_OBJ)
-define LISTING_TEMPLATE
-$(1)_LIST: $(2)
-endef
+.PHONY: streamchiphers
+streamciphers: $(foreach algo, $(STREAM_CIPHERS), $(algo)_OBJ)
-$(foreach algo, $(ALGORITHMS),$(eval $(call LISTING_TEMPLATE,$(call uc, $(algo)), \
- $(patsubst %,$(LIST_DIR)%, \
- $(patsubst $(BIN_DIR)%,%, \
- $(patsubst $(TESTBIN_DIR)%,%, \
- $(patsubst %.o,%.lst,$($(algo)_OBJ)))) ))))
+.PHONY: hashes
+hashes: $(foreach algo, $(HASHES), $(algo)_OBJ)
-listings: $(patsubst %,%_LIST,$(ALGORITHMS))
+.PHONY: macs
+macs: $(foreach algo, $(MACS), $(algo)_OBJ)
+.PHONY: prngs
+prngs: $(foreach algo, $(PRNGS), $(algo)_OBJ)
-$(LIST_DIR)%.lst: $(TESTBIN_DIR)%.elf
- $(OBJDUMP) -h -S $< > $@
+.PHONY: encodings
+encodings: $(foreach algo, $(ENCODINGS), $(algo)_OBJ)
-$(LIST_DIR)%.lst: $(BIN_DIR)%.o
- $(OBJDUMP) -h -S $< > $@
+.PHONY: aux
+aux: $(foreach algo, $(AUX), $(algo)_OBJ)
-$(LIST_DIR)%.lst: $(TESTBIN_DIR)%.o
- $(OBJDUMP) -h -S $< > $@
#-------------------------------------------------------------------------------
-.PHONY: cores
-cores: $(ALGORITHMS_OBJ)
-
-.PHONY: blockciphers
-blockciphers: $(patsubst %, %_OBJ, $(BLOCK_CIPHERS))
-
-.PHONY: streamciphers
-streamciphers: $(patsubst %, %_OBJ, $(STREAM_CIPHERS))
-
-.PHONY: hashes
-hashes: $(patsubst %, %_OBJ, $(HASHES))
-.PHONY: macs
-macs: $(patsubst %, %_OBJ, $(MACS))
-
-.PHONY: prngs
-prngs: $(patsubst %, %_OBJ, $(PRNGS))
-
-.PHONY: encodings
-encodings: $(patsubst %, %_OBJ, $(ENCODINGS))
-
-tests: $(ALGORITHMS_TEST_BIN) \
- $(ALGORITHMS_TEST_TARGET_ELF) \
- $(ALGORITHMS_TEST_TARGET_HEX)
+.PHONY: help
+help: info
+.PHONY: info
+info:
+ @echo "infos on AVR-Crypto-lib:"
+ @echo " block ciphers:"
+ @echo " $(BLOCK_CIPHERS)"
+ @echo " stream ciphers:"
+ @echo " $(STREAM_CIPHERS)"
+ @echo " hash functions:"
+ @echo " $(HASHES)"
+ @echo " MAC functions:"
+ @echo " $(MACS)"
+ @echo " PRNG functions:"
+ @echo " $(PRNGS)"
+ @echo " encodings:"
+ @echo " $(ENCODINGS)"
+ @echo " targets:"
+ @echo " all - all algorithm cores"
+ @echo " cores - all algorithm cores"
+ @echo " listings - all algorithm core listings"
+ @echo " tests - all algorithm test programs"
+ @echo " stats - all algorithm size statistics"
+ @echo " blockciphers - all blockcipher cores"
+ @echo " streamciphers - all streamcipher cores"
+ @echo " hashes - all hash cores"
+ @echo " macs - all MAC cores"
+ @echo " prngs - all PRNG cores"
+ @echo " all_testrun - testrun all algorithms"
+ @echo " docu - build doxygen documentation"
+ @echo " clean - remove a lot of builded files"
+ @echo " depclean - also remove dependency files"
+ @echo " *_TEST_BIN - build test program"
+ @echo " *_TESTRUN - run nessie test"
+ @echo " *_OBJ - build algorithm core"
+ @echo " *_FLASH - flash test program"
+ @echo " *_LIST - build assembler listing"
-.PHONY: stats
-stats: $(SIZESTAT_FILE)
- @cat $(STAT_DIR)$(SIZESTAT_FILE)
-
-$(SIZESTAT_FILE): $(patsubst %, $(STAT_DIR)%_size.txt, $(ALGORITHMS_LC))
- $(RUBY) sumsize.rb $^ > $(STAT_DIR)$(SIZESTAT_FILE)
-
-#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
.PHONY: clean
clean:
- rm -rf $(BIN_DIR)*.o *.o $(TESTBIN_DIR)*.elf $(TESTBIN_DIR)* *.elf *.eps *.png *.pdf *.bak
- rm -rf *.lst *.map $(EXTRA_CLEAN_FILES) $(STAT_DIR)$(SIZESTAT_FILE) $(STAT_DIR)*_size.txt
-xclean: clean
- rm -rf $(DEP_DIR)*.d $(AUTOASM_DIR)*.s
-
-docu:
- doxygen
+ rm -rf $(BIN_DIR)*
-make.dump: Makefile
- $(MAKE) -p -B -n -f $^ > $@
-
-make.dot: make.dump
- $(MAKE2GRAPH) $^ > $@
-
-make.png: make.dot
- $(TWOPI) -Tpng -o $@ $^
-
-make.svg: make.dot
- $(TWOPI) -Tsvg -o $@ $^
-
-.PHONY: make-info
-make-info: make.png make.svg
-
-
-# Rules for building the .text rom images
-
-%.hex: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .text -j .data -O ihex $< $@
+.PHONY: depclean
+depclean: clean
+ rm $(DEP_DIR)*.d
-%.srec: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .text -j .data -O srec $< $@
-
-%.bin: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .text -j .data -O binary $< $@
-
-# Rules for building the .eeprom rom images
-
-
-%_eeprom.hex: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
-
-%_eeprom.srec: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@
-
-%_eeprom.bin: %.elf
- @echo "[objcopy]: $@"
- @$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@
-
#-------------------------------------------------------------------------------
-$(AUTOASM_DIR)%.s: %.c
- $(CC) $(CFLAGS) $(AUTOASM_OPT) -o $@ $<
-
-%.s: %.c
- $(CC) $(CFLAGS) $(AUTOASM_OPT) -o $@ $<
-
-#-------------------------------------------------------------------------------
-FIG2DEV = fig2dev
-EXTRA_CLEAN_FILES = *.hex *.bin *.srec
-
-
-%.eps: %.fig
- $(FIG2DEV) -L eps $< $@
-
-%.pdf: %.fig
- $(FIG2DEV) -L pdf $< $@
-
-%.png: %.fig
- $(FIG2DEV) -L png $< $@
-
+# dependency inclusion
+#
DEPS := $(wildcard $(DEP_DIR)*.d)
+++ /dev/null
-/* aes.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-#ifndef AES_H_
-#define AES_H_
-
-#include <stdint.h>
-
-typedef struct{
- uint8_t ks[16];
-} aes_roundkey_t;
-
-typedef struct{
- aes_roundkey_t key[10+1];
-} aes128_ctx_t;
-
-typedef struct{
- aes_roundkey_t key[12+1];
-} aes192_ctx_t;
-
-typedef struct{
- aes_roundkey_t key[14+1];
-} aes256_ctx_t;
-
-typedef struct{
- aes_roundkey_t key[1]; /* just to avoid the warning */
-} aes_genctx_t;
-
-typedef struct{
- uint8_t s[16];
-} aes_cipher_state_t;
-
-#endif
--- /dev/null
+/* aes.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_H_
+#define AES_H_
+
+#include <stdint.h>
+
+typedef struct{
+ uint8_t ks[16];
+} aes_roundkey_t;
+
+typedef struct{
+ aes_roundkey_t key[10+1];
+} aes128_ctx_t;
+
+typedef struct{
+ aes_roundkey_t key[12+1];
+} aes192_ctx_t;
+
+typedef struct{
+ aes_roundkey_t key[14+1];
+} aes256_ctx_t;
+
+typedef struct{
+ aes_roundkey_t key[1]; /* just to avoid the warning */
+} aes_genctx_t;
+
+typedef struct{
+ uint8_t s[16];
+} aes_cipher_state_t;
+
+#endif
--- /dev/null
+/* aes128_dec.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes128_dec.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_dec.h"
+
+void aes128_dec(void* buffer, aes128_ctx_t* ctx){
+ aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 10);
+}
+
--- /dev/null
+/* aes128_dec.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes128_dec.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES128_DEC_H_
+#define AES128_DEC_H_
+
+#include "aes.h"
+#include "aes_dec.h"
+
+/** \fn void aes128_dec(void* buffer, aes128_ctx_t* ctx)
+ * \brief decrypt with 128 bit key.
+ *
+ * This function decrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 128 bit key.
+ * \param buffer pointer to the block to decrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes128_dec(void* buffer, aes128_ctx_t* ctx);
+
+
+
+#endif /* AES128_DEC_H_ */
--- /dev/null
+/* aes128_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes128_enc.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_enc.h"
+
+void aes128_enc(void* buffer, aes128_ctx_t* ctx){
+ aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 10);
+}
+
--- /dev/null
+/* aes128_enc.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes128_enc.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES128_ENC_H_
+#define AES128_ENC_H_
+
+#include "aes.h"
+#include "aes_enc.h"
+
+
+/** \fn void aes128_enc(void* buffer, aes128_ctx_t* ctx)
+ * \brief encrypt with 128 bit key.
+ *
+ * This function encrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 128 bit key.
+ * \param buffer pointer to the block to encrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes128_enc(void* buffer, aes128_ctx_t* ctx);
+
+
+
+#endif /* AES128_ENC_H_ */
--- /dev/null
+/* aes192_dec.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes192_dec.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_dec.h"
+
+void aes192_dec(void* buffer, aes192_ctx_t* ctx){
+ aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 12);
+}
+
--- /dev/null
+/* aes192_dec.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes192_dec.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES192_DEC_H_
+#define AES192_DEC_H_
+
+#include "aes.h"
+#include "aes_dec.h"
+
+/** \fn void aes192_dec(void* buffer, aes192_ctx_t* ctx)
+ * \brief decrypt with 192 bit key.
+ *
+ * This function decrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 192 bit key.
+ * \param buffer pointer to the block to decrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes192_dec(void* buffer, aes192_ctx_t* ctx);
+
+
+
+#endif /* AES192_DEC_H_ */
--- /dev/null
+/* aes192_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes192_enc.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_enc.h"
+
+void aes192_enc(void* buffer, aes192_ctx_t* ctx){
+ aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 12);
+}
+
--- /dev/null
+/* aes192_enc.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes192_enc.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES192_ENC_H_
+#define AES192_ENC_H_
+
+#include "aes.h"
+#include "aes_enc.h"
+
+
+/** \fn void aes192_enc(void* buffer, aes192_ctx_t* ctx)
+ * \brief encrypt with 192 bit key.
+ *
+ * This function encrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 192 bit key.
+ * \param buffer pointer to the block to encrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes192_enc(void* buffer, aes192_ctx_t* ctx);
+
+
+
+#endif /* AES192_ENC_H_ */
--- /dev/null
+/* aes256_dec.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes256_dec.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_dec.h"
+
+void aes256_dec(void* buffer, aes256_ctx_t* ctx){
+ aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 14);
+}
+
--- /dev/null
+/* aes256_dec.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes256_dec.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES256_DEC_H_
+#define AES256_DEC_H_
+
+#include "aes.h"
+#include "aes_dec.h"
+
+/** \fn void aes256_dec(void* buffer, aes256_ctx_t* ctx)
+ * \brief decrypt with 256 bit key.
+ *
+ * This function decrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 256 bit key.
+ * \param buffer pointer to the block to decrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes256_dec(void* buffer, aes256_ctx_t* ctx);
+
+
+
+#endif /* AES256_DEC_H_ */
--- /dev/null
+/* aes256_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes256_enc.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ *
+ */
+
+#include "aes.h"
+#include "aes_enc.h"
+
+void aes256_enc(void* buffer, aes256_ctx_t* ctx){
+ aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 14);
+}
+
--- /dev/null
+/* aes256_enc.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes256_enc.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-31
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+#ifndef AES256_ENC_H_
+#define AES256_ENC_H_
+
+#include "aes.h"
+#include "aes_enc.h"
+
+
+/** \fn void aes256_enc(void* buffer, aes256_ctx_t* ctx)
+ * \brief encrypt with 256 bit key.
+ *
+ * This function encrypts one block with the AES algorithm under control of
+ * a keyschedule produced from a 256 bit key.
+ * \param buffer pointer to the block to encrypt
+ * \param ctx pointer to the key schedule
+ */
+void aes256_enc(void* buffer, aes256_ctx_t* ctx);
+
+
+
+#endif /* AES256_ENC_H_ */
--- /dev/null
+/* aes_dec-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_dec-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-10
+ * \license GPLv3 or later
+ *
+ */
+
+#include "avr-asm-macros.S"
+A = 28
+B = 29
+P = 0
+xREDUCER = 25
+gf256mul:
+ clr P
+1:
+ lsr A
+ breq 4f
+ brcc 2f
+ eor P, B
+2:
+ lsl B
+ brcc 3f
+ eor B, xREDUCER
+3:
+ rjmp 1b
+4:
+ brcc 2f
+ eor P, B
+2:
+ ret
+
+.global aes256_dec
+aes256_dec:
+ ldi r20, 14
+ rjmp aes_decrypt_core
+
+.global aes192_dec
+aes192_dec:
+ ldi r20, 12
+ rjmp aes_decrypt_core
+
+.global aes128_dec
+aes128_dec:
+ ldi r20, 10
+
+
+/*
+ void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
+*/
+T0= 2
+T1= 3
+T2= 4
+T3= 5
+T4 = 6
+T5 = 7
+ST00 = 8
+ST01 = 9
+ST02 = 10
+ST03 = 11
+ST10 = 12
+ST11 = 13
+ST12 = 14
+ST13 = 15
+ST20 = 16
+ST21 = 17
+ST22 = 18
+ST23 = 19
+ST30 = 20
+ST31 = 21
+ST32 = 22
+ST33 = 23
+CTR = 24
+/*
+ * param state: r24:r25
+ * param ks: r22:r23
+ * param rounds: r20
+ */
+.global aes_decrypt_core
+aes_decrypt_core:
+ push_range 2, 17
+ push r28
+ push r29
+ push r24
+ push r25
+ movw r26, r22
+ movw r30, r24
+ mov CTR, r20
+ inc r20
+ swap r20 /* r20*16 */
+ add r26, r20
+ adc r27, r1
+ clt
+; ldi CTR, 2
+ .irp param, ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
+ ld \param, Z+
+ .endr
+
+ ldi xREDUCER, 0x1b /* load reducer */
+ ldi r31, hi8(aes_invsbox)
+
+
+ .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
+ ld r0, -X
+ eor \param, r0
+ .endr
+1:
+ dec CTR
+ brne 2f
+ set
+2:
+ /* substitute and invShift */
+ .irp param, ST00, ST10, ST20, ST30
+ mov r30, \param
+ lpm \param, Z
+ .endr
+ mov r30, ST31
+ lpm T0, Z
+ mov r30, ST21
+ lpm ST31, Z
+ mov r30, ST11
+ lpm ST21, Z
+ mov r30, ST01
+ lpm ST11, Z
+ mov ST01, T0
+
+ mov r30, ST32
+ lpm T0, Z
+ mov r30, ST22
+ lpm T1,Z
+ mov r30, ST12
+ lpm ST32, Z
+ mov r30, ST02
+ lpm ST22, Z
+ mov ST12, T0
+ mov ST02, T1
+
+ mov r30, ST03
+ lpm T0, Z
+ mov r30, ST13
+ lpm ST03, Z
+ mov r30, ST23
+ lpm ST13, Z
+ mov r30, ST33
+ lpm ST23, Z
+ mov ST33, T0
+
+ /* key addition */
+ .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
+ ld r0, -X
+ eor \param, r0
+ .endr
+ brtc 2f
+exit:
+ pop r31
+ pop r30
+ st Z+, ST00
+ st Z+, ST01
+ st Z+, ST02
+ st Z+, ST03
+ st Z+, ST10
+ st Z+, ST11
+ st Z+, ST12
+ st Z+, ST13
+ st Z+, ST20
+ st Z+, ST21
+ st Z+, ST22
+ st Z+, ST23
+ st Z+, ST30
+ st Z+, ST31
+ st Z+, ST32
+ st Z+, ST33
+ pop r29
+ pop r28
+ pop_range 2, 17
+ ret
+2:
+ /* inv column (row) mixing*/
+ /* invMixCol (Row) 1 */
+ /* preparing */
+ mov T0, ST03
+ eor T0, ST02 ; T0 = t
+ mov T1, ST00
+ eor T1, ST01 ; T1 = u
+ mov T2, T0
+ eor T2, T1
+
+ mov B, T2
+ ldi A, 0x08
+ rcall gf256mul
+ eor T2, P ; T2 = v'
+
+ mov B, ST02
+ eor B, ST00
+ ldi A, 0x04
+ rcall gf256mul
+ mov T3, P
+ eor T3, T2; T3 = w
+
+ mov B, ST03
+ eor B, ST01
+ ldi A, 0x04
+ rcall gf256mul
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST00
+ eor T4, ST03
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST03, T4
+
+ mov T4, ST02
+ eor T4, ST01
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST01, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST02, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST00, T1
+
+ /* invMixCol (Row) 2 */
+ /* preparing */
+ mov T0, ST13
+ eor T0, ST12 ; T0 = t
+ mov T1, ST10
+ eor T1, ST11 ; T1 = u
+ mov T2, T0
+ eor T2, T1
+
+ mov B, T2
+ ldi A, 0x08
+ rcall gf256mul
+ eor T2, P ; T2 = v'
+
+ mov B, ST12
+ eor B, ST10
+ ldi A, 0x04
+ rcall gf256mul
+ mov T3, P
+ eor T3, T2; T3 = w
+
+ mov B, ST13
+ eor B, ST11
+ ldi A, 0x04
+ rcall gf256mul
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST10
+ eor T4, ST13
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST13, T4
+
+ mov T4, ST12
+ eor T4, ST11
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST11, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST12, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST10, T1
+
+ /* invMixCol (Row) 2 */
+ /* preparing */
+ mov T0, ST23
+ eor T0, ST22 ; T0 = t
+ mov T1, ST20
+ eor T1, ST21 ; T1 = u
+ mov T2, T0
+ eor T2, T1
+
+ mov B, T2
+ ldi A, 0x08
+ rcall gf256mul
+ eor T2, P ; T2 = v'
+
+ mov B, ST22
+ eor B, ST20
+ ldi A, 0x04
+ rcall gf256mul
+ mov T3, P
+ eor T3, T2; T3 = w
+
+ mov B, ST23
+ eor B, ST21
+ ldi A, 0x04
+ rcall gf256mul
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST20
+ eor T4, ST23
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST23, T4
+
+ mov T4, ST22
+ eor T4, ST21
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST21, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST22, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST20, T1
+
+ /* invMixCol (Row) 3 */
+ /* preparing */
+ mov T0, ST33
+ eor T0, ST32 ; T0 = t
+ mov T1, ST30
+ eor T1, ST31 ; T1 = u
+ mov T2, T0
+ eor T2, T1
+
+ mov B, T2
+ ldi A, 0x08
+ rcall gf256mul
+ eor T2, P ; T2 = v'
+
+ mov B, ST32
+ eor B, ST30
+ ldi A, 0x04
+ rcall gf256mul
+ mov T3, P
+ eor T3, T2; T3 = w
+
+ mov B, ST33
+ eor B, ST31
+ ldi A, 0x04
+ rcall gf256mul
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST30
+ eor T4, ST33
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST33, T4
+
+ mov T4, ST32
+ eor T4, ST31
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST31, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST32, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST30, T1
+
+ rjmp 1b
+
+
+
--- /dev/null
+/* aes_dec-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_dec-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-10
+ * \license GPLv3 or later
+ *
+ */
+
+#include "avr-asm-macros.S"
+A = 28
+B = 29
+P = 0
+xREDUCER = 25
+
+.global aes256_dec
+aes256_dec:
+ ldi r20, 14
+ rjmp aes_decrypt_core
+
+.global aes192_dec
+aes192_dec:
+ ldi r20, 12
+ rjmp aes_decrypt_core
+
+.global aes128_dec
+aes128_dec:
+ ldi r20, 10
+
+
+/*
+ void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
+*/
+T0= 2
+T1= 3
+T2= 4
+T3= 5
+T4 = 6
+T5 = 7
+ST00 = 8
+ST01 = 9
+ST02 = 10
+ST03 = 11
+ST10 = 12
+ST11 = 13
+ST12 = 14
+ST13 = 15
+ST20 = 16
+ST21 = 17
+ST22 = 18
+ST23 = 19
+ST30 = 20
+ST31 = 21
+ST32 = 22
+ST33 = 23
+CTR = 24
+/*
+ * param state: r24:r25
+ * param ks: r22:r23
+ * param rounds: r20
+ */
+.global aes_decrypt_core
+aes_decrypt_core:
+ push_range 2, 17
+ push r28
+ push r29
+ push r24
+ push r25
+ movw r26, r22
+ movw r30, r24
+ mov CTR, r20
+ inc r20
+ swap r20 /* r20*16 */
+ add r26, r20
+ adc r27, r1
+ clt
+ .irp param, ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
+ ld \param, Z+
+ .endr
+
+ ldi xREDUCER, 0x1b /* load reducer */
+
+
+ .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
+ ld r0, -X
+ eor \param, r0
+ .endr
+1:
+ dec CTR
+ brne 2f
+ set
+2:
+ ldi r31, hi8(aes_invsbox)
+ /* substitute and invShift */
+ .irp param, ST00, ST10, ST20, ST30
+ mov r30, \param
+ lpm \param, Z
+ .endr
+ mov r30, ST31
+ lpm T0, Z
+ mov r30, ST21
+ lpm ST31, Z
+ mov r30, ST11
+ lpm ST21, Z
+ mov r30, ST01
+ lpm ST11, Z
+ mov ST01, T0
+
+ mov r30, ST32
+ lpm T0, Z
+ mov r30, ST22
+ lpm T1,Z
+ mov r30, ST12
+ lpm ST32, Z
+ mov r30, ST02
+ lpm ST22, Z
+ mov ST12, T0
+ mov ST02, T1
+
+ mov r30, ST03
+ lpm T0, Z
+ mov r30, ST13
+ lpm ST03, Z
+ mov r30, ST23
+ lpm ST13, Z
+ mov r30, ST33
+ lpm ST23, Z
+ mov ST33, T0
+
+ /* key addition */
+ .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
+ ld r0, -X
+ eor \param, r0
+ .endr
+ brtc 2f
+exit:
+ pop r31
+ pop r30
+ st Z+, ST00
+ st Z+, ST01
+ st Z+, ST02
+ st Z+, ST03
+ st Z+, ST10
+ st Z+, ST11
+ st Z+, ST12
+ st Z+, ST13
+ st Z+, ST20
+ st Z+, ST21
+ st Z+, ST22
+ st Z+, ST23
+ st Z+, ST30
+ st Z+, ST31
+ st Z+, ST32
+ st Z+, ST33
+ pop r29
+ pop r28
+ pop_range 2, 17
+ ret
+2:
+ /* inv column (row) mixing*/
+ /* invMixCol (Row) 1 */
+ /* preparing */
+ ldi r31, hi8(lut_gf256mul_0x09)
+ mov T0, ST03
+ eor T0, ST02 ; T0 = t
+ mov T1, ST00
+ eor T1, ST01 ; T1 = u
+ mov r30, T0
+ eor r30, T1
+ lpm T2, Z ; T2 = v'
+
+ ldi r31, hi8(lut_gf256mul_0x04)
+ mov r30, ST02
+ eor r30, ST00
+ lpm T3, Z
+ eor T3, T2; T3 = w
+
+ mov r30, ST03
+ eor r30, ST01
+ lpm P, Z ; T2 = v
+ eor T2, P
+
+ /* now the big move */
+ mov T4, ST00
+ eor T4, ST03
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST03, T4
+
+ mov T4, ST02
+ eor T4, ST01
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST01, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST02, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST00, T1
+
+ /* invMixCol (Row) 2 */
+ /* preparing */
+ ldi r31, hi8(lut_gf256mul_0x09)
+ mov T0, ST13
+ eor T0, ST12 ; T0 = t
+ mov T1, ST10
+ eor T1, ST11 ; T1 = u
+ mov r30, T0
+ eor r30, T1
+
+ lpm T2, Z ; T2 = v'
+
+ ldi r31, hi8(lut_gf256mul_0x04)
+ mov r30, ST12
+ eor r30, ST10
+ lpm T3, Z
+ eor T3, T2; T3 = w
+
+ mov r30, ST13
+ eor r30, ST11
+ lpm P, Z
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST10
+ eor T4, ST13
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST13, T4
+
+ mov T4, ST12
+ eor T4, ST11
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST11, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST12, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST10, T1
+
+ /* invMixCol (Row) 2 */
+ /* preparing */
+ ldi r31, hi8(lut_gf256mul_0x09)
+ mov T0, ST23
+ eor T0, ST22 ; T0 = t
+ mov T1, ST20
+ eor T1, ST21 ; T1 = u
+ mov r30, T0
+ eor r30, T1
+
+ lpm T2, Z ; T2 = v'
+
+ ldi r31, hi8(lut_gf256mul_0x04)
+ mov r30, ST22
+ eor r30, ST20
+ lpm T3, Z
+ eor T3, T2; T3 = w
+
+ mov r30, ST23
+ eor r30, ST21
+ lpm P, Z
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST20
+ eor T4, ST23
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST23, T4
+
+ mov T4, ST22
+ eor T4, ST21
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST21, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST22, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST20, T1
+
+ /* invMixCol (Row) 3 */
+ /* preparing */
+ ldi r31, hi8(lut_gf256mul_0x09)
+ mov T0, ST33
+ eor T0, ST32 ; T0 = t
+ mov T1, ST30
+ eor T1, ST31 ; T1 = u
+ mov r30, T0
+ eor r30, T1
+
+ lpm T2, Z ; T2 = v'
+
+ ldi r31, hi8(lut_gf256mul_0x04)
+ mov r30, ST32
+ eor r30, ST30
+ lpm T3, Z
+ eor T3, T2; T3 = w
+
+ mov r30, ST33
+ eor r30, ST31
+ lpm P, Z
+ eor T2, P ; T2 = v
+
+ /* now the big move */
+ mov T4, ST30
+ eor T4, ST33
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST33, T4
+
+ mov T4, ST32
+ eor T4, ST31
+ lsl T4
+ brcc 3f
+ eor T4, xREDUCER
+3: eor T4, T2
+ eor ST31, T4
+
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, T3
+ eor ST32, T0
+
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, T3
+ eor ST30, T1
+
+ rjmp 1b
+
+.balign 256
+
+lut_gf256mul_0x09:
+.byte 0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F
+.byte 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77
+.byte 0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF
+.byte 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7
+.byte 0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04
+.byte 0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C
+.byte 0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94
+.byte 0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC
+.byte 0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49
+.byte 0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01
+.byte 0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9
+.byte 0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91
+.byte 0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72
+.byte 0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A
+.byte 0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2
+.byte 0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA
+.byte 0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3
+.byte 0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B
+.byte 0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43
+.byte 0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B
+.byte 0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8
+.byte 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0
+.byte 0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78
+.byte 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30
+.byte 0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5
+.byte 0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED
+.byte 0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35
+.byte 0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D
+.byte 0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E
+.byte 0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6
+.byte 0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E
+.byte 0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46
+
+lut_gf256mul_0x04:
+.byte 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C
+.byte 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C
+.byte 0x40, 0x44, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x5C
+.byte 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74, 0x78, 0x7C
+.byte 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9C
+.byte 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC
+.byte 0xC0, 0xC4, 0xC8, 0xCC, 0xD0, 0xD4, 0xD8, 0xDC
+.byte 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC
+.byte 0x1B, 0x1F, 0x13, 0x17, 0x0B, 0x0F, 0x03, 0x07
+.byte 0x3B, 0x3F, 0x33, 0x37, 0x2B, 0x2F, 0x23, 0x27
+.byte 0x5B, 0x5F, 0x53, 0x57, 0x4B, 0x4F, 0x43, 0x47
+.byte 0x7B, 0x7F, 0x73, 0x77, 0x6B, 0x6F, 0x63, 0x67
+.byte 0x9B, 0x9F, 0x93, 0x97, 0x8B, 0x8F, 0x83, 0x87
+.byte 0xBB, 0xBF, 0xB3, 0xB7, 0xAB, 0xAF, 0xA3, 0xA7
+.byte 0xDB, 0xDF, 0xD3, 0xD7, 0xCB, 0xCF, 0xC3, 0xC7
+.byte 0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7
+.byte 0x36, 0x32, 0x3E, 0x3A, 0x26, 0x22, 0x2E, 0x2A
+.byte 0x16, 0x12, 0x1E, 0x1A, 0x06, 0x02, 0x0E, 0x0A
+.byte 0x76, 0x72, 0x7E, 0x7A, 0x66, 0x62, 0x6E, 0x6A
+.byte 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A
+.byte 0xB6, 0xB2, 0xBE, 0xBA, 0xA6, 0xA2, 0xAE, 0xAA
+.byte 0x96, 0x92, 0x9E, 0x9A, 0x86, 0x82, 0x8E, 0x8A
+.byte 0xF6, 0xF2, 0xFE, 0xFA, 0xE6, 0xE2, 0xEE, 0xEA
+.byte 0xD6, 0xD2, 0xDE, 0xDA, 0xC6, 0xC2, 0xCE, 0xCA
+.byte 0x2D, 0x29, 0x25, 0x21, 0x3D, 0x39, 0x35, 0x31
+.byte 0x0D, 0x09, 0x05, 0x01, 0x1D, 0x19, 0x15, 0x11
+.byte 0x6D, 0x69, 0x65, 0x61, 0x7D, 0x79, 0x75, 0x71
+.byte 0x4D, 0x49, 0x45, 0x41, 0x5D, 0x59, 0x55, 0x51
+.byte 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1
+.byte 0x8D, 0x89, 0x85, 0x81, 0x9D, 0x99, 0x95, 0x91
+.byte 0xED, 0xE9, 0xE5, 0xE1, 0xFD, 0xF9, 0xF5, 0xF1
+.byte 0xCD, 0xC9, 0xC5, 0xC1, 0xDD, 0xD9, 0xD5, 0xD1
+
--- /dev/null
+/* aes.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include "gf256mul.h"
+#include "aes.h"
+#include "aes_invsbox.h"
+#include "aes_dec.h"
+#include <avr/pgmspace.h>
+
+void aes_invshiftrow(void* data, uint8_t shift){
+ uint8_t tmp[4];
+ tmp[0] = ((uint8_t*)data)[(4+0-shift)&3];
+ tmp[1] = ((uint8_t*)data)[(4+1-shift)&3];
+ tmp[2] = ((uint8_t*)data)[(4+2-shift)&3];
+ tmp[3] = ((uint8_t*)data)[(4+3-shift)&3];
+ memcpy(data, tmp, 4);
+}
+
+void aes_invshiftcol(void* data, uint8_t shift){
+ uint8_t tmp[4];
+ tmp[0] = ((uint8_t*)data)[ 0];
+ tmp[1] = ((uint8_t*)data)[ 4];
+ tmp[2] = ((uint8_t*)data)[ 8];
+ tmp[3] = ((uint8_t*)data)[12];
+ ((uint8_t*)data)[ 0] = tmp[(4-shift+0)&3];
+ ((uint8_t*)data)[ 4] = tmp[(4-shift+1)&3];
+ ((uint8_t*)data)[ 8] = tmp[(4-shift+2)&3];
+ ((uint8_t*)data)[12] = tmp[(4-shift+3)&3];
+}
+static
+void aes_dec_round(aes_cipher_state_t* state, const aes_roundkey_t* k){
+ uint8_t tmp[16];
+ uint8_t i;
+ uint8_t t,u,v,w;
+ /* keyAdd */
+ for(i=0; i<16; ++i){
+ tmp[i] = state->s[i] ^ k->ks[i];
+ }
+ /* mixColums */
+ for(i=0; i<4; ++i){
+ t = tmp[4*i+3] ^ tmp[4*i+2];
+ u = tmp[4*i+1] ^ tmp[4*i+0];
+ v = t ^ u;
+ v = gf256mul(0x09, v, 0x1b);
+ w = v ^ gf256mul(0x04, tmp[4*i+2] ^ tmp[4*i+0], 0x1b);
+ v = v ^ gf256mul(0x04, tmp[4*i+3] ^ tmp[4*i+1], 0x1b);
+ state->s[4*i+3] = tmp[4*i+3] ^ v ^ gf256mul(0x02, tmp[4*i+0] ^ tmp[4*i+3], 0x1b);
+ state->s[4*i+2] = tmp[4*i+2] ^ w ^ gf256mul(0x02, t, 0x1b);
+ state->s[4*i+1] = tmp[4*i+1] ^ v ^ gf256mul(0x02, tmp[4*i+2] ^ tmp[4*i+1], 0x1b);
+ state->s[4*i+0] = tmp[4*i+0] ^ w ^ gf256mul(0x02, u, 0x1b);
+
+ /*
+ state->s[4*i+0] =
+ gf256mul(0xe, tmp[4*i+0], 0x1b)
+ ^ gf256mul(0xb, tmp[4*i+1], 0x1b)
+ ^ gf256mul(0xd, tmp[4*i+2], 0x1b)
+ ^ gf256mul(0x9, tmp[4*i+3], 0x1b);
+ state->s[4*i+1] =
+ gf256mul(0x9, tmp[4*i+0], 0x1b)
+ ^ gf256mul(0xe, tmp[4*i+1], 0x1b)
+ ^ gf256mul(0xb, tmp[4*i+2], 0x1b)
+ ^ gf256mul(0xd, tmp[4*i+3], 0x1b);
+ state->s[4*i+2] =
+ gf256mul(0xd, tmp[4*i+0], 0x1b)
+ ^ gf256mul(0x9, tmp[4*i+1], 0x1b)
+ ^ gf256mul(0xe, tmp[4*i+2], 0x1b)
+ ^ gf256mul(0xb, tmp[4*i+3], 0x1b);
+ state->s[4*i+3] =
+ gf256mul(0xb, tmp[4*i+0], 0x1b)
+ ^ gf256mul(0xd, tmp[4*i+1], 0x1b)
+ ^ gf256mul(0x9, tmp[4*i+2], 0x1b)
+ ^ gf256mul(0xe, tmp[4*i+3], 0x1b);
+ */
+ }
+ /* shiftRows */
+ aes_invshiftcol(state->s+1, 1);
+ aes_invshiftcol(state->s+2, 2);
+ aes_invshiftcol(state->s+3, 3);
+ /* subBytes */
+ for(i=0; i<16; ++i){
+ state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
+ }
+}
+
+
+static
+void aes_dec_firstround(aes_cipher_state_t* state, const aes_roundkey_t* k){
+ uint8_t i;
+ /* keyAdd */
+ for(i=0; i<16; ++i){
+ state->s[i] ^= k->ks[i];
+ }
+ /* shiftRows */
+ aes_invshiftcol(state->s+1, 1);
+ aes_invshiftcol(state->s+2, 2);
+ aes_invshiftcol(state->s+3, 3);
+ /* subBytes */
+ for(i=0; i<16; ++i){
+ state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
+ }
+}
+
+void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds){
+ uint8_t i;
+ aes_dec_firstround(state, &(ks->key[i=rounds]));
+ for(;rounds>1;--rounds){
+ --i;
+ aes_dec_round(state, &(ks->key[i]));
+ }
+ for(i=0; i<16; ++i){
+ state->s[i] ^= ks->key[0].ks[i];
+ }
+}
--- /dev/null
+/* aes_dec.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_dec.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_DEC_H_
+#define AES_DEC_H_
+#include "aes.h"
+#include <stdint.h>
+
+
+void aes_decrypt_core(aes_cipher_state_t* state,const aes_genctx_t* ks, uint8_t rounds);
+
+
+#endif
--- /dev/null
+/* aes_enc-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_enc-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-10
+ * \license GPLv3 or later
+ *
+ */
+
+#include "avr-asm-macros.S"
+
+
+/*
+ * param a: r24
+ * param b: r22
+ * param reducer: r0
+ */
+A = 28
+B = 29
+P = 0
+xREDUCER = 25
+
+.global aes256_enc
+aes256_enc:
+ ldi r20, 14
+ rjmp aes_encrypt_core
+
+.global aes192_enc
+aes192_enc:
+ ldi r20, 12
+ rjmp aes_encrypt_core
+
+.global aes128_enc
+aes128_enc:
+ ldi r20, 10
+
+
+/*
+ void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
+*/
+T0= 2
+T1= 3
+T2= 4
+T3= 5
+SBOX_SAVE0 = 6
+SBOX_SAVE1 = 7
+ST00 = 8
+ST01 = 9
+ST02 = 10
+ST03 = 11
+ST10 = 12
+ST11 = 13
+ST12 = 14
+ST13 = 15
+ST20 = 16
+ST21 = 17
+ST22 = 18
+ST23 = 19
+ST30 = 20
+ST31 = 21
+ST32 = 22
+ST33 = 23
+CTR = 24
+/*
+ * param state: r24:r25
+ * param ks: r22:r23
+ * param rounds: r20
+ */
+.global aes_encrypt_core
+aes_encrypt_core:
+ push_range 2, 17
+ push r28
+ push r29
+ push r24
+ push r25
+ movw r26, r22
+ movw r30, r24
+ mov CTR, r20
+ clt
+
+ .irp param,ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
+ ld \param, Z+
+ .endr
+
+ ldi xREDUCER, 0x1b /* load reducer */
+ ldi r31, hi8(aes_sbox)
+
+ /* key whitening */
+1:
+ .irp param,ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
+ ld r0, X+
+ eor \param, r0
+ .endr
+
+ brtc 2f
+exit:
+ pop r31
+ pop r30
+ st Z+, ST00
+ st Z+, ST01
+ st Z+, ST02
+ st Z+, ST03
+ st Z+, ST10
+ st Z+, ST11
+ st Z+, ST12
+ st Z+, ST13
+ st Z+, ST20
+ st Z+, ST21
+ st Z+, ST22
+ st Z+, ST23
+ st Z+, ST30
+ st Z+, ST31
+ st Z+, ST32
+ st Z+, ST33
+ pop r29
+ pop r28
+ pop_range 2, 17
+ ret
+
+2: dec CTR
+ brne 3f
+ set
+3:
+
+ /* encryption loop */
+
+ /* SBOX substitution and shifting */
+ mov r30, ST00
+ lpm ST00, Z
+ mov r30, ST10
+ lpm ST10, Z
+ mov r30, ST20
+ lpm ST20, Z
+ mov r30, ST30
+ lpm ST30, Z
+
+ mov r30, ST01
+ lpm T0, Z
+ mov r30, ST11
+ lpm ST01, Z
+ mov r30, ST21
+ lpm ST11, Z
+ mov r30, ST31
+ lpm ST21, Z
+ mov ST31, T0
+
+ mov r30, ST02
+ lpm T0, Z
+ mov r30, ST12
+ lpm T1, Z
+ mov r30, ST22
+ lpm ST02, Z
+ mov r30, ST32
+ lpm ST12, Z
+ mov ST22, T0
+ mov ST32, T1
+
+ mov r30, ST03
+ lpm T0, Z
+ mov r30, ST33
+ lpm ST03, Z
+ mov r30, ST23
+ lpm ST33, Z
+ mov r30, ST13
+ lpm ST23, Z
+ mov ST13, T0
+
+ /* mixcols (or rows in our case) */
+ brtc 2f
+ rjmp 1b
+2:
+ /* mixrow 1 */
+ mov r0, ST02
+ eor r0, ST03
+ mov T2, r0
+
+ mov T0, ST00
+ eor ST00, ST01
+ eor r0, ST00
+ lsl ST00
+ brcc 3f
+ eor ST00, xREDUCER
+3: eor ST00, r0
+ eor ST00, T0
+
+ mov T1, ST01
+ eor T1, ST02
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, r0
+ eor ST01, T1
+
+ lsl T2
+ brcc 3f
+ eor T2, xREDUCER
+3: eor T2, r0
+ eor ST02, T2
+
+ eor T0, ST03
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, r0
+ eor ST03, T0
+
+ /* mixrow 2 */
+ mov r0, ST12
+ eor r0, ST13
+ mov T2, r0
+
+ mov T0, ST10
+ eor ST10, ST11
+ eor r0, ST10
+ lsl ST10
+ brcc 3f
+ eor ST10, xREDUCER
+3: eor ST10, r0
+ eor ST10, T0
+
+ mov T1, ST11
+ eor T1, ST12
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, r0
+ eor ST11, T1
+
+ lsl T2
+ brcc 3f
+ eor T2, xREDUCER
+3: eor T2, r0
+ eor ST12, T2
+
+ eor T0, ST13
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, r0
+ eor ST13, T0
+
+ /* mixrow 3 */
+ mov r0, ST22
+ eor r0, ST23
+ mov T2, r0
+
+ mov T0, ST20
+ eor ST20, ST21
+ eor r0, ST20
+ lsl ST20
+ brcc 3f
+ eor ST20, xREDUCER
+3: eor ST20, r0
+ eor ST20, T0
+
+ mov T1, ST21
+ eor T1, ST22
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, r0
+ eor ST21, T1
+
+ lsl T2
+ brcc 3f
+ eor T2, xREDUCER
+3: eor T2, r0
+ eor ST22, T2
+
+ eor T0, ST23
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, r0
+ eor ST23, T0
+
+ /* mixrow 4 */
+ mov r0, ST32
+ eor r0, ST33
+ mov T2, r0
+
+ mov T0, ST30
+ eor ST30, ST31
+ eor r0, ST30
+ lsl ST30
+ brcc 3f
+ eor ST30, xREDUCER
+3: eor ST30, r0
+ eor ST30, T0
+
+ mov T1, ST31
+ eor T1, ST32
+ lsl T1
+ brcc 3f
+ eor T1, xREDUCER
+3: eor T1, r0
+ eor ST31, T1
+
+ lsl T2
+ brcc 3f
+ eor T2, xREDUCER
+3: eor T2, r0
+ eor ST32, T2
+
+ eor T0, ST33
+ lsl T0
+ brcc 3f
+ eor T0, xREDUCER
+3: eor T0, r0
+ eor ST33, T0
+ /* mix colums (rows) done */
+
+ /* add key*/
+ rjmp 1b
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* aes_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_enc.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "aes.h"
+#include "gf256mul.h"
+#include "aes_sbox.h"
+#include "aes_enc.h"
+#include <avr/pgmspace.h>
+
+void aes_shiftcol(void* data, uint8_t shift){
+ uint8_t tmp[4];
+ tmp[0] = ((uint8_t*)data)[ 0];
+ tmp[1] = ((uint8_t*)data)[ 4];
+ tmp[2] = ((uint8_t*)data)[ 8];
+ tmp[3] = ((uint8_t*)data)[12];
+ ((uint8_t*)data)[ 0] = tmp[(shift+0)&3];
+ ((uint8_t*)data)[ 4] = tmp[(shift+1)&3];
+ ((uint8_t*)data)[ 8] = tmp[(shift+2)&3];
+ ((uint8_t*)data)[12] = tmp[(shift+3)&3];
+}
+
+#define GF256MUL_1(a) (a)
+#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
+#define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
+
+static
+void aes_enc_round(aes_cipher_state_t* state, const aes_roundkey_t* k){
+ uint8_t tmp[16], t;
+ uint8_t i;
+ /* subBytes */
+ for(i=0; i<16; ++i){
+ tmp[i] = pgm_read_byte(aes_sbox+state->s[i]);
+ }
+ /* shiftRows */
+ aes_shiftcol(tmp+1, 1);
+ aes_shiftcol(tmp+2, 2);
+ aes_shiftcol(tmp+3, 3);
+ /* mixColums */
+ for(i=0; i<4; ++i){
+ t = tmp[4*i+0] ^ tmp[4*i+1] ^ tmp[4*i+2] ^ tmp[4*i+3];
+ state->s[4*i+0] =
+ GF256MUL_2(tmp[4*i+0]^tmp[4*i+1])
+ ^ tmp[4*i+0]
+ ^ t;
+ state->s[4*i+1] =
+ GF256MUL_2(tmp[4*i+1]^tmp[4*i+2])
+ ^ tmp[4*i+1]
+ ^ t;
+ state->s[4*i+2] =
+ GF256MUL_2(tmp[4*i+2]^tmp[4*i+3])
+ ^ tmp[4*i+2]
+ ^ t;
+ state->s[4*i+3] =
+ GF256MUL_2(tmp[4*i+3]^tmp[4*i+0])
+ ^ tmp[4*i+3]
+ ^ t;
+ }
+
+ /* addKey */
+ for(i=0; i<16; ++i){
+ state->s[i] ^= k->ks[i];
+ }
+}
+
+
+static
+void aes_enc_lastround(aes_cipher_state_t* state,const aes_roundkey_t* k){
+ uint8_t i;
+ /* subBytes */
+ for(i=0; i<16; ++i){
+ state->s[i] = pgm_read_byte(aes_sbox+state->s[i]);
+ }
+ /* shiftRows */
+ aes_shiftcol(state->s+1, 1);
+ aes_shiftcol(state->s+2, 2);
+ aes_shiftcol(state->s+3, 3);
+ /* keyAdd */
+ for(i=0; i<16; ++i){
+ state->s[i] ^= k->ks[i];
+ }
+}
+
+void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds){
+ uint8_t i;
+ for(i=0; i<16; ++i){
+ state->s[i] ^= ks->key[0].ks[i];
+ }
+ i=1;
+ for(;rounds>1;--rounds){
+ aes_enc_round(state, &(ks->key[i]));
+ ++i;
+ }
+ aes_enc_lastround(state, &(ks->key[i]));
+}
--- /dev/null
+/* aes_enc.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_enc.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_ENC_H_
+#define AES_ENC_H_
+#include "aes.h"
+#include <stdint.h>
+
+
+void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds);
+
+
+#endif
--- /dev/null
+/* aes_sbox-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_dec-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-10
+ * \license GPLv3 or later
+ *
+ */
+.balign 256
+.global aes_invsbox
+aes_invsbox:
+.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
--- /dev/null
+/* aes inverted sbox */
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+uint8_t aes_invsbox[256] PROGMEM = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
--- /dev/null
+/* aes_invsbox.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_invsbox.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_INVSBOX_H_
+#define AES_INVSBOX_H_
+#include <stdint.h>
+
+extern uint8_t aes_invsbox[];
+
+#endif
--- /dev/null
+/* aes_keyschedule-asm */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_keyschedule-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-09
+ * \license GPLv3 or later
+ *
+ */
+
+#include "avr-asm-macros.S"
+
+.global aes256_init
+aes256_init:
+ movw r20, r22
+ ldi r23, hi8(256)
+ ldi r22, lo8(256)
+ rjmp aes_init
+
+.global aes192_init
+aes192_init:
+ movw r20, r22
+ ldi r23, hi8(192)
+ ldi r22, lo8(192)
+ rjmp aes_init
+
+.global aes128_init
+aes128_init:
+ movw r20, r22
+ clr r23
+ ldi r22, 128
+
+/*
+void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx){
+ uint8_t hi,i,nk, next_nk;
+ uint8_t rc=1;
+ uint8_t tmp[4];
+ nk=keysize_b>>5; / * 4, 6, 8 * /
+ hi=4*(nk+6+1);
+ memcpy(ctx, key, keysize_b/8);
+ next_nk = nk;
+ for(i=nk;i<hi;++i){
+ *((uint32_t*)tmp) = ((uint32_t*)(ctx->key[0].ks))[i-1];
+ if(i!=next_nk){
+ if(nk==8 && i%8==4){
+ tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
+ tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
+ tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
+ tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
+ }
+ } else {
+ next_nk += nk;
+ aes_rotword(tmp);
+ tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
+ tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
+ tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
+ tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
+ tmp[0] ^= rc;
+ rc<<=1;
+ }
+ ((uint32_t*)(ctx->key[0].ks))[i] = ((uint32_t*)(ctx->key[0].ks))[i-nk]
+ ^ *((uint32_t*)tmp);
+ }
+}
+*/
+
+SBOX_SAVE0 = 14
+SBOX_SAVE1 = 15
+XRC = 17
+NK = 22
+C1 = 18
+NEXT_NK = 19
+HI = 23
+T0 = 20
+T1 = 21
+T2 = 24
+T3 = 25
+/*
+ * param key: r24:r25
+ * param keysize_b: r22:r23
+ * param ctx: r20:r21
+ */
+.global aes_init
+aes_init:
+ push_range 14, 17
+ push r28
+ push r29
+ movw r30, r20
+ movw r28, r20
+ movw r26, r24
+ lsr r23
+ ror r22
+ lsr r22
+ lsr r22 /* r22 contains keysize_b/8 */
+ mov C1, r22
+
+1: /* copy key to ctx */
+ ld r0, X+
+ st Z+, r0
+ dec C1
+ brne 1b
+
+ lsr NK
+ lsr NK
+ bst NK,3 /* set T if NK==8 */
+ mov NEXT_NK, NK
+ mov HI, NK
+ subi HI, -7
+ lsl HI
+ lsl HI
+ movw r26, r30
+ sbiw r26, 4
+ mov C1, NK
+ ldi r30, lo8(aes_sbox)
+ ldi r31, hi8(aes_sbox)
+ movw SBOX_SAVE0, r30
+ ldi XRC, 1
+1:
+ ld T0, X+
+ ld T1, X+
+ ld T2, X+
+ ld T3, X+
+ cp NEXT_NK, C1
+ breq 2f
+ brtc 5f
+ mov r16, C1
+ andi r16, 0x07
+ cpi r16, 0x04
+ brne 5f
+ movw r30, SBOX_SAVE0
+ add r30, T0
+ adc r31, r1
+ lpm T0, Z
+ movw r30, SBOX_SAVE0
+ add r30, T1
+ adc r31, r1
+ lpm T1, Z
+ movw r30, SBOX_SAVE0
+ add r30, T2
+ adc r31, r1
+ lpm T2, Z
+ movw r30, SBOX_SAVE0
+ add r30, T3
+ adc r31, r1
+ lpm T3, Z
+ rjmp 5f
+2:
+ add NEXT_NK, NK
+ movw r30, SBOX_SAVE0
+ add r30, T0
+ adc r31, r1
+ lpm r16, Z
+ movw r30, SBOX_SAVE0
+ add r30, T1
+ adc r31, r1
+ lpm T0, Z
+ movw r30, SBOX_SAVE0
+ add r30, T2
+ adc r31, r1
+ lpm T1, Z
+ movw r30, SBOX_SAVE0
+ add r30, T3
+ adc r31, r1
+ lpm T2, Z
+ mov T3, r16
+ eor T0, XRC
+ lsl XRC
+ brcc 3f
+ ldi XRC, 0x1b
+3:
+5:
+ movw r30, r26
+
+ ld r0, Y+
+ eor r0, T0
+ st Z+, r0
+ ld r0, Y+
+ eor r0 ,T1
+ st Z+, r0
+ ld r0, Y+
+ eor r0, T2
+ st Z+, r0
+ ld r0, Y+
+ eor r0, T3
+ st Z+, r0
+
+/*
+ st Z+, T0
+ st Z+, T1
+ st Z+, T2
+ st Z+, T3
+*/
+
+ inc C1
+ cp C1, HI
+ breq 6f
+ rjmp 1b
+6:
+
+ clt
+ pop r29
+ pop r28
+ pop_range 14, 17
+ ret
+
+
+
+
--- /dev/null
+/* aes_keyschedule.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_keyschedule.c
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "aes.h"
+#include "aes_keyschedule.h"
+#include "aes_sbox.h"
+#include <string.h>
+#include <avr/pgmspace.h>
+
+static
+void aes_rotword(void* a){
+ uint8_t t;
+ t=((uint8_t*)a)[0];
+ ((uint8_t*)a)[0] = ((uint8_t*)a)[1];
+ ((uint8_t*)a)[1] = ((uint8_t*)a)[2];
+ ((uint8_t*)a)[2] = ((uint8_t*)a)[3];
+ ((uint8_t*)a)[3] = t;
+}
+
+uint8_t rc_tab[] PROGMEM = { 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80,
+ 0x1b, 0x36 };
+
+void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx){
+ uint8_t hi,i,nk, next_nk;
+ uint8_t rc=0;
+ uint8_t tmp[4];
+ nk=keysize_b>>5; /* 4, 6, 8 */
+ hi=4*(nk+6+1);
+ memcpy(ctx, key, keysize_b/8);
+ next_nk = nk;
+ for(i=nk;i<hi;++i){
+ *((uint32_t*)tmp) = ((uint32_t*)(ctx->key[0].ks))[i-1];
+ if(i!=next_nk){
+ if(nk==8 && i%8==4){
+ tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
+ tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
+ tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
+ tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
+ }
+ } else {
+ next_nk += nk;
+ aes_rotword(tmp);
+ tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
+ tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
+ tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
+ tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
+ tmp[0] ^= pgm_read_byte(rc_tab+rc);
+ rc++;
+ }
+ ((uint32_t*)(ctx->key[0].ks))[i] = ((uint32_t*)(ctx->key[0].ks))[i-nk]
+ ^ *((uint32_t*)tmp);
+ }
+}
+
+void aes128_init(const void* key, aes128_ctx_t* ctx){
+ aes_init(key, 128, (aes_genctx_t*)ctx);
+}
+
+void aes192_init(const void* key, aes192_ctx_t* ctx){
+ aes_init(key, 192, (aes_genctx_t*)ctx);
+}
+
+void aes256_init(const void* key, aes256_ctx_t* ctx){
+ aes_init(key, 256, (aes_genctx_t*)ctx);
+}
--- /dev/null
+/* aes_keyschedule.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_keyschedule.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ * \ingroup AES
+ */
+
+
+#ifndef AES_KEYSCHEDULE_H_
+#define AES_KEYSCHEDULE_H_
+
+#include "aes.h"
+/** \fn void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx)
+ * \brief initialize the keyschedule
+ *
+ * This function computes the keyschedule from a given key with a given length
+ * and stores it in the context variable
+ * \param key pointer to the key material
+ * \param keysize_b length of the key in bits (valid are 128, 192 and 256)
+ * \param ctx pointer to the context where the keyschedule should be stored
+ */
+void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx);
+
+/** \fn void aes128_init(const void* key, aes128_ctx_t* ctx)
+ * \brief initialize the keyschedule for 128 bit key
+ *
+ * This function computes the keyschedule from a given 128 bit key
+ * and stores it in the context variable
+ * \param key pointer to the key material
+ * \param ctx pointer to the context where the keyschedule should be stored
+ */
+void aes128_init(const void* key, aes128_ctx_t* ctx);
+
+/** \fn void aes192_init(const void* key, aes192_ctx_t* ctx)
+ * \brief initialize the keyschedule for 192 bit key
+ *
+ * This function computes the keyschedule from a given 192 bit key
+ * and stores it in the context variable
+ * \param key pointer to the key material
+ * \param ctx pointer to the context where the keyschedule should be stored
+ */
+void aes192_init(const void* key, aes192_ctx_t* ctx);
+
+/** \fn void aes256_init(const void* key, aes256_ctx_t* ctx)
+ * \brief initialize the keyschedule for 256 bit key
+ *
+ * This function computes the keyschedule from a given 256 bit key
+ * and stores it in the context variable
+ * \param key pointer to the key material
+ * \param ctx pointer to the context where the keyschedule should be stored
+ */
+void aes256_init(const void* key, aes256_ctx_t* ctx);
+
+#endif /* AES_KEYSCHEDULE_H_ */
+
--- /dev/null
+/* aes_sbox-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_dec-asm.S
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2009-01-10
+ * \license GPLv3 or later
+ *
+ */
+
+.balign 256
+.global aes_sbox
+aes_sbox:
+.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+
--- /dev/null
+/* aes sbox */
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+uint8_t aes_sbox[256] PROGMEM = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
--- /dev/null
+/* aes_sbox.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_sbox.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_SBOX_H_
+#define AES_SBOX_H_
+#include <stdint.h>
+
+extern uint8_t aes_sbox[];
+
+#endif
--- /dev/null
+/* gf256mul.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: gf256mul.S
+ * Author: Daniel Otte
+ * Date: 2008-12-19
+ * License: GPLv3 or later
+ * Description: peasant's algorithm for multiplication in GF(2^8)
+ *
+ */
+
+#include <avr/io.h>
+#define OPTIMIZE_SMALL_A
+
+/*
+ * param a: r24
+ * param b: r22
+ * param reducer: r20
+ */
+A = 23
+B = 22
+P = 24
+.global gf256mul
+
+#ifdef OPTIMIZE_SMALL_A
+gf256mul:
+ mov A, r24
+ clr r24
+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
+
+#else
+
+gf256mul:
+ mov r21, r24
+ clr r24
+ ldi r25, 8
+1:
+ lsr A
+ brcc 2f
+ eor P, B
+2:
+ lsl B
+ brcc 3f
+ eor B, r20
+3:
+ dec r25
+ brne 1b
+ ret
+
+#endif
--- /dev/null
+/* gf256mul.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2008-12-19
+ * \license GPLv3
+ * \brief
+ *
+ *
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
+++ /dev/null
-/* aes128_dec.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes128_dec.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_dec.h"
-
-void aes128_dec(void* buffer, aes128_ctx_t* ctx){
- aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 10);
-}
-
+++ /dev/null
-/* aes128_dec.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes128_dec.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES128_DEC_H_
-#define AES128_DEC_H_
-
-#include "aes.h"
-#include "aes_dec.h"
-
-/** \fn void aes128_dec(void* buffer, aes128_ctx_t* ctx)
- * \brief decrypt with 128 bit key.
- *
- * This function decrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 128 bit key.
- * \param buffer pointer to the block to decrypt
- * \param ctx pointer to the key schedule
- */
-void aes128_dec(void* buffer, aes128_ctx_t* ctx);
-
-
-
-#endif /* AES128_DEC_H_ */
+++ /dev/null
-/* aes128_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes128_enc.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_enc.h"
-
-void aes128_enc(void* buffer, aes128_ctx_t* ctx){
- aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 10);
-}
-
+++ /dev/null
-/* aes128_enc.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes128_enc.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES128_ENC_H_
-#define AES128_ENC_H_
-
-#include "aes.h"
-#include "aes_enc.h"
-
-
-/** \fn void aes128_enc(void* buffer, aes128_ctx_t* ctx)
- * \brief encrypt with 128 bit key.
- *
- * This function encrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 128 bit key.
- * \param buffer pointer to the block to encrypt
- * \param ctx pointer to the key schedule
- */
-void aes128_enc(void* buffer, aes128_ctx_t* ctx);
-
-
-
-#endif /* AES128_ENC_H_ */
+++ /dev/null
-/* aes192_dec.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes192_dec.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_dec.h"
-
-void aes192_dec(void* buffer, aes192_ctx_t* ctx){
- aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 12);
-}
-
+++ /dev/null
-/* aes192_dec.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes192_dec.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES192_DEC_H_
-#define AES192_DEC_H_
-
-#include "aes.h"
-#include "aes_dec.h"
-
-/** \fn void aes192_dec(void* buffer, aes192_ctx_t* ctx)
- * \brief decrypt with 192 bit key.
- *
- * This function decrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 192 bit key.
- * \param buffer pointer to the block to decrypt
- * \param ctx pointer to the key schedule
- */
-void aes192_dec(void* buffer, aes192_ctx_t* ctx);
-
-
-
-#endif /* AES192_DEC_H_ */
+++ /dev/null
-/* aes192_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes192_enc.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_enc.h"
-
-void aes192_enc(void* buffer, aes192_ctx_t* ctx){
- aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 12);
-}
-
+++ /dev/null
-/* aes192_enc.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes192_enc.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES192_ENC_H_
-#define AES192_ENC_H_
-
-#include "aes.h"
-#include "aes_enc.h"
-
-
-/** \fn void aes192_enc(void* buffer, aes192_ctx_t* ctx)
- * \brief encrypt with 192 bit key.
- *
- * This function encrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 192 bit key.
- * \param buffer pointer to the block to encrypt
- * \param ctx pointer to the key schedule
- */
-void aes192_enc(void* buffer, aes192_ctx_t* ctx);
-
-
-
-#endif /* AES192_ENC_H_ */
+++ /dev/null
-/* aes256_dec.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes256_dec.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_dec.h"
-
-void aes256_dec(void* buffer, aes256_ctx_t* ctx){
- aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 14);
-}
-
+++ /dev/null
-/* aes256_dec.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes256_dec.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES256_DEC_H_
-#define AES256_DEC_H_
-
-#include "aes.h"
-#include "aes_dec.h"
-
-/** \fn void aes256_dec(void* buffer, aes256_ctx_t* ctx)
- * \brief decrypt with 256 bit key.
- *
- * This function decrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 256 bit key.
- * \param buffer pointer to the block to decrypt
- * \param ctx pointer to the key schedule
- */
-void aes256_dec(void* buffer, aes256_ctx_t* ctx);
-
-
-
-#endif /* AES256_DEC_H_ */
+++ /dev/null
-/* aes256_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes256_enc.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- *
- */
-
-#include "aes.h"
-#include "aes_enc.h"
-
-void aes256_enc(void* buffer, aes256_ctx_t* ctx){
- aes_encrypt_core(buffer, (aes_genctx_t*)ctx, 14);
-}
-
+++ /dev/null
-/* aes256_enc.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes256_enc.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-31
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-#ifndef AES256_ENC_H_
-#define AES256_ENC_H_
-
-#include "aes.h"
-#include "aes_enc.h"
-
-
-/** \fn void aes256_enc(void* buffer, aes256_ctx_t* ctx)
- * \brief encrypt with 256 bit key.
- *
- * This function encrypts one block with the AES algorithm under control of
- * a keyschedule produced from a 256 bit key.
- * \param buffer pointer to the block to encrypt
- * \param ctx pointer to the key schedule
- */
-void aes256_enc(void* buffer, aes256_ctx_t* ctx);
-
-
-
-#endif /* AES256_ENC_H_ */
+++ /dev/null
-/* aes_dec-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_dec-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-10
- * \license GPLv3 or later
- *
- */
-
-#include "avr-asm-macros.S"
-A = 28
-B = 29
-P = 0
-xREDUCER = 25
-gf256mul:
- clr P
-1:
- lsr A
- breq 4f
- brcc 2f
- eor P, B
-2:
- lsl B
- brcc 3f
- eor B, xREDUCER
-3:
- rjmp 1b
-4:
- brcc 2f
- eor P, B
-2:
- ret
-
-.global aes256_dec
-aes256_dec:
- ldi r20, 14
- rjmp aes_decrypt_core
-
-.global aes192_dec
-aes192_dec:
- ldi r20, 12
- rjmp aes_decrypt_core
-
-.global aes128_dec
-aes128_dec:
- ldi r20, 10
-
-
-/*
- void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
-*/
-T0= 2
-T1= 3
-T2= 4
-T3= 5
-T4 = 6
-T5 = 7
-ST00 = 8
-ST01 = 9
-ST02 = 10
-ST03 = 11
-ST10 = 12
-ST11 = 13
-ST12 = 14
-ST13 = 15
-ST20 = 16
-ST21 = 17
-ST22 = 18
-ST23 = 19
-ST30 = 20
-ST31 = 21
-ST32 = 22
-ST33 = 23
-CTR = 24
-/*
- * param state: r24:r25
- * param ks: r22:r23
- * param rounds: r20
- */
-.global aes_decrypt_core
-aes_decrypt_core:
- push_range 2, 17
- push r28
- push r29
- push r24
- push r25
- movw r26, r22
- movw r30, r24
- mov CTR, r20
- inc r20
- swap r20 /* r20*16 */
- add r26, r20
- adc r27, r1
- clt
-; ldi CTR, 2
- .irp param, ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
- ld \param, Z+
- .endr
-
- ldi xREDUCER, 0x1b /* load reducer */
- ldi r31, hi8(aes_invsbox)
-
-
- .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
- ld r0, -X
- eor \param, r0
- .endr
-1:
- dec CTR
- brne 2f
- set
-2:
- /* substitute and invShift */
- .irp param, ST00, ST10, ST20, ST30
- mov r30, \param
- lpm \param, Z
- .endr
- mov r30, ST31
- lpm T0, Z
- mov r30, ST21
- lpm ST31, Z
- mov r30, ST11
- lpm ST21, Z
- mov r30, ST01
- lpm ST11, Z
- mov ST01, T0
-
- mov r30, ST32
- lpm T0, Z
- mov r30, ST22
- lpm T1,Z
- mov r30, ST12
- lpm ST32, Z
- mov r30, ST02
- lpm ST22, Z
- mov ST12, T0
- mov ST02, T1
-
- mov r30, ST03
- lpm T0, Z
- mov r30, ST13
- lpm ST03, Z
- mov r30, ST23
- lpm ST13, Z
- mov r30, ST33
- lpm ST23, Z
- mov ST33, T0
-
- /* key addition */
- .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
- ld r0, -X
- eor \param, r0
- .endr
- brtc 2f
-exit:
- pop r31
- pop r30
- st Z+, ST00
- st Z+, ST01
- st Z+, ST02
- st Z+, ST03
- st Z+, ST10
- st Z+, ST11
- st Z+, ST12
- st Z+, ST13
- st Z+, ST20
- st Z+, ST21
- st Z+, ST22
- st Z+, ST23
- st Z+, ST30
- st Z+, ST31
- st Z+, ST32
- st Z+, ST33
- pop r29
- pop r28
- pop_range 2, 17
- ret
-2:
- /* inv column (row) mixing*/
- /* invMixCol (Row) 1 */
- /* preparing */
- mov T0, ST03
- eor T0, ST02 ; T0 = t
- mov T1, ST00
- eor T1, ST01 ; T1 = u
- mov T2, T0
- eor T2, T1
-
- mov B, T2
- ldi A, 0x08
- rcall gf256mul
- eor T2, P ; T2 = v'
-
- mov B, ST02
- eor B, ST00
- ldi A, 0x04
- rcall gf256mul
- mov T3, P
- eor T3, T2; T3 = w
-
- mov B, ST03
- eor B, ST01
- ldi A, 0x04
- rcall gf256mul
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST00
- eor T4, ST03
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST03, T4
-
- mov T4, ST02
- eor T4, ST01
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST01, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST02, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST00, T1
-
- /* invMixCol (Row) 2 */
- /* preparing */
- mov T0, ST13
- eor T0, ST12 ; T0 = t
- mov T1, ST10
- eor T1, ST11 ; T1 = u
- mov T2, T0
- eor T2, T1
-
- mov B, T2
- ldi A, 0x08
- rcall gf256mul
- eor T2, P ; T2 = v'
-
- mov B, ST12
- eor B, ST10
- ldi A, 0x04
- rcall gf256mul
- mov T3, P
- eor T3, T2; T3 = w
-
- mov B, ST13
- eor B, ST11
- ldi A, 0x04
- rcall gf256mul
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST10
- eor T4, ST13
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST13, T4
-
- mov T4, ST12
- eor T4, ST11
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST11, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST12, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST10, T1
-
- /* invMixCol (Row) 2 */
- /* preparing */
- mov T0, ST23
- eor T0, ST22 ; T0 = t
- mov T1, ST20
- eor T1, ST21 ; T1 = u
- mov T2, T0
- eor T2, T1
-
- mov B, T2
- ldi A, 0x08
- rcall gf256mul
- eor T2, P ; T2 = v'
-
- mov B, ST22
- eor B, ST20
- ldi A, 0x04
- rcall gf256mul
- mov T3, P
- eor T3, T2; T3 = w
-
- mov B, ST23
- eor B, ST21
- ldi A, 0x04
- rcall gf256mul
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST20
- eor T4, ST23
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST23, T4
-
- mov T4, ST22
- eor T4, ST21
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST21, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST22, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST20, T1
-
- /* invMixCol (Row) 3 */
- /* preparing */
- mov T0, ST33
- eor T0, ST32 ; T0 = t
- mov T1, ST30
- eor T1, ST31 ; T1 = u
- mov T2, T0
- eor T2, T1
-
- mov B, T2
- ldi A, 0x08
- rcall gf256mul
- eor T2, P ; T2 = v'
-
- mov B, ST32
- eor B, ST30
- ldi A, 0x04
- rcall gf256mul
- mov T3, P
- eor T3, T2; T3 = w
-
- mov B, ST33
- eor B, ST31
- ldi A, 0x04
- rcall gf256mul
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST30
- eor T4, ST33
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST33, T4
-
- mov T4, ST32
- eor T4, ST31
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST31, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST32, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST30, T1
-
- rjmp 1b
-
-
-
+++ /dev/null
-/* aes_dec-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_dec-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-10
- * \license GPLv3 or later
- *
- */
-
-#include "avr-asm-macros.S"
-A = 28
-B = 29
-P = 0
-xREDUCER = 25
-
-.global aes256_dec
-aes256_dec:
- ldi r20, 14
- rjmp aes_decrypt_core
-
-.global aes192_dec
-aes192_dec:
- ldi r20, 12
- rjmp aes_decrypt_core
-
-.global aes128_dec
-aes128_dec:
- ldi r20, 10
-
-
-/*
- void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
-*/
-T0= 2
-T1= 3
-T2= 4
-T3= 5
-T4 = 6
-T5 = 7
-ST00 = 8
-ST01 = 9
-ST02 = 10
-ST03 = 11
-ST10 = 12
-ST11 = 13
-ST12 = 14
-ST13 = 15
-ST20 = 16
-ST21 = 17
-ST22 = 18
-ST23 = 19
-ST30 = 20
-ST31 = 21
-ST32 = 22
-ST33 = 23
-CTR = 24
-/*
- * param state: r24:r25
- * param ks: r22:r23
- * param rounds: r20
- */
-.global aes_decrypt_core
-aes_decrypt_core:
- push_range 2, 17
- push r28
- push r29
- push r24
- push r25
- movw r26, r22
- movw r30, r24
- mov CTR, r20
- inc r20
- swap r20 /* r20*16 */
- add r26, r20
- adc r27, r1
- clt
- .irp param, ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
- ld \param, Z+
- .endr
-
- ldi xREDUCER, 0x1b /* load reducer */
-
-
- .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
- ld r0, -X
- eor \param, r0
- .endr
-1:
- dec CTR
- brne 2f
- set
-2:
- ldi r31, hi8(aes_invsbox)
- /* substitute and invShift */
- .irp param, ST00, ST10, ST20, ST30
- mov r30, \param
- lpm \param, Z
- .endr
- mov r30, ST31
- lpm T0, Z
- mov r30, ST21
- lpm ST31, Z
- mov r30, ST11
- lpm ST21, Z
- mov r30, ST01
- lpm ST11, Z
- mov ST01, T0
-
- mov r30, ST32
- lpm T0, Z
- mov r30, ST22
- lpm T1,Z
- mov r30, ST12
- lpm ST32, Z
- mov r30, ST02
- lpm ST22, Z
- mov ST12, T0
- mov ST02, T1
-
- mov r30, ST03
- lpm T0, Z
- mov r30, ST13
- lpm ST03, Z
- mov r30, ST23
- lpm ST13, Z
- mov r30, ST33
- lpm ST23, Z
- mov ST33, T0
-
- /* key addition */
- .irp param, ST33, ST32, ST31, ST30, ST23, ST22, ST21, ST20, ST13, ST12, ST11, ST10, ST03, ST02, ST01, ST00
- ld r0, -X
- eor \param, r0
- .endr
- brtc 2f
-exit:
- pop r31
- pop r30
- st Z+, ST00
- st Z+, ST01
- st Z+, ST02
- st Z+, ST03
- st Z+, ST10
- st Z+, ST11
- st Z+, ST12
- st Z+, ST13
- st Z+, ST20
- st Z+, ST21
- st Z+, ST22
- st Z+, ST23
- st Z+, ST30
- st Z+, ST31
- st Z+, ST32
- st Z+, ST33
- pop r29
- pop r28
- pop_range 2, 17
- ret
-2:
- /* inv column (row) mixing*/
- /* invMixCol (Row) 1 */
- /* preparing */
- ldi r31, hi8(lut_gf256mul_0x09)
- mov T0, ST03
- eor T0, ST02 ; T0 = t
- mov T1, ST00
- eor T1, ST01 ; T1 = u
- mov r30, T0
- eor r30, T1
- lpm T2, Z ; T2 = v'
-
- ldi r31, hi8(lut_gf256mul_0x04)
- mov r30, ST02
- eor r30, ST00
- lpm T3, Z
- eor T3, T2; T3 = w
-
- mov r30, ST03
- eor r30, ST01
- lpm P, Z ; T2 = v
- eor T2, P
-
- /* now the big move */
- mov T4, ST00
- eor T4, ST03
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST03, T4
-
- mov T4, ST02
- eor T4, ST01
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST01, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST02, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST00, T1
-
- /* invMixCol (Row) 2 */
- /* preparing */
- ldi r31, hi8(lut_gf256mul_0x09)
- mov T0, ST13
- eor T0, ST12 ; T0 = t
- mov T1, ST10
- eor T1, ST11 ; T1 = u
- mov r30, T0
- eor r30, T1
-
- lpm T2, Z ; T2 = v'
-
- ldi r31, hi8(lut_gf256mul_0x04)
- mov r30, ST12
- eor r30, ST10
- lpm T3, Z
- eor T3, T2; T3 = w
-
- mov r30, ST13
- eor r30, ST11
- lpm P, Z
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST10
- eor T4, ST13
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST13, T4
-
- mov T4, ST12
- eor T4, ST11
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST11, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST12, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST10, T1
-
- /* invMixCol (Row) 2 */
- /* preparing */
- ldi r31, hi8(lut_gf256mul_0x09)
- mov T0, ST23
- eor T0, ST22 ; T0 = t
- mov T1, ST20
- eor T1, ST21 ; T1 = u
- mov r30, T0
- eor r30, T1
-
- lpm T2, Z ; T2 = v'
-
- ldi r31, hi8(lut_gf256mul_0x04)
- mov r30, ST22
- eor r30, ST20
- lpm T3, Z
- eor T3, T2; T3 = w
-
- mov r30, ST23
- eor r30, ST21
- lpm P, Z
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST20
- eor T4, ST23
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST23, T4
-
- mov T4, ST22
- eor T4, ST21
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST21, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST22, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST20, T1
-
- /* invMixCol (Row) 3 */
- /* preparing */
- ldi r31, hi8(lut_gf256mul_0x09)
- mov T0, ST33
- eor T0, ST32 ; T0 = t
- mov T1, ST30
- eor T1, ST31 ; T1 = u
- mov r30, T0
- eor r30, T1
-
- lpm T2, Z ; T2 = v'
-
- ldi r31, hi8(lut_gf256mul_0x04)
- mov r30, ST32
- eor r30, ST30
- lpm T3, Z
- eor T3, T2; T3 = w
-
- mov r30, ST33
- eor r30, ST31
- lpm P, Z
- eor T2, P ; T2 = v
-
- /* now the big move */
- mov T4, ST30
- eor T4, ST33
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST33, T4
-
- mov T4, ST32
- eor T4, ST31
- lsl T4
- brcc 3f
- eor T4, xREDUCER
-3: eor T4, T2
- eor ST31, T4
-
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, T3
- eor ST32, T0
-
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, T3
- eor ST30, T1
-
- rjmp 1b
-
-.balign 256
-
-lut_gf256mul_0x09:
-.byte 0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F
-.byte 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77
-.byte 0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF
-.byte 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7
-.byte 0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04
-.byte 0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C
-.byte 0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94
-.byte 0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC
-.byte 0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49
-.byte 0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01
-.byte 0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9
-.byte 0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91
-.byte 0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72
-.byte 0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A
-.byte 0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2
-.byte 0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA
-.byte 0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3
-.byte 0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B
-.byte 0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43
-.byte 0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B
-.byte 0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8
-.byte 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0
-.byte 0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78
-.byte 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30
-.byte 0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5
-.byte 0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED
-.byte 0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35
-.byte 0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D
-.byte 0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E
-.byte 0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6
-.byte 0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E
-.byte 0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46
-
-lut_gf256mul_0x04:
-.byte 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C
-.byte 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C
-.byte 0x40, 0x44, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x5C
-.byte 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74, 0x78, 0x7C
-.byte 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9C
-.byte 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC
-.byte 0xC0, 0xC4, 0xC8, 0xCC, 0xD0, 0xD4, 0xD8, 0xDC
-.byte 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC
-.byte 0x1B, 0x1F, 0x13, 0x17, 0x0B, 0x0F, 0x03, 0x07
-.byte 0x3B, 0x3F, 0x33, 0x37, 0x2B, 0x2F, 0x23, 0x27
-.byte 0x5B, 0x5F, 0x53, 0x57, 0x4B, 0x4F, 0x43, 0x47
-.byte 0x7B, 0x7F, 0x73, 0x77, 0x6B, 0x6F, 0x63, 0x67
-.byte 0x9B, 0x9F, 0x93, 0x97, 0x8B, 0x8F, 0x83, 0x87
-.byte 0xBB, 0xBF, 0xB3, 0xB7, 0xAB, 0xAF, 0xA3, 0xA7
-.byte 0xDB, 0xDF, 0xD3, 0xD7, 0xCB, 0xCF, 0xC3, 0xC7
-.byte 0xFB, 0xFF, 0xF3, 0xF7, 0xEB, 0xEF, 0xE3, 0xE7
-.byte 0x36, 0x32, 0x3E, 0x3A, 0x26, 0x22, 0x2E, 0x2A
-.byte 0x16, 0x12, 0x1E, 0x1A, 0x06, 0x02, 0x0E, 0x0A
-.byte 0x76, 0x72, 0x7E, 0x7A, 0x66, 0x62, 0x6E, 0x6A
-.byte 0x56, 0x52, 0x5E, 0x5A, 0x46, 0x42, 0x4E, 0x4A
-.byte 0xB6, 0xB2, 0xBE, 0xBA, 0xA6, 0xA2, 0xAE, 0xAA
-.byte 0x96, 0x92, 0x9E, 0x9A, 0x86, 0x82, 0x8E, 0x8A
-.byte 0xF6, 0xF2, 0xFE, 0xFA, 0xE6, 0xE2, 0xEE, 0xEA
-.byte 0xD6, 0xD2, 0xDE, 0xDA, 0xC6, 0xC2, 0xCE, 0xCA
-.byte 0x2D, 0x29, 0x25, 0x21, 0x3D, 0x39, 0x35, 0x31
-.byte 0x0D, 0x09, 0x05, 0x01, 0x1D, 0x19, 0x15, 0x11
-.byte 0x6D, 0x69, 0x65, 0x61, 0x7D, 0x79, 0x75, 0x71
-.byte 0x4D, 0x49, 0x45, 0x41, 0x5D, 0x59, 0x55, 0x51
-.byte 0xAD, 0xA9, 0xA5, 0xA1, 0xBD, 0xB9, 0xB5, 0xB1
-.byte 0x8D, 0x89, 0x85, 0x81, 0x9D, 0x99, 0x95, 0x91
-.byte 0xED, 0xE9, 0xE5, 0xE1, 0xFD, 0xF9, 0xF5, 0xF1
-.byte 0xCD, 0xC9, 0xC5, 0xC1, 0xDD, 0xD9, 0xD5, 0xD1
-
+++ /dev/null
-/* aes.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include "gf256mul.h"
-#include "aes.h"
-#include "aes_invsbox.h"
-#include "aes_dec.h"
-#include <avr/pgmspace.h>
-
-void aes_invshiftrow(void* data, uint8_t shift){
- uint8_t tmp[4];
- tmp[0] = ((uint8_t*)data)[(4+0-shift)&3];
- tmp[1] = ((uint8_t*)data)[(4+1-shift)&3];
- tmp[2] = ((uint8_t*)data)[(4+2-shift)&3];
- tmp[3] = ((uint8_t*)data)[(4+3-shift)&3];
- memcpy(data, tmp, 4);
-}
-
-void aes_invshiftcol(void* data, uint8_t shift){
- uint8_t tmp[4];
- tmp[0] = ((uint8_t*)data)[ 0];
- tmp[1] = ((uint8_t*)data)[ 4];
- tmp[2] = ((uint8_t*)data)[ 8];
- tmp[3] = ((uint8_t*)data)[12];
- ((uint8_t*)data)[ 0] = tmp[(4-shift+0)&3];
- ((uint8_t*)data)[ 4] = tmp[(4-shift+1)&3];
- ((uint8_t*)data)[ 8] = tmp[(4-shift+2)&3];
- ((uint8_t*)data)[12] = tmp[(4-shift+3)&3];
-}
-static
-void aes_dec_round(aes_cipher_state_t* state, const aes_roundkey_t* k){
- uint8_t tmp[16];
- uint8_t i;
- uint8_t t,u,v,w;
- /* keyAdd */
- for(i=0; i<16; ++i){
- tmp[i] = state->s[i] ^ k->ks[i];
- }
- /* mixColums */
- for(i=0; i<4; ++i){
- t = tmp[4*i+3] ^ tmp[4*i+2];
- u = tmp[4*i+1] ^ tmp[4*i+0];
- v = t ^ u;
- v = gf256mul(0x09, v, 0x1b);
- w = v ^ gf256mul(0x04, tmp[4*i+2] ^ tmp[4*i+0], 0x1b);
- v = v ^ gf256mul(0x04, tmp[4*i+3] ^ tmp[4*i+1], 0x1b);
- state->s[4*i+3] = tmp[4*i+3] ^ v ^ gf256mul(0x02, tmp[4*i+0] ^ tmp[4*i+3], 0x1b);
- state->s[4*i+2] = tmp[4*i+2] ^ w ^ gf256mul(0x02, t, 0x1b);
- state->s[4*i+1] = tmp[4*i+1] ^ v ^ gf256mul(0x02, tmp[4*i+2] ^ tmp[4*i+1], 0x1b);
- state->s[4*i+0] = tmp[4*i+0] ^ w ^ gf256mul(0x02, u, 0x1b);
-
- /*
- state->s[4*i+0] =
- gf256mul(0xe, tmp[4*i+0], 0x1b)
- ^ gf256mul(0xb, tmp[4*i+1], 0x1b)
- ^ gf256mul(0xd, tmp[4*i+2], 0x1b)
- ^ gf256mul(0x9, tmp[4*i+3], 0x1b);
- state->s[4*i+1] =
- gf256mul(0x9, tmp[4*i+0], 0x1b)
- ^ gf256mul(0xe, tmp[4*i+1], 0x1b)
- ^ gf256mul(0xb, tmp[4*i+2], 0x1b)
- ^ gf256mul(0xd, tmp[4*i+3], 0x1b);
- state->s[4*i+2] =
- gf256mul(0xd, tmp[4*i+0], 0x1b)
- ^ gf256mul(0x9, tmp[4*i+1], 0x1b)
- ^ gf256mul(0xe, tmp[4*i+2], 0x1b)
- ^ gf256mul(0xb, tmp[4*i+3], 0x1b);
- state->s[4*i+3] =
- gf256mul(0xb, tmp[4*i+0], 0x1b)
- ^ gf256mul(0xd, tmp[4*i+1], 0x1b)
- ^ gf256mul(0x9, tmp[4*i+2], 0x1b)
- ^ gf256mul(0xe, tmp[4*i+3], 0x1b);
- */
- }
- /* shiftRows */
- aes_invshiftcol(state->s+1, 1);
- aes_invshiftcol(state->s+2, 2);
- aes_invshiftcol(state->s+3, 3);
- /* subBytes */
- for(i=0; i<16; ++i){
- state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
- }
-}
-
-
-static
-void aes_dec_firstround(aes_cipher_state_t* state, const aes_roundkey_t* k){
- uint8_t i;
- /* keyAdd */
- for(i=0; i<16; ++i){
- state->s[i] ^= k->ks[i];
- }
- /* shiftRows */
- aes_invshiftcol(state->s+1, 1);
- aes_invshiftcol(state->s+2, 2);
- aes_invshiftcol(state->s+3, 3);
- /* subBytes */
- for(i=0; i<16; ++i){
- state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
- }
-}
-
-void aes_decrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds){
- uint8_t i;
- aes_dec_firstround(state, &(ks->key[i=rounds]));
- for(;rounds>1;--rounds){
- --i;
- aes_dec_round(state, &(ks->key[i]));
- }
- for(i=0; i<16; ++i){
- state->s[i] ^= ks->key[0].ks[i];
- }
-}
+++ /dev/null
-/* aes_dec.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_dec.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-#ifndef AES_DEC_H_
-#define AES_DEC_H_
-#include "aes.h"
-#include <stdint.h>
-
-
-void aes_decrypt_core(aes_cipher_state_t* state,const aes_genctx_t* ks, uint8_t rounds);
-
-
-#endif
+++ /dev/null
-/* aes_enc-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_enc-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-10
- * \license GPLv3 or later
- *
- */
-
-#include "avr-asm-macros.S"
-
-
-/*
- * param a: r24
- * param b: r22
- * param reducer: r0
- */
-A = 28
-B = 29
-P = 0
-xREDUCER = 25
-
-.global aes256_enc
-aes256_enc:
- ldi r20, 14
- rjmp aes_encrypt_core
-
-.global aes192_enc
-aes192_enc:
- ldi r20, 12
- rjmp aes_encrypt_core
-
-.global aes128_enc
-aes128_enc:
- ldi r20, 10
-
-
-/*
- void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds)
-*/
-T0= 2
-T1= 3
-T2= 4
-T3= 5
-SBOX_SAVE0 = 6
-SBOX_SAVE1 = 7
-ST00 = 8
-ST01 = 9
-ST02 = 10
-ST03 = 11
-ST10 = 12
-ST11 = 13
-ST12 = 14
-ST13 = 15
-ST20 = 16
-ST21 = 17
-ST22 = 18
-ST23 = 19
-ST30 = 20
-ST31 = 21
-ST32 = 22
-ST33 = 23
-CTR = 24
-/*
- * param state: r24:r25
- * param ks: r22:r23
- * param rounds: r20
- */
-.global aes_encrypt_core
-aes_encrypt_core:
- push_range 2, 17
- push r28
- push r29
- push r24
- push r25
- movw r26, r22
- movw r30, r24
- mov CTR, r20
- clt
-
- .irp param,ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
- ld \param, Z+
- .endr
-
- ldi xREDUCER, 0x1b /* load reducer */
- ldi r31, hi8(aes_sbox)
-
- /* key whitening */
-1:
- .irp param,ST00, ST01, ST02, ST03, ST10, ST11, ST12, ST13, ST20, ST21, ST22, ST23, ST30, ST31, ST32, ST33
- ld r0, X+
- eor \param, r0
- .endr
-
- brtc 2f
-exit:
- pop r31
- pop r30
- st Z+, ST00
- st Z+, ST01
- st Z+, ST02
- st Z+, ST03
- st Z+, ST10
- st Z+, ST11
- st Z+, ST12
- st Z+, ST13
- st Z+, ST20
- st Z+, ST21
- st Z+, ST22
- st Z+, ST23
- st Z+, ST30
- st Z+, ST31
- st Z+, ST32
- st Z+, ST33
- pop r29
- pop r28
- pop_range 2, 17
- ret
-
-2: dec CTR
- brne 3f
- set
-3:
-
- /* encryption loop */
-
- /* SBOX substitution and shifting */
- mov r30, ST00
- lpm ST00, Z
- mov r30, ST10
- lpm ST10, Z
- mov r30, ST20
- lpm ST20, Z
- mov r30, ST30
- lpm ST30, Z
-
- mov r30, ST01
- lpm T0, Z
- mov r30, ST11
- lpm ST01, Z
- mov r30, ST21
- lpm ST11, Z
- mov r30, ST31
- lpm ST21, Z
- mov ST31, T0
-
- mov r30, ST02
- lpm T0, Z
- mov r30, ST12
- lpm T1, Z
- mov r30, ST22
- lpm ST02, Z
- mov r30, ST32
- lpm ST12, Z
- mov ST22, T0
- mov ST32, T1
-
- mov r30, ST03
- lpm T0, Z
- mov r30, ST33
- lpm ST03, Z
- mov r30, ST23
- lpm ST33, Z
- mov r30, ST13
- lpm ST23, Z
- mov ST13, T0
-
- /* mixcols (or rows in our case) */
- brtc 2f
- rjmp 1b
-2:
- /* mixrow 1 */
- mov r0, ST02
- eor r0, ST03
- mov T2, r0
-
- mov T0, ST00
- eor ST00, ST01
- eor r0, ST00
- lsl ST00
- brcc 3f
- eor ST00, xREDUCER
-3: eor ST00, r0
- eor ST00, T0
-
- mov T1, ST01
- eor T1, ST02
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, r0
- eor ST01, T1
-
- lsl T2
- brcc 3f
- eor T2, xREDUCER
-3: eor T2, r0
- eor ST02, T2
-
- eor T0, ST03
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, r0
- eor ST03, T0
-
- /* mixrow 2 */
- mov r0, ST12
- eor r0, ST13
- mov T2, r0
-
- mov T0, ST10
- eor ST10, ST11
- eor r0, ST10
- lsl ST10
- brcc 3f
- eor ST10, xREDUCER
-3: eor ST10, r0
- eor ST10, T0
-
- mov T1, ST11
- eor T1, ST12
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, r0
- eor ST11, T1
-
- lsl T2
- brcc 3f
- eor T2, xREDUCER
-3: eor T2, r0
- eor ST12, T2
-
- eor T0, ST13
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, r0
- eor ST13, T0
-
- /* mixrow 3 */
- mov r0, ST22
- eor r0, ST23
- mov T2, r0
-
- mov T0, ST20
- eor ST20, ST21
- eor r0, ST20
- lsl ST20
- brcc 3f
- eor ST20, xREDUCER
-3: eor ST20, r0
- eor ST20, T0
-
- mov T1, ST21
- eor T1, ST22
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, r0
- eor ST21, T1
-
- lsl T2
- brcc 3f
- eor T2, xREDUCER
-3: eor T2, r0
- eor ST22, T2
-
- eor T0, ST23
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, r0
- eor ST23, T0
-
- /* mixrow 4 */
- mov r0, ST32
- eor r0, ST33
- mov T2, r0
-
- mov T0, ST30
- eor ST30, ST31
- eor r0, ST30
- lsl ST30
- brcc 3f
- eor ST30, xREDUCER
-3: eor ST30, r0
- eor ST30, T0
-
- mov T1, ST31
- eor T1, ST32
- lsl T1
- brcc 3f
- eor T1, xREDUCER
-3: eor T1, r0
- eor ST31, T1
-
- lsl T2
- brcc 3f
- eor T2, xREDUCER
-3: eor T2, r0
- eor ST32, T2
-
- eor T0, ST33
- lsl T0
- brcc 3f
- eor T0, xREDUCER
-3: eor T0, r0
- eor ST33, T0
- /* mix colums (rows) done */
-
- /* add key*/
- rjmp 1b
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* aes_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_enc.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "aes.h"
-#include "gf256mul.h"
-#include "aes_sbox.h"
-#include "aes_enc.h"
-#include <avr/pgmspace.h>
-
-void aes_shiftcol(void* data, uint8_t shift){
- uint8_t tmp[4];
- tmp[0] = ((uint8_t*)data)[ 0];
- tmp[1] = ((uint8_t*)data)[ 4];
- tmp[2] = ((uint8_t*)data)[ 8];
- tmp[3] = ((uint8_t*)data)[12];
- ((uint8_t*)data)[ 0] = tmp[(shift+0)&3];
- ((uint8_t*)data)[ 4] = tmp[(shift+1)&3];
- ((uint8_t*)data)[ 8] = tmp[(shift+2)&3];
- ((uint8_t*)data)[12] = tmp[(shift+3)&3];
-}
-
-#define GF256MUL_1(a) (a)
-#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
-#define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
-
-static
-void aes_enc_round(aes_cipher_state_t* state, const aes_roundkey_t* k){
- uint8_t tmp[16], t;
- uint8_t i;
- /* subBytes */
- for(i=0; i<16; ++i){
- tmp[i] = pgm_read_byte(aes_sbox+state->s[i]);
- }
- /* shiftRows */
- aes_shiftcol(tmp+1, 1);
- aes_shiftcol(tmp+2, 2);
- aes_shiftcol(tmp+3, 3);
- /* mixColums */
- for(i=0; i<4; ++i){
- t = tmp[4*i+0] ^ tmp[4*i+1] ^ tmp[4*i+2] ^ tmp[4*i+3];
- state->s[4*i+0] =
- GF256MUL_2(tmp[4*i+0]^tmp[4*i+1])
- ^ tmp[4*i+0]
- ^ t;
- state->s[4*i+1] =
- GF256MUL_2(tmp[4*i+1]^tmp[4*i+2])
- ^ tmp[4*i+1]
- ^ t;
- state->s[4*i+2] =
- GF256MUL_2(tmp[4*i+2]^tmp[4*i+3])
- ^ tmp[4*i+2]
- ^ t;
- state->s[4*i+3] =
- GF256MUL_2(tmp[4*i+3]^tmp[4*i+0])
- ^ tmp[4*i+3]
- ^ t;
- }
-
- /* addKey */
- for(i=0; i<16; ++i){
- state->s[i] ^= k->ks[i];
- }
-}
-
-
-static
-void aes_enc_lastround(aes_cipher_state_t* state,const aes_roundkey_t* k){
- uint8_t i;
- /* subBytes */
- for(i=0; i<16; ++i){
- state->s[i] = pgm_read_byte(aes_sbox+state->s[i]);
- }
- /* shiftRows */
- aes_shiftcol(state->s+1, 1);
- aes_shiftcol(state->s+2, 2);
- aes_shiftcol(state->s+3, 3);
- /* keyAdd */
- for(i=0; i<16; ++i){
- state->s[i] ^= k->ks[i];
- }
-}
-
-void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds){
- uint8_t i;
- for(i=0; i<16; ++i){
- state->s[i] ^= ks->key[0].ks[i];
- }
- i=1;
- for(;rounds>1;--rounds){
- aes_enc_round(state, &(ks->key[i]));
- ++i;
- }
- aes_enc_lastround(state, &(ks->key[i]));
-}
+++ /dev/null
-/* aes_enc.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_enc.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-#ifndef AES_ENC_H_
-#define AES_ENC_H_
-#include "aes.h"
-#include <stdint.h>
-
-
-void aes_encrypt_core(aes_cipher_state_t* state, const aes_genctx_t* ks, uint8_t rounds);
-
-
-#endif
+++ /dev/null
-/* aes_sbox-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_dec-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-10
- * \license GPLv3 or later
- *
- */
-.balign 256
-.global aes_invsbox
-aes_invsbox:
-.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+++ /dev/null
-/* aes inverted sbox */
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-uint8_t aes_invsbox[256] PROGMEM = {
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-};
+++ /dev/null
-/* aes_invsbox.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_invsbox.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-#ifndef AES_INVSBOX_H_
-#define AES_INVSBOX_H_
-#include <stdint.h>
-
-extern uint8_t aes_invsbox[];
-
-#endif
+++ /dev/null
-/* aes_keyschedule-asm */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_keyschedule-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-09
- * \license GPLv3 or later
- *
- */
-
-#include "avr-asm-macros.S"
-
-.global aes256_init
-aes256_init:
- movw r20, r22
- ldi r23, hi8(256)
- ldi r22, lo8(256)
- rjmp aes_init
-
-.global aes192_init
-aes192_init:
- movw r20, r22
- ldi r23, hi8(192)
- ldi r22, lo8(192)
- rjmp aes_init
-
-.global aes128_init
-aes128_init:
- movw r20, r22
- clr r23
- ldi r22, 128
-
-/*
-void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx){
- uint8_t hi,i,nk, next_nk;
- uint8_t rc=1;
- uint8_t tmp[4];
- nk=keysize_b>>5; / * 4, 6, 8 * /
- hi=4*(nk+6+1);
- memcpy(ctx, key, keysize_b/8);
- next_nk = nk;
- for(i=nk;i<hi;++i){
- *((uint32_t*)tmp) = ((uint32_t*)(ctx->key[0].ks))[i-1];
- if(i!=next_nk){
- if(nk==8 && i%8==4){
- tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
- tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
- tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
- tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
- }
- } else {
- next_nk += nk;
- aes_rotword(tmp);
- tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
- tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
- tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
- tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
- tmp[0] ^= rc;
- rc<<=1;
- }
- ((uint32_t*)(ctx->key[0].ks))[i] = ((uint32_t*)(ctx->key[0].ks))[i-nk]
- ^ *((uint32_t*)tmp);
- }
-}
-*/
-
-SBOX_SAVE0 = 14
-SBOX_SAVE1 = 15
-XRC = 17
-NK = 22
-C1 = 18
-NEXT_NK = 19
-HI = 23
-T0 = 20
-T1 = 21
-T2 = 24
-T3 = 25
-/*
- * param key: r24:r25
- * param keysize_b: r22:r23
- * param ctx: r20:r21
- */
-.global aes_init
-aes_init:
- push_range 14, 17
- push r28
- push r29
- movw r30, r20
- movw r28, r20
- movw r26, r24
- lsr r23
- ror r22
- lsr r22
- lsr r22 /* r22 contains keysize_b/8 */
- mov C1, r22
-
-1: /* copy key to ctx */
- ld r0, X+
- st Z+, r0
- dec C1
- brne 1b
-
- lsr NK
- lsr NK
- bst NK,3 /* set T if NK==8 */
- mov NEXT_NK, NK
- mov HI, NK
- subi HI, -7
- lsl HI
- lsl HI
- movw r26, r30
- sbiw r26, 4
- mov C1, NK
- ldi r30, lo8(aes_sbox)
- ldi r31, hi8(aes_sbox)
- movw SBOX_SAVE0, r30
- ldi XRC, 1
-1:
- ld T0, X+
- ld T1, X+
- ld T2, X+
- ld T3, X+
- cp NEXT_NK, C1
- breq 2f
- brtc 5f
- mov r16, C1
- andi r16, 0x07
- cpi r16, 0x04
- brne 5f
- movw r30, SBOX_SAVE0
- add r30, T0
- adc r31, r1
- lpm T0, Z
- movw r30, SBOX_SAVE0
- add r30, T1
- adc r31, r1
- lpm T1, Z
- movw r30, SBOX_SAVE0
- add r30, T2
- adc r31, r1
- lpm T2, Z
- movw r30, SBOX_SAVE0
- add r30, T3
- adc r31, r1
- lpm T3, Z
- rjmp 5f
-2:
- add NEXT_NK, NK
- movw r30, SBOX_SAVE0
- add r30, T0
- adc r31, r1
- lpm r16, Z
- movw r30, SBOX_SAVE0
- add r30, T1
- adc r31, r1
- lpm T0, Z
- movw r30, SBOX_SAVE0
- add r30, T2
- adc r31, r1
- lpm T1, Z
- movw r30, SBOX_SAVE0
- add r30, T3
- adc r31, r1
- lpm T2, Z
- mov T3, r16
- eor T0, XRC
- lsl XRC
- brcc 3f
- ldi XRC, 0x1b
-3:
-5:
- movw r30, r26
-
- ld r0, Y+
- eor r0, T0
- st Z+, r0
- ld r0, Y+
- eor r0 ,T1
- st Z+, r0
- ld r0, Y+
- eor r0, T2
- st Z+, r0
- ld r0, Y+
- eor r0, T3
- st Z+, r0
-
-/*
- st Z+, T0
- st Z+, T1
- st Z+, T2
- st Z+, T3
-*/
-
- inc C1
- cp C1, HI
- breq 6f
- rjmp 1b
-6:
-
- clt
- pop r29
- pop r28
- pop_range 14, 17
- ret
-
-
-
-
+++ /dev/null
-/* aes_keyschedule.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_keyschedule.c
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "aes.h"
-#include "aes_keyschedule.h"
-#include "aes_sbox.h"
-#include <string.h>
-#include <avr/pgmspace.h>
-
-static
-void aes_rotword(void* a){
- uint8_t t;
- t=((uint8_t*)a)[0];
- ((uint8_t*)a)[0] = ((uint8_t*)a)[1];
- ((uint8_t*)a)[1] = ((uint8_t*)a)[2];
- ((uint8_t*)a)[2] = ((uint8_t*)a)[3];
- ((uint8_t*)a)[3] = t;
-}
-
-uint8_t rc_tab[] PROGMEM = { 0x01, 0x02, 0x04, 0x08,
- 0x10, 0x20, 0x40, 0x80,
- 0x1b, 0x36 };
-
-void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx){
- uint8_t hi,i,nk, next_nk;
- uint8_t rc=0;
- uint8_t tmp[4];
- nk=keysize_b>>5; /* 4, 6, 8 */
- hi=4*(nk+6+1);
- memcpy(ctx, key, keysize_b/8);
- next_nk = nk;
- for(i=nk;i<hi;++i){
- *((uint32_t*)tmp) = ((uint32_t*)(ctx->key[0].ks))[i-1];
- if(i!=next_nk){
- if(nk==8 && i%8==4){
- tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
- tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
- tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
- tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
- }
- } else {
- next_nk += nk;
- aes_rotword(tmp);
- tmp[0] = pgm_read_byte(aes_sbox+tmp[0]);
- tmp[1] = pgm_read_byte(aes_sbox+tmp[1]);
- tmp[2] = pgm_read_byte(aes_sbox+tmp[2]);
- tmp[3] = pgm_read_byte(aes_sbox+tmp[3]);
- tmp[0] ^= pgm_read_byte(rc_tab+rc);
- rc++;
- }
- ((uint32_t*)(ctx->key[0].ks))[i] = ((uint32_t*)(ctx->key[0].ks))[i-nk]
- ^ *((uint32_t*)tmp);
- }
-}
-
-void aes128_init(const void* key, aes128_ctx_t* ctx){
- aes_init(key, 128, (aes_genctx_t*)ctx);
-}
-
-void aes192_init(const void* key, aes192_ctx_t* ctx){
- aes_init(key, 192, (aes_genctx_t*)ctx);
-}
-
-void aes256_init(const void* key, aes256_ctx_t* ctx){
- aes_init(key, 256, (aes_genctx_t*)ctx);
-}
+++ /dev/null
-/* aes_keyschedule.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_keyschedule.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- * \ingroup AES
- */
-
-
-#ifndef AES_KEYSCHEDULE_H_
-#define AES_KEYSCHEDULE_H_
-
-#include "aes.h"
-/** \fn void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx)
- * \brief initialize the keyschedule
- *
- * This function computes the keyschedule from a given key with a given length
- * and stores it in the context variable
- * \param key pointer to the key material
- * \param keysize_b length of the key in bits (valid are 128, 192 and 256)
- * \param ctx pointer to the context where the keyschedule should be stored
- */
-void aes_init(const void* key, uint16_t keysize_b, aes_genctx_t* ctx);
-
-/** \fn void aes128_init(const void* key, aes128_ctx_t* ctx)
- * \brief initialize the keyschedule for 128 bit key
- *
- * This function computes the keyschedule from a given 128 bit key
- * and stores it in the context variable
- * \param key pointer to the key material
- * \param ctx pointer to the context where the keyschedule should be stored
- */
-void aes128_init(const void* key, aes128_ctx_t* ctx);
-
-/** \fn void aes192_init(const void* key, aes192_ctx_t* ctx)
- * \brief initialize the keyschedule for 192 bit key
- *
- * This function computes the keyschedule from a given 192 bit key
- * and stores it in the context variable
- * \param key pointer to the key material
- * \param ctx pointer to the context where the keyschedule should be stored
- */
-void aes192_init(const void* key, aes192_ctx_t* ctx);
-
-/** \fn void aes256_init(const void* key, aes256_ctx_t* ctx)
- * \brief initialize the keyschedule for 256 bit key
- *
- * This function computes the keyschedule from a given 256 bit key
- * and stores it in the context variable
- * \param key pointer to the key material
- * \param ctx pointer to the context where the keyschedule should be stored
- */
-void aes256_init(const void* key, aes256_ctx_t* ctx);
-
-#endif /* AES_KEYSCHEDULE_H_ */
-
+++ /dev/null
-/* aes_sbox-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008, 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_dec-asm.S
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2009-01-10
- * \license GPLv3 or later
- *
- */
-
-.balign 256
-.global aes_sbox
-aes_sbox:
-.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-
+++ /dev/null
-/* aes sbox */
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-uint8_t aes_sbox[256] PROGMEM = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
+++ /dev/null
-/* aes_sbox.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file aes_sbox.h
- * \email daniel.otte@rub.de
- * \author Daniel Otte
- * \date 2008-12-30
- * \license GPLv3 or later
- *
- */
-#ifndef AES_SBOX_H_
-#define AES_SBOX_H_
-#include <stdint.h>
-
-extern uint8_t aes_sbox[];
-
-#endif
FLASHCMD = avrdude -p $(MCU_TARGET) -P /dev/ttyUSB0 -c $(PROGRAMMER) -U flash:w:# no space at the end
#FLASHCMD = avrdude -p $(MCU_TARGET) -c usbasp -U flash:w:# no space at the end
DEP_DIR = deps/
+TEST_DIR = test/
BIN_DIR = bin/
TESTBIN_DIR = test_bin/
TESTSRC_DIR = test_src/
#uisp -dprog=bsd -dlpt=/dev/parport1 --upload if=$(PRG).hex
-ERASECMD =
+ERASECMD =
TESTPORT = /dev/ttyUSB1
TESTPORTBAUDR = 38400
TESTLOG_DIR = testlog/
CC = avr-gcc
CSTD = c99
-override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.c,%.d,$(patsubst $(TESTSRC_DIR)%,%,$<)) -I. -Itest_src -gdwarf-2 -pedantic -std=$(CSTD) -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
+override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) -I. -Itest_src -gdwarf-2 -pedantic -std=$(CSTD) -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
+override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) -I. -Itest_src -gdwarf-2 -pedantic -std=$(CSTD) -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS = -gdwarf-2 -Wl,-Map,
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
--- /dev/null
+/* blake_common.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_common.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+uint8_t blake_sigma[] PROGMEM = {
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
+ 0xE, 0xA, 0x4, 0x8, 0x9, 0xF, 0xD, 0x6, 0x1, 0xC, 0x0, 0x2, 0xB, 0x7, 0x5, 0x3,
+ 0xB, 0x8, 0xC, 0x0, 0x5, 0x2, 0xF, 0xD, 0xA, 0xE, 0x3, 0x6, 0x7, 0x1, 0x9, 0x4,
+ 0x7, 0x9, 0x3, 0x1, 0xD, 0xC, 0xB, 0xE, 0x2, 0x6, 0x5, 0xA, 0x4, 0x0, 0xF, 0x8,
+ 0x9, 0x0, 0x5, 0x7, 0x2, 0x4, 0xA, 0xF, 0xE, 0x1, 0xB, 0xC, 0x6, 0x8, 0x3, 0xD,
+ 0x2, 0xC, 0x6, 0xA, 0x0, 0xB, 0x8, 0x3, 0x4, 0xD, 0x7, 0x5, 0xF, 0xE, 0x1, 0x9,
+ 0xC, 0x5, 0x1, 0xF, 0xE, 0xD, 0x4, 0xA, 0x0, 0x7, 0x6, 0x3, 0x9, 0x2, 0x8, 0xB,
+ 0xD, 0xB, 0x7, 0xE, 0xC, 0x1, 0x3, 0x9, 0x5, 0x0, 0xF, 0x4, 0x8, 0x6, 0x2, 0xA,
+ 0x6, 0xF, 0xE, 0x9, 0xB, 0x3, 0x0, 0x8, 0xC, 0x2, 0xD, 0x7, 0x1, 0x4, 0xA, 0x5,
+ 0xA, 0x2, 0x8, 0x4, 0x7, 0x6, 0x1, 0x5, 0xF, 0xB, 0x9, 0xE, 0x3, 0xC, 0xD, 0x0
+};
+
+uint8_t blake_index_lut[] PROGMEM = {
+ 0x0, 0x4, 0x8, 0xC,
+ 0x1, 0x5, 0x9, 0xD,
+ 0x2, 0x6, 0xA, 0xE,
+ 0x3, 0x7, 0xB, 0xF,
+ 0x0, 0x5, 0xA, 0xF,
+ 0x1, 0x6, 0xB, 0xC,
+ 0x2, 0x7, 0x8, 0xD,
+ 0x3, 0x4, 0x9, 0xE
+};
--- /dev/null
+/* blake_common.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_common.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+
+
+#ifndef BLAKE_COMMON_H_
+#define BLAKE_COMMON_H_
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+extern uint8_t blake_sigma[];
+extern uint8_t blake_index_lut[];
+
+#endif /* BLAKE_COMMON_H_ */
--- /dev/null
+/* blake_large.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_large.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "memxor.h"
+#include "blake_large.h"
+#include "blake_common.h"
+
+#define BUG_3 1 /* bug compatibility with reference code */
+#define BUG_4 1 /* bug compatibility with reference code */
+
+uint64_t pgm_read_qword(void* p){
+ union{
+ uint64_t v64;
+ uint32_t v32[2];
+ }r;
+ r.v32[0] = pgm_read_dword(p);
+ r.v32[1] = pgm_read_dword((uint8_t*)p+4);
+ return r.v64;
+}
+
+static
+uint64_t blake_c[] PROGMEM = {
+ 0x243F6A8885A308D3LL, 0x13198A2E03707344LL,
+ 0xA4093822299F31D0LL, 0x082EFA98EC4E6C89LL,
+ 0x452821E638D01377LL, 0xBE5466CF34E90C6CLL,
+ 0xC0AC29B7C97C50DDLL, 0x3F84D5B5B5470917LL,
+ 0x9216D5D98979FB1BLL, 0xD1310BA698DFB5ACLL,
+ 0x2FFD72DBD01ADFB7LL, 0xB8E1AFED6A267E96LL,
+ 0xBA7C9045F12C7F99LL, 0x24A19947B3916CF7LL,
+ 0x0801F2E2858EFC16LL, 0x636920D871574E69LL
+
+};
+
+
+
+#define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n))))
+#define ROTR64(a, n) (((a)>>(n))|((a)<<(64-(n))))
+#define CHANGE_ENDIAN32(a) (((a)<<24)| \
+ ((0x0000ff00&(a))<<8)| \
+ ((0x00ff0000&(a))>>8)| \
+ (a)>>24 )
+
+void blake_large_expand(uint64_t* v, const blake_large_ctx_t* ctx){
+ uint8_t i;
+ memcpy(v, ctx->h, 8*8);
+ for(i=0; i<8; ++i){
+ v[8+i] = pgm_read_qword(&(blake_c[i]));
+ }
+ memxor((uint8_t*)v+8, ctx->s, 4*8);
+
+}
+
+void blake_large_changeendian(void* dest, const void* src){
+ uint8_t i;
+ uint32_t tmp;
+ for(i=0; i<32; i+=2){
+ tmp = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
+ ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i+1]);
+ ((uint32_t*)dest)[i+1] = tmp;
+ }
+}
+
+void blake_large_compress(uint64_t* v,const void* m){
+ uint8_t r,i;
+ uint8_t a,b,c,d, s0, s1;
+ for(r=0; r<14; ++r){
+ for(i=0; i<8; ++i){
+ // blake_large_g(r%10, i, v, (uint64_t*)m);
+ a = pgm_read_byte(blake_index_lut+4*i+0);
+ b = pgm_read_byte(blake_index_lut+4*i+1);
+ c = pgm_read_byte(blake_index_lut+4*i+2);
+ d = pgm_read_byte(blake_index_lut+4*i+3);
+ s0 = pgm_read_byte(blake_sigma+16*r+2*i+0);
+ s1 = pgm_read_byte(blake_sigma+16*r+2*i+1);
+ v[a] += v[b] + (((uint64_t*)m)[s0] ^ pgm_read_qword(&(blake_c[s1])));
+ v[d] = ROTR64(v[d]^v[a], 32);
+ v[c] += v[d];
+ v[b] = ROTR64(v[b]^v[c], 25);
+ v[a] += v[b] + (((uint64_t*)m)[s1] ^ pgm_read_qword(&(blake_c[s0])));
+ v[d] = ROTR64(v[d]^v[a], 16);
+ v[c] += v[d];
+ v[b] = ROTR64(v[b]^v[c], 11);
+ }
+ }
+}
+
+void blake_large_collapse(blake_large_ctx_t* ctx, uint64_t* v){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
+ }
+}
+
+void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* msg){
+ uint64_t v[16];
+ uint64_t m[16];
+ union {
+ uint64_t v64;
+ uint32_t v32[2];
+ }ctr;
+ blake_large_expand(v,ctx);
+ ctx->counter++;
+ ctr.v64 = ctx->counter*1024;
+ v[12] ^= ctr.v64;
+ v[13] ^= ctr.v64;
+ blake_large_changeendian(m, msg);
+ blake_large_compress(v, m);
+ blake_large_collapse(ctx, v);
+}
+
+void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* msg, uint16_t length_b){
+ while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+ blake_large_nextBlock(ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+ length_b -= BLAKE_LARGE_BLOCKSIZE;
+ }
+ uint8_t buffer[128];
+ uint64_t v[16];
+ uint64_t ctr;
+ ctr = ctx->counter*1024+length_b;
+ memset(buffer, 0, 128);
+ memcpy(buffer, msg, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80 >> (length_b%8);
+ blake_large_changeendian(buffer, buffer);
+ blake_large_expand(v, ctx);
+#if BUG_3
+ uint8_t x=0;
+ if(length_b%1024<895 && length_b%8)
+ x=0x40;
+ v[12] ^= ctr + x;
+ v[13] ^= ctr + x;
+
+#else
+ v[12] ^= ctr;
+ v[13] ^= ctr;
+#endif
+ if(length_b>1024-128-2){
+#if BUG_4
+ if(length_b<1017){
+ blake_large_compress(v, buffer);
+ blake_large_collapse(ctx, v);
+ }
+#else
+ blake_large_compress(v, buffer);
+ blake_large_collapse(ctx, v);
+#endif
+ memset(buffer, 0, 128-8);
+ blake_large_expand(v, ctx);
+ }
+ if(ctx->appendone)
+ buffer[128-16-8] |= 0x01;
+ *((uint64_t*)(&(buffer[128-8]))) = ctr;
+ blake_large_compress(v, buffer);
+ blake_large_collapse(ctx, v);
+
+}
+
+uint64_t blake64_iv[] PROGMEM = {
+ 0x6A09E667F3BCC908LL, 0xBB67AE8584CAA73BLL,
+ 0x3C6EF372FE94F82BLL, 0xA54FF53A5F1D36F1LL,
+ 0x510E527FADE682D1LL, 0x9B05688C2B3E6C1FLL,
+ 0x1F83D9ABFB41BD6BLL, 0x5BE0CD19137E2179LL
+};
+
+void blake64_init(blake64_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] = pgm_read_qword(&(blake64_iv[i]));
+ }
+ memset(ctx->s, 0, 4*8);
+ ctx->counter = 0;
+ ctx->appendone = 1;
+}
+
+uint64_t blake48_iv[] PROGMEM = {
+ 0xCBBB9D5DC1059ED8LL, 0x629A292A367CD507LL,
+ 0x9159015A3070DD17LL, 0x152FECD8F70E5939LL,
+ 0x67332667FFC00B31LL, 0x8EB44A8768581511LL,
+ 0xDB0C2E0D64F98FA7LL, 0x47B5481DBEFA4FA4LL
+};
+
+void blake48_init(blake48_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] = pgm_read_qword(&(blake48_iv[i]));
+ }
+ memset(ctx->s, 0, 4*8);
+ ctx->counter = 0;
+ ctx->appendone = 0;
+}
+
+void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
+ ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
+ }
+}
+
+void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<6; ++i){
+ ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
+ ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
+ }
+}
+
+void blake64_nextBlock(blake64_ctx_t* ctx, const void* block){
+ blake_large_nextBlock(ctx, block);
+}
+
+void blake48_nextBlock(blake48_ctx_t* ctx, const void* block){
+ blake_large_nextBlock(ctx, block);
+}
+
+void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b){
+ blake_large_lastBlock(ctx, block, length_b);
+}
+
+void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b){
+ blake_large_lastBlock(ctx, block, length_b);
+}
+
+void blake64(void* dest, const void* msg, uint32_t length_b){
+ blake_large_ctx_t ctx;
+ blake64_init(&ctx);
+ while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+ blake_large_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+ length_b -= BLAKE_LARGE_BLOCKSIZE;
+ }
+ blake_large_lastBlock(&ctx, msg, length_b);
+ blake64_ctx2hash(dest, &ctx);
+}
+
+void blake48(void* dest, const void* msg, uint32_t length_b){
+ blake_large_ctx_t ctx;
+ blake48_init(&ctx);
+ while(length_b>=BLAKE_LARGE_BLOCKSIZE){
+ blake_large_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
+ length_b -= BLAKE_LARGE_BLOCKSIZE;
+ }
+ blake_large_lastBlock(&ctx, msg, length_b);
+ blake48_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* blake_large.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_large.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-08
+ * \license GPLv3 or later
+ *
+ */
+#ifndef BLAKE_LARGE_H_
+#define BLAKE_LARGE_H_
+
+#include <stdint.h>
+
+#define BLAKE_LARGE_BLOCKSIZE 1024
+#define BLAKE_LARGE_BLOCKSIZE_B ((BLAKE_LARGE_BLOCKSIZE+7)/8)
+#define BLAKE48_BLOCKSIZE BLAKE_LARGE_BLOCKSIZE
+#define BLAKE48_BLOCKSIZE_B BLAKE_LARGE_BLOCKSIZE_B
+#define BLAKE64_BLOCKSIZE BLAKE_LARGE_BLOCKSIZE
+#define BLAKE64_BLOCKSIZE_B BLAKE_LARGE_BLOCKSIZE_B
+
+typedef struct {
+ uint64_t h[8];
+ uint64_t s[4];
+ uint32_t counter;
+ uint8_t appendone;
+} blake_large_ctx_t;
+
+typedef blake_large_ctx_t blake48_ctx_t;
+typedef blake_large_ctx_t blake64_ctx_t;
+
+void blake48_init(blake48_ctx_t* ctx);
+void blake64_init(blake64_ctx_t* ctx);
+
+void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* block);
+void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake48_nextBlock(blake48_ctx_t* ctx, const void* block);
+void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake64_nextBlock(blake64_ctx_t* ctx, const void* block);
+void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx);
+void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx);
+
+void blake48(void* dest, const void* msg, uint32_t length_b);
+void blake64(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BLAKE_LARGE_H_ */
--- /dev/null
+/* blake_small.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_small.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-04
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "memxor.h"
+#include "blake_small.h"
+#include "blake_common.h"
+
+#define BUG_1 1 /* bug compatibility for zero length message */
+#define BUG_2 1 /* bug compatibility for messages of length%512=505...511 */
+
+
+uint32_t blake_c[] PROGMEM = {
+ 0x243F6A88, 0x85A308D3,
+ 0x13198A2E, 0x03707344,
+ 0xA4093822, 0x299F31D0,
+ 0x082EFA98, 0xEC4E6C89,
+ 0x452821E6, 0x38D01377,
+ 0xBE5466CF, 0x34E90C6C,
+ 0xC0AC29B7, 0xC97C50DD,
+ 0x3F84D5B5, 0xB5470917
+};
+
+#define ROTL32(a, n) (((a)<<(n))|((a)>>(32-(n))))
+#define ROTR32(a, n) (((a)>>(n))|((a)<<(32-(n))))
+#define CHANGE_ENDIAN32(a) (((a)<<24)| \
+ ((0x0000ff00&(a))<<8)| \
+ ((0x00ff0000&(a))>>8)| \
+ (a)>>24 )
+
+void blake_small_expand(uint32_t* v, const blake_small_ctx_t* ctx){
+ uint8_t i;
+ memcpy(v, ctx->h, 8*4);
+ for(i=0; i<8; ++i){
+ v[8+i] = pgm_read_dword(&(blake_c[i]));
+ }
+ memxor((uint8_t*)v+8, ctx->s, 4*4);
+
+}
+
+void blake_small_changeendian(void* dest, const void* src){
+ uint8_t i;
+ for(i=0; i<16; ++i){
+ ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
+ }
+}
+
+void blake_small_compress(uint32_t* v,const void* m){
+ uint8_t r,i;
+ uint8_t a,b,c,d, s0, s1;
+ uint32_t lv[4];
+ for(r=0; r<10; ++r){
+ for(i=0; i<8; ++i){
+ // blake_small_g(r, i, v, (uint32_t*)m);
+ a = pgm_read_byte(blake_index_lut+4*i+0);
+ b = pgm_read_byte(blake_index_lut+4*i+1);
+ c = pgm_read_byte(blake_index_lut+4*i+2);
+ d = pgm_read_byte(blake_index_lut+4*i+3);
+ s0 = pgm_read_byte(blake_sigma+16*r+2*i+0);
+ s1 = pgm_read_byte(blake_sigma+16*r+2*i+1);
+ lv[0] = v[a];
+ lv[1] = v[b];
+ lv[2] = v[c];
+ lv[3] = v[d];
+
+ lv[0] += lv[1] + (((uint32_t*)m)[s0] ^ pgm_read_dword(&(blake_c[s1])));
+ lv[3] = ROTR32(lv[3]^lv[0], 16);
+ lv[2] += lv[3];
+ lv[1] = ROTR32(lv[1]^lv[2], 12);
+ lv[0] += lv[1] + (((uint32_t*)m)[s1] ^ pgm_read_dword(&(blake_c[s0])));
+ lv[3] = ROTR32(lv[3]^lv[0], 8);
+ lv[2] += lv[3];
+ lv[1] = ROTR32(lv[1]^lv[2], 7);
+
+ v[a] = lv[0];
+ v[b] = lv[1];
+ v[c] = lv[2];
+ v[d] = lv[3];
+
+ }
+ }
+}
+
+void blake_small_collapse(blake_small_ctx_t* ctx, uint32_t* v){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
+ }
+}
+
+void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* msg){
+ uint32_t v[16];
+ uint32_t m[16];
+ union {
+ uint64_t v64;
+ uint32_t v32[2];
+ }ctr;
+ blake_small_expand(v,ctx);
+ ctx->counter++;
+ ctr.v64 = ctx->counter*512;
+ v[12] ^= ctr.v32[0];
+ v[13] ^= ctr.v32[0];
+ v[14] ^= ctr.v32[1];
+ v[15] ^= ctr.v32[1];
+ blake_small_changeendian(m, msg);
+ blake_small_compress(v, m);
+ blake_small_collapse(ctx, v);
+}
+
+void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t length_b){
+ while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+ blake_small_nextBlock(ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+ length_b -= BLAKE_SMALL_BLOCKSIZE;
+ }
+ uint8_t buffer[64];
+ uint32_t v[16];
+#if BUG_2
+ uint32_t tmp=0;
+#endif
+ union {
+ uint64_t v64;
+ uint32_t v32[2];
+ }ctr;
+ ctr.v64 = ctx->counter*512+length_b;
+#if BUG_2
+ if(length_b>=505){
+ tmp =ctr.v32[0];
+ ctr.v32[0] = ctx->counter*512;
+ ctr.v32[0] |= 0x40+length_b-504;
+ }
+#endif
+ memset(buffer, 0, 64);
+ memcpy(buffer, msg, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80 >> (length_b%8);
+ blake_small_changeendian(buffer, buffer);
+ blake_small_expand(v, ctx);
+ v[12] ^= ctr.v32[0];
+ v[13] ^= ctr.v32[0];
+ v[14] ^= ctr.v32[1];
+ v[15] ^= ctr.v32[1];
+#if BUG_2
+ if(length_b>=505)
+ ctr.v32[0] = tmp;
+#endif
+#if BUG_1
+ if(length_b==0 && ctx->counter==0){
+ v[14] ^= 1;
+ v[15] ^= 1;
+ }
+#endif
+ if(length_b>512-64-2){
+ blake_small_compress(v, buffer);
+ blake_small_collapse(ctx, v);
+ memset(buffer, 0, 64-8);
+ blake_small_expand(v, ctx);
+ }
+ if(ctx->appendone)
+ buffer[64-8-4] |= 0x01;
+ *((uint32_t*)(&(buffer[64-8]))) = ctr.v32[1];
+ *((uint32_t*)(&(buffer[64-4]))) = ctr.v32[0];
+ blake_small_compress(v, buffer);
+ blake_small_collapse(ctx, v);
+
+}
+
+uint32_t blake32_iv[] PROGMEM = {
+ 0x6A09E667L, 0xBB67AE85,
+ 0x3C6EF372L, 0xA54FF53A,
+ 0x510E527FL, 0x9B05688C,
+ 0x1F83D9ABL, 0x5BE0CD19
+};
+
+void blake32_init(blake32_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] = pgm_read_dword(&(blake32_iv[i]));
+ }
+ memset(ctx->s, 0, 4*4);
+ ctx->counter = 0;
+ ctx->appendone = 1;
+}
+
+uint32_t blake28_iv[] PROGMEM = {
+ 0xC1059ED8, 0x367CD507,
+ 0x3070DD17, 0xF70E5939,
+ 0xFFC00B31, 0x68581511,
+ 0x64F98FA7, 0xBEFA4FA4
+};
+
+void blake28_init(blake28_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ctx->h[i] = pgm_read_dword(&(blake28_iv[i]));
+ }
+ memset(ctx->s, 0, 4*4);
+ ctx->counter = 0;
+ ctx->appendone = 0;
+}
+
+void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<8; ++i){
+ ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
+ }
+}
+
+void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx){
+ uint8_t i;
+ for(i=0; i<7; ++i){
+ ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
+ }
+}
+
+void blake32_nextBlock(blake32_ctx_t* ctx, const void* block){
+ blake_small_nextBlock(ctx, block);
+}
+
+void blake28_nextBlock(blake28_ctx_t* ctx, const void* block){
+ blake_small_nextBlock(ctx, block);
+}
+
+void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b){
+ blake_small_lastBlock(ctx, block, length_b);
+}
+
+void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b){
+ blake_small_lastBlock(ctx, block, length_b);
+}
+
+void blake32(void* dest, const void* msg, uint32_t length_b){
+ blake_small_ctx_t ctx;
+ blake32_init(&ctx);
+ while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+ blake_small_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+ length_b -= BLAKE_SMALL_BLOCKSIZE;
+ }
+ blake_small_lastBlock(&ctx, msg, length_b);
+ blake32_ctx2hash(dest, &ctx);
+}
+
+void blake28(void* dest, const void* msg, uint32_t length_b){
+ blake_small_ctx_t ctx;
+ blake28_init(&ctx);
+ while(length_b>=BLAKE_SMALL_BLOCKSIZE){
+ blake_small_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
+ length_b -= BLAKE_SMALL_BLOCKSIZE;
+ }
+ blake_small_lastBlock(&ctx, msg, length_b);
+ blake28_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* blake_small.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file blake_small.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+#ifndef BLAKE_SMALL_H_
+#define BLAKE_SMALL_H_
+
+#include <stdint.h>
+
+#define BLAKE_SMALL_BLOCKSIZE 512
+#define BLAKE_SMALL_BLOCKSIZE_B ((BLAKE_SMALL_BLOCKSIZE+7)/8)
+#define BLAKE28_BLOCKSIZE BLAKE_SMALL_BLOCKSIZE
+#define BLAKE28_BLOCKSIZE_B BLAKE_SMALL_BLOCKSIZE_B
+#define BLAKE32_BLOCKSIZE BLAKE_SMALL_BLOCKSIZE
+#define BLAKE32_BLOCKSIZE_B BLAKE_SMALL_BLOCKSIZE_B
+
+typedef struct {
+ uint32_t h[8];
+ uint32_t s[4];
+ uint32_t counter;
+ uint8_t appendone;
+} blake_small_ctx_t;
+
+typedef blake_small_ctx_t blake28_ctx_t;
+typedef blake_small_ctx_t blake32_ctx_t;
+
+void blake28_init(blake28_ctx_t* ctx);
+void blake32_init(blake32_ctx_t* ctx);
+
+void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* block);
+void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake28_nextBlock(blake28_ctx_t* ctx, const void* block);
+void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake32_nextBlock(blake32_ctx_t* ctx, const void* block);
+void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx);
+void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx);
+
+void blake28(void* dest, const void* msg, uint32_t length_b);
+void blake32(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* BLAKE_SMALL_H_ */
--- /dev/null
+/* memxor.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: memxor.S
+ * Author: Daniel Otte
+ * Date: 2008-08-07
+ * License: GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+ * param dest is passed in r24:r25
+ * param src is passed in r22:r23
+ * param n is passed in r20:r21
+ */
+.global memxor
+memxor:
+ movw r30, r24
+ movw r26, r22
+ movw r24, r20
+ adiw r24, 0
+ breq 2f
+1:
+ ld r20, X+
+ ld r21, Z
+ eor r20, r21
+ st Z+, r20
+ sbiw r24, 1
+ brne 1b
+2:
+ ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
+++ /dev/null
-/* blake_common.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_common.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-08
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-
-uint8_t blake_sigma[] PROGMEM = {
- 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
- 0xE, 0xA, 0x4, 0x8, 0x9, 0xF, 0xD, 0x6, 0x1, 0xC, 0x0, 0x2, 0xB, 0x7, 0x5, 0x3,
- 0xB, 0x8, 0xC, 0x0, 0x5, 0x2, 0xF, 0xD, 0xA, 0xE, 0x3, 0x6, 0x7, 0x1, 0x9, 0x4,
- 0x7, 0x9, 0x3, 0x1, 0xD, 0xC, 0xB, 0xE, 0x2, 0x6, 0x5, 0xA, 0x4, 0x0, 0xF, 0x8,
- 0x9, 0x0, 0x5, 0x7, 0x2, 0x4, 0xA, 0xF, 0xE, 0x1, 0xB, 0xC, 0x6, 0x8, 0x3, 0xD,
- 0x2, 0xC, 0x6, 0xA, 0x0, 0xB, 0x8, 0x3, 0x4, 0xD, 0x7, 0x5, 0xF, 0xE, 0x1, 0x9,
- 0xC, 0x5, 0x1, 0xF, 0xE, 0xD, 0x4, 0xA, 0x0, 0x7, 0x6, 0x3, 0x9, 0x2, 0x8, 0xB,
- 0xD, 0xB, 0x7, 0xE, 0xC, 0x1, 0x3, 0x9, 0x5, 0x0, 0xF, 0x4, 0x8, 0x6, 0x2, 0xA,
- 0x6, 0xF, 0xE, 0x9, 0xB, 0x3, 0x0, 0x8, 0xC, 0x2, 0xD, 0x7, 0x1, 0x4, 0xA, 0x5,
- 0xA, 0x2, 0x8, 0x4, 0x7, 0x6, 0x1, 0x5, 0xF, 0xB, 0x9, 0xE, 0x3, 0xC, 0xD, 0x0
-};
-
-uint8_t blake_index_lut[] PROGMEM = {
- 0x0, 0x4, 0x8, 0xC,
- 0x1, 0x5, 0x9, 0xD,
- 0x2, 0x6, 0xA, 0xE,
- 0x3, 0x7, 0xB, 0xF,
- 0x0, 0x5, 0xA, 0xF,
- 0x1, 0x6, 0xB, 0xC,
- 0x2, 0x7, 0x8, 0xD,
- 0x3, 0x4, 0x9, 0xE
-};
+++ /dev/null
-/* blake_common.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_common.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-08
- * \license GPLv3 or later
- *
- */
-
-
-#ifndef BLAKE_COMMON_H_
-#define BLAKE_COMMON_H_
-
-#include <stdint.h>
-#include <avr/pgmspace.h>
-
-extern uint8_t blake_sigma[];
-extern uint8_t blake_index_lut[];
-
-#endif /* BLAKE_COMMON_H_ */
+++ /dev/null
-/* blake_large.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_large.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-08
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "memxor.h"
-#include "blake_large.h"
-#include "blake_common.h"
-
-#define BUG_3 1 /* bug compatibility with reference code */
-#define BUG_4 1 /* bug compatibility with reference code */
-
-uint64_t pgm_read_qword(void* p){
- union{
- uint64_t v64;
- uint32_t v32[2];
- }r;
- r.v32[0] = pgm_read_dword(p);
- r.v32[1] = pgm_read_dword((uint8_t*)p+4);
- return r.v64;
-}
-
-static
-uint64_t blake_c[] PROGMEM = {
- 0x243F6A8885A308D3LL, 0x13198A2E03707344LL,
- 0xA4093822299F31D0LL, 0x082EFA98EC4E6C89LL,
- 0x452821E638D01377LL, 0xBE5466CF34E90C6CLL,
- 0xC0AC29B7C97C50DDLL, 0x3F84D5B5B5470917LL,
- 0x9216D5D98979FB1BLL, 0xD1310BA698DFB5ACLL,
- 0x2FFD72DBD01ADFB7LL, 0xB8E1AFED6A267E96LL,
- 0xBA7C9045F12C7F99LL, 0x24A19947B3916CF7LL,
- 0x0801F2E2858EFC16LL, 0x636920D871574E69LL
-
-};
-
-
-
-#define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n))))
-#define ROTR64(a, n) (((a)>>(n))|((a)<<(64-(n))))
-#define CHANGE_ENDIAN32(a) (((a)<<24)| \
- ((0x0000ff00&(a))<<8)| \
- ((0x00ff0000&(a))>>8)| \
- (a)>>24 )
-
-void blake_large_expand(uint64_t* v, const blake_large_ctx_t* ctx){
- uint8_t i;
- memcpy(v, ctx->h, 8*8);
- for(i=0; i<8; ++i){
- v[8+i] = pgm_read_qword(&(blake_c[i]));
- }
- memxor((uint8_t*)v+8, ctx->s, 4*8);
-
-}
-
-void blake_large_changeendian(void* dest, const void* src){
- uint8_t i;
- uint32_t tmp;
- for(i=0; i<32; i+=2){
- tmp = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
- ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i+1]);
- ((uint32_t*)dest)[i+1] = tmp;
- }
-}
-
-void blake_large_compress(uint64_t* v,const void* m){
- uint8_t r,i;
- uint8_t a,b,c,d, s0, s1;
- for(r=0; r<14; ++r){
- for(i=0; i<8; ++i){
- // blake_large_g(r%10, i, v, (uint64_t*)m);
- a = pgm_read_byte(blake_index_lut+4*i+0);
- b = pgm_read_byte(blake_index_lut+4*i+1);
- c = pgm_read_byte(blake_index_lut+4*i+2);
- d = pgm_read_byte(blake_index_lut+4*i+3);
- s0 = pgm_read_byte(blake_sigma+16*r+2*i+0);
- s1 = pgm_read_byte(blake_sigma+16*r+2*i+1);
- v[a] += v[b] + (((uint64_t*)m)[s0] ^ pgm_read_qword(&(blake_c[s1])));
- v[d] = ROTR64(v[d]^v[a], 32);
- v[c] += v[d];
- v[b] = ROTR64(v[b]^v[c], 25);
- v[a] += v[b] + (((uint64_t*)m)[s1] ^ pgm_read_qword(&(blake_c[s0])));
- v[d] = ROTR64(v[d]^v[a], 16);
- v[c] += v[d];
- v[b] = ROTR64(v[b]^v[c], 11);
- }
- }
-}
-
-void blake_large_collapse(blake_large_ctx_t* ctx, uint64_t* v){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
- }
-}
-
-void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* msg){
- uint64_t v[16];
- uint64_t m[16];
- union {
- uint64_t v64;
- uint32_t v32[2];
- }ctr;
- blake_large_expand(v,ctx);
- ctx->counter++;
- ctr.v64 = ctx->counter*1024;
- v[12] ^= ctr.v64;
- v[13] ^= ctr.v64;
- blake_large_changeendian(m, msg);
- blake_large_compress(v, m);
- blake_large_collapse(ctx, v);
-}
-
-void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* msg, uint16_t length_b){
- while(length_b>=BLAKE_LARGE_BLOCKSIZE){
- blake_large_nextBlock(ctx, msg);
- msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
- length_b -= BLAKE_LARGE_BLOCKSIZE;
- }
- uint8_t buffer[128];
- uint64_t v[16];
- uint64_t ctr;
- ctr = ctx->counter*1024+length_b;
- memset(buffer, 0, 128);
- memcpy(buffer, msg, (length_b+7)/8);
- buffer[length_b/8] |= 0x80 >> (length_b%8);
- blake_large_changeendian(buffer, buffer);
- blake_large_expand(v, ctx);
-#if BUG_3
- uint8_t x=0;
- if(length_b%1024<895 && length_b%8)
- x=0x40;
- v[12] ^= ctr + x;
- v[13] ^= ctr + x;
-
-#else
- v[12] ^= ctr;
- v[13] ^= ctr;
-#endif
- if(length_b>1024-128-2){
-#if BUG_4
- if(length_b<1017){
- blake_large_compress(v, buffer);
- blake_large_collapse(ctx, v);
- }
-#else
- blake_large_compress(v, buffer);
- blake_large_collapse(ctx, v);
-#endif
- memset(buffer, 0, 128-8);
- blake_large_expand(v, ctx);
- }
- if(ctx->appendone)
- buffer[128-16-8] |= 0x01;
- *((uint64_t*)(&(buffer[128-8]))) = ctr;
- blake_large_compress(v, buffer);
- blake_large_collapse(ctx, v);
-
-}
-
-uint64_t blake64_iv[] PROGMEM = {
- 0x6A09E667F3BCC908LL, 0xBB67AE8584CAA73BLL,
- 0x3C6EF372FE94F82BLL, 0xA54FF53A5F1D36F1LL,
- 0x510E527FADE682D1LL, 0x9B05688C2B3E6C1FLL,
- 0x1F83D9ABFB41BD6BLL, 0x5BE0CD19137E2179LL
-};
-
-void blake64_init(blake64_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] = pgm_read_qword(&(blake64_iv[i]));
- }
- memset(ctx->s, 0, 4*8);
- ctx->counter = 0;
- ctx->appendone = 1;
-}
-
-uint64_t blake48_iv[] PROGMEM = {
- 0xCBBB9D5DC1059ED8LL, 0x629A292A367CD507LL,
- 0x9159015A3070DD17LL, 0x152FECD8F70E5939LL,
- 0x67332667FFC00B31LL, 0x8EB44A8768581511LL,
- 0xDB0C2E0D64F98FA7LL, 0x47B5481DBEFA4FA4LL
-};
-
-void blake48_init(blake48_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] = pgm_read_qword(&(blake48_iv[i]));
- }
- memset(ctx->s, 0, 4*8);
- ctx->counter = 0;
- ctx->appendone = 0;
-}
-
-void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
- ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
- }
-}
-
-void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<6; ++i){
- ((uint32_t*)dest)[2*i+0] = CHANGE_ENDIAN32((ctx->h[i])>>32);
- ((uint32_t*)dest)[2*i+1] = CHANGE_ENDIAN32((uint32_t)ctx->h[i]);
- }
-}
-
-void blake64_nextBlock(blake64_ctx_t* ctx, const void* block){
- blake_large_nextBlock(ctx, block);
-}
-
-void blake48_nextBlock(blake48_ctx_t* ctx, const void* block){
- blake_large_nextBlock(ctx, block);
-}
-
-void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b){
- blake_large_lastBlock(ctx, block, length_b);
-}
-
-void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b){
- blake_large_lastBlock(ctx, block, length_b);
-}
-
-void blake64(void* dest, const void* msg, uint32_t length_b){
- blake_large_ctx_t ctx;
- blake64_init(&ctx);
- while(length_b>=BLAKE_LARGE_BLOCKSIZE){
- blake_large_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
- length_b -= BLAKE_LARGE_BLOCKSIZE;
- }
- blake_large_lastBlock(&ctx, msg, length_b);
- blake64_ctx2hash(dest, &ctx);
-}
-
-void blake48(void* dest, const void* msg, uint32_t length_b){
- blake_large_ctx_t ctx;
- blake48_init(&ctx);
- while(length_b>=BLAKE_LARGE_BLOCKSIZE){
- blake_large_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + BLAKE_LARGE_BLOCKSIZE_B;
- length_b -= BLAKE_LARGE_BLOCKSIZE;
- }
- blake_large_lastBlock(&ctx, msg, length_b);
- blake48_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* blake_large.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_large.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-08
- * \license GPLv3 or later
- *
- */
-#ifndef BLAKE_LARGE_H_
-#define BLAKE_LARGE_H_
-
-#include <stdint.h>
-
-#define BLAKE_LARGE_BLOCKSIZE 1024
-#define BLAKE_LARGE_BLOCKSIZE_B ((BLAKE_LARGE_BLOCKSIZE+7)/8)
-#define BLAKE48_BLOCKSIZE BLAKE_LARGE_BLOCKSIZE
-#define BLAKE48_BLOCKSIZE_B BLAKE_LARGE_BLOCKSIZE_B
-#define BLAKE64_BLOCKSIZE BLAKE_LARGE_BLOCKSIZE
-#define BLAKE64_BLOCKSIZE_B BLAKE_LARGE_BLOCKSIZE_B
-
-typedef struct {
- uint64_t h[8];
- uint64_t s[4];
- uint32_t counter;
- uint8_t appendone;
-} blake_large_ctx_t;
-
-typedef blake_large_ctx_t blake48_ctx_t;
-typedef blake_large_ctx_t blake64_ctx_t;
-
-void blake48_init(blake48_ctx_t* ctx);
-void blake64_init(blake64_ctx_t* ctx);
-
-void blake_large_nextBlock(blake_large_ctx_t* ctx, const void* block);
-void blake_large_lastBlock(blake_large_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake48_nextBlock(blake48_ctx_t* ctx, const void* block);
-void blake48_lastBlock(blake48_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake64_nextBlock(blake64_ctx_t* ctx, const void* block);
-void blake64_lastBlock(blake64_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake48_ctx2hash(void* dest, const blake48_ctx_t* ctx);
-void blake64_ctx2hash(void* dest, const blake64_ctx_t* ctx);
-
-void blake48(void* dest, const void* msg, uint32_t length_b);
-void blake64(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* BLAKE_LARGE_H_ */
+++ /dev/null
-/* blake_small.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_small.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-04
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "memxor.h"
-#include "blake_small.h"
-#include "blake_common.h"
-
-#define BUG_1 1 /* bug compatibility for zero length message */
-#define BUG_2 1 /* bug compatibility for messages of length%512=505...511 */
-
-
-uint32_t blake_c[] PROGMEM = {
- 0x243F6A88, 0x85A308D3,
- 0x13198A2E, 0x03707344,
- 0xA4093822, 0x299F31D0,
- 0x082EFA98, 0xEC4E6C89,
- 0x452821E6, 0x38D01377,
- 0xBE5466CF, 0x34E90C6C,
- 0xC0AC29B7, 0xC97C50DD,
- 0x3F84D5B5, 0xB5470917
-};
-
-#define ROTL32(a, n) (((a)<<(n))|((a)>>(32-(n))))
-#define ROTR32(a, n) (((a)>>(n))|((a)<<(32-(n))))
-#define CHANGE_ENDIAN32(a) (((a)<<24)| \
- ((0x0000ff00&(a))<<8)| \
- ((0x00ff0000&(a))>>8)| \
- (a)>>24 )
-
-void blake_small_expand(uint32_t* v, const blake_small_ctx_t* ctx){
- uint8_t i;
- memcpy(v, ctx->h, 8*4);
- for(i=0; i<8; ++i){
- v[8+i] = pgm_read_dword(&(blake_c[i]));
- }
- memxor((uint8_t*)v+8, ctx->s, 4*4);
-
-}
-
-void blake_small_changeendian(void* dest, const void* src){
- uint8_t i;
- for(i=0; i<16; ++i){
- ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
- }
-}
-
-void blake_small_compress(uint32_t* v,const void* m){
- uint8_t r,i;
- uint8_t a,b,c,d, s0, s1;
- uint32_t lv[4];
- for(r=0; r<10; ++r){
- for(i=0; i<8; ++i){
- // blake_small_g(r, i, v, (uint32_t*)m);
- a = pgm_read_byte(blake_index_lut+4*i+0);
- b = pgm_read_byte(blake_index_lut+4*i+1);
- c = pgm_read_byte(blake_index_lut+4*i+2);
- d = pgm_read_byte(blake_index_lut+4*i+3);
- s0 = pgm_read_byte(blake_sigma+16*r+2*i+0);
- s1 = pgm_read_byte(blake_sigma+16*r+2*i+1);
- lv[0] = v[a];
- lv[1] = v[b];
- lv[2] = v[c];
- lv[3] = v[d];
-
- lv[0] += lv[1] + (((uint32_t*)m)[s0] ^ pgm_read_dword(&(blake_c[s1])));
- lv[3] = ROTR32(lv[3]^lv[0], 16);
- lv[2] += lv[3];
- lv[1] = ROTR32(lv[1]^lv[2], 12);
- lv[0] += lv[1] + (((uint32_t*)m)[s1] ^ pgm_read_dword(&(blake_c[s0])));
- lv[3] = ROTR32(lv[3]^lv[0], 8);
- lv[2] += lv[3];
- lv[1] = ROTR32(lv[1]^lv[2], 7);
-
- v[a] = lv[0];
- v[b] = lv[1];
- v[c] = lv[2];
- v[d] = lv[3];
-
- }
- }
-}
-
-void blake_small_collapse(blake_small_ctx_t* ctx, uint32_t* v){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
- }
-}
-
-void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* msg){
- uint32_t v[16];
- uint32_t m[16];
- union {
- uint64_t v64;
- uint32_t v32[2];
- }ctr;
- blake_small_expand(v,ctx);
- ctx->counter++;
- ctr.v64 = ctx->counter*512;
- v[12] ^= ctr.v32[0];
- v[13] ^= ctr.v32[0];
- v[14] ^= ctr.v32[1];
- v[15] ^= ctr.v32[1];
- blake_small_changeendian(m, msg);
- blake_small_compress(v, m);
- blake_small_collapse(ctx, v);
-}
-
-void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t length_b){
- while(length_b>=BLAKE_SMALL_BLOCKSIZE){
- blake_small_nextBlock(ctx, msg);
- msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
- length_b -= BLAKE_SMALL_BLOCKSIZE;
- }
- uint8_t buffer[64];
- uint32_t v[16];
-#if BUG_2
- uint32_t tmp=0;
-#endif
- union {
- uint64_t v64;
- uint32_t v32[2];
- }ctr;
- ctr.v64 = ctx->counter*512+length_b;
-#if BUG_2
- if(length_b>=505){
- tmp =ctr.v32[0];
- ctr.v32[0] = ctx->counter*512;
- ctr.v32[0] |= 0x40+length_b-504;
- }
-#endif
- memset(buffer, 0, 64);
- memcpy(buffer, msg, (length_b+7)/8);
- buffer[length_b/8] |= 0x80 >> (length_b%8);
- blake_small_changeendian(buffer, buffer);
- blake_small_expand(v, ctx);
- v[12] ^= ctr.v32[0];
- v[13] ^= ctr.v32[0];
- v[14] ^= ctr.v32[1];
- v[15] ^= ctr.v32[1];
-#if BUG_2
- if(length_b>=505)
- ctr.v32[0] = tmp;
-#endif
-#if BUG_1
- if(length_b==0 && ctx->counter==0){
- v[14] ^= 1;
- v[15] ^= 1;
- }
-#endif
- if(length_b>512-64-2){
- blake_small_compress(v, buffer);
- blake_small_collapse(ctx, v);
- memset(buffer, 0, 64-8);
- blake_small_expand(v, ctx);
- }
- if(ctx->appendone)
- buffer[64-8-4] |= 0x01;
- *((uint32_t*)(&(buffer[64-8]))) = ctr.v32[1];
- *((uint32_t*)(&(buffer[64-4]))) = ctr.v32[0];
- blake_small_compress(v, buffer);
- blake_small_collapse(ctx, v);
-
-}
-
-uint32_t blake32_iv[] PROGMEM = {
- 0x6A09E667L, 0xBB67AE85,
- 0x3C6EF372L, 0xA54FF53A,
- 0x510E527FL, 0x9B05688C,
- 0x1F83D9ABL, 0x5BE0CD19
-};
-
-void blake32_init(blake32_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] = pgm_read_dword(&(blake32_iv[i]));
- }
- memset(ctx->s, 0, 4*4);
- ctx->counter = 0;
- ctx->appendone = 1;
-}
-
-uint32_t blake28_iv[] PROGMEM = {
- 0xC1059ED8, 0x367CD507,
- 0x3070DD17, 0xF70E5939,
- 0xFFC00B31, 0x68581511,
- 0x64F98FA7, 0xBEFA4FA4
-};
-
-void blake28_init(blake28_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ctx->h[i] = pgm_read_dword(&(blake28_iv[i]));
- }
- memset(ctx->s, 0, 4*4);
- ctx->counter = 0;
- ctx->appendone = 0;
-}
-
-void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<8; ++i){
- ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
- }
-}
-
-void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx){
- uint8_t i;
- for(i=0; i<7; ++i){
- ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
- }
-}
-
-void blake32_nextBlock(blake32_ctx_t* ctx, const void* block){
- blake_small_nextBlock(ctx, block);
-}
-
-void blake28_nextBlock(blake28_ctx_t* ctx, const void* block){
- blake_small_nextBlock(ctx, block);
-}
-
-void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b){
- blake_small_lastBlock(ctx, block, length_b);
-}
-
-void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b){
- blake_small_lastBlock(ctx, block, length_b);
-}
-
-void blake32(void* dest, const void* msg, uint32_t length_b){
- blake_small_ctx_t ctx;
- blake32_init(&ctx);
- while(length_b>=BLAKE_SMALL_BLOCKSIZE){
- blake_small_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
- length_b -= BLAKE_SMALL_BLOCKSIZE;
- }
- blake_small_lastBlock(&ctx, msg, length_b);
- blake32_ctx2hash(dest, &ctx);
-}
-
-void blake28(void* dest, const void* msg, uint32_t length_b){
- blake_small_ctx_t ctx;
- blake28_init(&ctx);
- while(length_b>=BLAKE_SMALL_BLOCKSIZE){
- blake_small_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
- length_b -= BLAKE_SMALL_BLOCKSIZE;
- }
- blake_small_lastBlock(&ctx, msg, length_b);
- blake28_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* blake_small.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file blake_small.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-#ifndef BLAKE_SMALL_H_
-#define BLAKE_SMALL_H_
-
-#include <stdint.h>
-
-#define BLAKE_SMALL_BLOCKSIZE 512
-#define BLAKE_SMALL_BLOCKSIZE_B ((BLAKE_SMALL_BLOCKSIZE+7)/8)
-#define BLAKE28_BLOCKSIZE BLAKE_SMALL_BLOCKSIZE
-#define BLAKE28_BLOCKSIZE_B BLAKE_SMALL_BLOCKSIZE_B
-#define BLAKE32_BLOCKSIZE BLAKE_SMALL_BLOCKSIZE
-#define BLAKE32_BLOCKSIZE_B BLAKE_SMALL_BLOCKSIZE_B
-
-typedef struct {
- uint32_t h[8];
- uint32_t s[4];
- uint32_t counter;
- uint8_t appendone;
-} blake_small_ctx_t;
-
-typedef blake_small_ctx_t blake28_ctx_t;
-typedef blake_small_ctx_t blake32_ctx_t;
-
-void blake28_init(blake28_ctx_t* ctx);
-void blake32_init(blake32_ctx_t* ctx);
-
-void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* block);
-void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake28_nextBlock(blake28_ctx_t* ctx, const void* block);
-void blake28_lastBlock(blake28_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake32_nextBlock(blake32_ctx_t* ctx, const void* block);
-void blake32_lastBlock(blake32_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void blake28_ctx2hash(void* dest, const blake28_ctx_t* ctx);
-void blake32_ctx2hash(void* dest, const blake32_ctx_t* ctx);
-
-void blake28(void* dest, const void* msg, uint32_t length_b);
-void blake32(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* BLAKE_SMALL_H_ */
+++ /dev/null
-/* camellia-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * File: camellis-asm.S
- * Author: Daniel Otte
- * Date: 2006-11-10
- * License: GPLv3 or later
- * Description: Implementation of the camellia block cipher algorithm.
- *
- */
-
-.macro SWAP_R A, B
- eor \A, \B
- eor \B, \A
- eor \A, \B
-.endm
-
-.macro precall
- /* push r18 - r27, r30 - r31*/
- push r0
- push r1
- push r18
- push r19
- push r20
- push r21
- push r22
- push r23
- push r24
- push r25
- push r26
- push r27
- push r30
- push r31
- clr r1
-.endm
-
-.macro postcall
- pop r31
- pop r30
- pop r27
- pop r26
- pop r25
- pop r24
- pop r23
- pop r22
- pop r21
- pop r20
- pop r19
- pop r18
- pop r1
- pop r0
-.endm
-
-
-.macro hexdump length
- push r27
- push r26
- ldi r25, '\r'
- mov r24, r25
- call uart_putc
- ldi r25, '\n'
- mov r24, r25
- call uart_putc
- pop r26
- pop r27
- movw r24, r26
-.if \length > 16
- ldi r22, lo8(16)
- ldi r23, hi8(16)
- push r27
- push r26
- call uart_hexdump
- pop r26
- pop r27
- adiw r26, 16
- hexdump \length-16
-.else
- ldi r22, lo8(\length)
- ldi r23, hi8(\length)
- call uart_hexdump
-.endif
-.endm
-
-/* X points to Block */
-.macro dbg_hexdump length
- precall
- hexdump \length
- postcall
-.endm
-
-SPL = 0x3D
-SPH = 0x3E
-SREG = 0x3F
-NULLr = 1
-
-
-camellia_sbox:
-.byte 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65
-.byte 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189
-.byte 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26
-.byte 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77
-.byte 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153
-.byte 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215
-.byte 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34
-.byte 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80
-.byte 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210
-.byte 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148
-.byte 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226
-.byte 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46
-.byte 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89
-.byte 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250
-.byte 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164
-.byte 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
-
-//.global camellia_sigma
-/*
-camellia_sigma:
-.quad 0xA09E667F3BCC908B
-.quad 0xB67AE8584CAA73B2
-.quad 0xC6EF372FE94F82BE
-.quad 0x54FF53A5F1D36F1C
-.quad 0x10E527FADE682D1D
-.quad 0xB05688C2B3E6C1FD
-*/
-
-
-
-/* uint8_t camellia_s1(uint8_t b) */
-.global camellia_s1
-camellia_s1:
- ldi r30, lo8(camellia_sbox)
- ldi r31, hi8(camellia_sbox)
- add r30, r24
- adc r31, NULLr
- lpm r24, Z
- clr r25
- ret
-
-.global camellia_s2
-camellia_s2:
- ldi r30, lo8(camellia_sbox)
- ldi r31, hi8(camellia_sbox)
- add r30, r24
- adc r31, NULLr
- lpm r24, Z
- lsl r24
- adc r24, NULLr
- clr r25
- ret
-
-.global camellia_s3
-camellia_s3:
- ldi r30, lo8(camellia_sbox)
- ldi r31, hi8(camellia_sbox)
- add r30, r24
- adc r31, NULLr
- lpm r24, Z
- bst r24, 0
- lsr r24
- bld r24, 7
- clr r25
- ret
-
-.global camellia_s4
-camellia_s4:
- ldi r30, lo8(camellia_sbox)
- ldi r31, hi8(camellia_sbox)
- lsl r24
- adc r24, NULLr
- add r30, r24
- adc r31, NULLr
- lpm r24, Z
- clr r25
- ret
-
-.global camellia_s
-/* uint64_t camellia_s(uint64_t d){
- #define D ((uint8_t*)(&d))
- D[7] = camellia_s1(D[7]); // MSB
- D[6] = camellia_s2(D[6]);
- D[5] = camellia_s3(D[5]);
- D[4] = camellia_s4(D[4]);
-
- D[3] = camellia_s2(D[3]);
- D[2] = camellia_s3(D[2]);
- D[1] = camellia_s4(D[1]);
- D[0] = camellia_s1(D[0]); // LSB
- #undef D
- return d;
-}*/
-; parameters
-; d: r18-r25 (r18 is LSB)
-camellia_s:
- movw r26, r24 ; backup r24,r25 -> X
- clr r25
- rcall camellia_s2
- mov r26, r24
-
- mov r24, r27
- rcall camellia_s1
- mov r27, r24
-
- mov r24, r23
- rcall camellia_s3
- mov r23, r24
-
- mov r24, r22
- rcall camellia_s4
- mov r22, r24
-
- mov r24, r21
- rcall camellia_s2
- mov r21, r24
-
- mov r24, r20
- rcall camellia_s3
- mov r20, r24
-
- mov r24, r19
- rcall camellia_s4
- mov r19, r24
-
-
- mov r24, r18
- rcall camellia_s1
- mov r18, r24
-
- movw r24, r26
- ret
-
-;##############################################################################
-/* uint64_t camellia_p(uint64_t d) */
-; param: r18-r25 (r18 is LSB)
-z1 = 25
-z2 = 24
-z3 = 23
-z4 = 22
-z5 = 21
-z6 = 20
-z7 = 19
-z8 = 18
-
-.global camellia_p
-camellia_p:
- eor z1, z6
- eor z2, z7
- eor z3, z8
- eor z4, z5
- eor z5, z3
- eor z6, z4
- eor z7, z1
- eor z8, z2
- ;---------
- eor z1, z8
- eor z2, z5
- eor z3, z6
- eor z4, z7
- eor z5, z4
- eor z6, z1
- eor z7, z2
- eor z8, z3
- ;---------
- movw r26, z8
- movw r30, z6 ; backup z5 bis z8
- movw z8, z4
- movw z6, z2
- movw z4, r26
- movw z2, r30
- ret
-
-
-;##############################################################################
-
-/* uint64_t camellia_f(uint64_t x, uint64_t k) */
-; param x: r18-r25
-; param k: r10-r17
-.global camellia_f
-camellia_f:
- eor r18, r10
- eor r19, r11
- eor r20, r12
- eor r21, r13
- eor r22, r14
- eor r23, r15
- eor r24, r16
- eor r25, r17
- rcall camellia_s
- rcall camellia_p
- ret
-
-;##############################################################################
-
-/* uint64_t camellia_fl(uint64_t x, uint64_t k) */
-; param x: r18-r25 xl: r22-r25, xr: r18-r21
-; param k: r10-r17 kl: r14-r17, kr: r10-r13
-kl1 = 14
-kl2 = 15
-kl3 = 16
-kl4 = 17
-kr1 = 10
-kr2 = 11
-kr3 = 12
-kr4 = 13
-xr1 = 18
-xr2 = 19
-xr3 = 20
-xr4 = 21
-xl1 = 22
-xl2 = 23
-xl3 = 24
-xl4 = 25
-.global camellia_fl
-camellia_fl:
- and kl1, xl1
- and kl2, xl2
- and kl3, xl3
- and kl4, xl4
- mov r26, kl4
- rol r26
- rol kl1
- rol kl2
- rol kl3
- rol kl4
- eor xr1, kl1
- eor xr2, kl2
- eor xr3, kl3
- eor xr4, kl4
- // that was part one
- or kr1, xr1
- or kr2, xr2
- or kr3, xr3
- or kr4, xr4
- eor xl1, kr1
- eor xl2, kr2
- eor xl3, kr3
- eor xl4, kr4
- ret
-
-;##############################################################################
-
-/* uint64_t camellia_fl_inv(uint64_t y, uint64_t k) */
-; param y: r18-r25 yl: r22-r25, yr: r18-r21
-; param k: r10-r17 kl: r14-r17, kr: r10-r13
-kl1 = 14
-kl2 = 15
-kl3 = 16
-kl4 = 17
-kr1 = 10
-kr2 = 11
-kr3 = 12
-kr4 = 13
-yr1 = 18
-yr2 = 19
-yr3 = 20
-yr4 = 21
-yl1 = 22
-yl2 = 23
-yl3 = 24
-yl4 = 25
-.global camellia_fl_inv
-camellia_fl_inv:
- or kr1, yr1
- or kr2, yr2
- or kr3, yr3
- or kr4, yr4
- eor yl1, kr1
- eor yl2, kr2
- eor yl3, kr3
- eor yl4, kr4
- // the first one is done
- and kl1, yl1
- and kl2, yl2
- and kl3, yl3
- and kl4, yl4
- mov r26, kl4
- rol r26
- rol kl1
- rol kl2
- rol kl3
- rol kl4
- eor yr1, kl1
- eor yr2, kl2
- eor yr3, kl3
- eor yr4, kl4
- ret
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-B1 = 18
-B2 = 19
-.global camellia128_keyop_rot15
-camellia128_keyop_rot15:
- movw r30, r24 ; Z points at LSB of kl ;-- 0
- ldi r22, 2
-2: adiw r30, 15 ;-- 15
- ld r21, Z
- ld r20, -Z ;-- 14
- movw B1, r20 ; store Backup of the 2 MSB of kl
- ror r20
-
- ldi r21, 14
-1: ld r20, -Z ;-- 13..0
- ror r20
- std Z+2, r20 ;-- (15..2)
- dec r21
- brne 1b
-
- ror B2
- ror B1
- st Z+, B1 ;-- 1
- st Z, B2
- adiw r30, 15 ;-- 16
-
- dec r22
- brne 2b
- ret
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-.global camellia128_keyop_rot17
-camellia128_keyop_rot17:
- push r8
- push r9
- push r10
- push r11
- push r12
- push r13
- push r14
- push r15
- push r16
- push r17
- clt
- movw r30, r24
- clr r27
-2: ldi r26, 8
- mov r1, r26
- lsl r1 ; r1=16
- ;push r1
- ; load 128bit value
- ldd r0, Z+15
- rol r0
-1: ld r0, Z+
- rol r0
- st X+, r0
- dec r1
- brne 1b
-
- st -Z, 21
- st -Z, 20
- st -Z, 19
- st -Z, 18
- st -Z, 17
- st -Z, 16
- st -Z, 15
- st -Z, 14 ;--
- st -Z, 13
- st -Z, 12
- st -Z, 11
- st -Z, 10
- st -Z, 9
- st -Z, 8
- st -Z, 23
- st -Z, 22
-
- brts 2f
- set
- adiw r30, 16
- rjmp 2b
-2:
- pop r17
- pop r16
- pop r15
- pop r14
- pop r13
- pop r12
- pop r11
- pop r10
- pop r9
- pop r8
- ret
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-.global camellia128_keyop
-camellia128_keyop:
- cpi r22, 1
- breq camellia128_keyop_rot17
- rjmp camellia128_keyop_rot15
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-B1 = 18
-B2 = 19
-.global camellia128_keyop_inv_rot15
-camellia128_keyop_inv_rot15:
- movw r30, r24 ; Z points at LSB of kl ;-- 0
- movw r26, r24 ; X also
- ldi r22, 2
-2: ;-- 0
- ld r20, Z+ ;-- 0/1
- ld r21, Z+ ;-- 1/2
- movw B1, r20 ; store Backup of the 2 LSB of kl
- rol r21
-
- ldi r20, 14
-1: ld r21, Z+ ;-- 2/14..3/16
- rol r21
- st X+, r21 ;-- (0..13)/(1..14)
- dec r20
- brne 1b
-
- rol B1
- rol B2
- st X+, B1 ;-- 14/15
- st X+, B2 ;-- 15/16
-
- dec r22
- brne 2b
- ret
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-.global camellia128_keyop_inv_rot17
-camellia128_keyop_inv_rot17:
- push r8
- push r9
- push r10
- push r11
- push r12
- push r13
- push r14
- push r15
- push r16
- push r17
- clt
- movw r30, r24
- clr r27
-2: ldi r26, 8
- mov r1, r26
- lsl r1 ; r1=16
- ; load 128bit value
-
- ld r0, Z
- adiw r30, 16
- ror r0
-1: ld r0, -Z
- ror r0
- st X+, r0
- dec r1
- brne 1b
-
- st Z+, 21
- st Z+, 20
- st Z+, 19
- st Z+, 18
- st Z+, 17
- st Z+, 16
- st Z+, 15
- st Z+, 14 ;--
- st Z+, 13
- st Z+, 12
- st Z+, 11
- st Z+, 10
- st Z+, 9
- st Z+, 8
- st Z+, 23
- st Z+, 22
-
- brts 2f
- set
-; adiw r30, 16
- rjmp 2b
-2:
- pop r17
- pop r16
- pop r15
- pop r14
- pop r13
- pop r12
- pop r11
- pop r10
- pop r9
- pop r8
- ret
-
-;##############################################################################
-; param s: r24-r25
-; param q: r22
-.global camellia128_keyop_inv
-camellia128_keyop_inv:
- cpi r22, 1
- breq camellia128_keyop_inv_rot17
- rjmp camellia128_keyop_inv_rot15
-
-;##############################################################################
-; param p: r24-r25 pointer to data
-; param l: r22 length of word
-.global change_endian
-change_endian:
- movw r26, r24
- movw r30, r24
- add r30, r22
- adc r31, r1
- lsr r22
-1:
- ld r20, X
- ld r21, -Z
- st X+, r21
- st Z, r20
- dec r22
- brne 1b
- ret
-
-;##############################################################################
-
-#define SEL_KA 1
-#define SEL_KL 0
-#define KEY_POSTC1 0x00
-#define KEY_POSTC2 0x01
-#define KEY_INC2 0x02
-#define KEY_DIR 0x04
-#define KEY_DIR_NORM 0x00
-#define KEY_DIR_INV 0x04
-#define KEY_AMMOUNT 0x08
-#define KEY_ROL17 0x08
-#define KEY_ROL15 0x00
-/*
-void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice){
- uint8_t i;
- uint64_t* k[4];
- k[0] = &(s->kll);
- k[1] = &(s->klr);
- k[2] = &(s->kal);
- k[3] = &(s->kar);
- for(i=0; i<3; ++i){ / * each cycle * /
- br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
- keychoice >>= 1;
-
- if((i == 1) && (roundop&KEY_INC2)){
- ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
- }
-
- bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
- keychoice >>= 1;
-
- / * check if we should do some keyop * /
- if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
- ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
- / * isn't it fuckin nice what we can do in C?! * /
- }
- }
-}
-*/
-; param s: r24-r25
-; param bl: r22-r23
-; param br: r20-r21
-; param roundop: r18
-; param keychoice: r16
-s1 = 24
-s2 = 25
-bl1 = 22
-bl2 = 23
-br1 = 20
-br2 = 22
-xro = 18
-kc = 16
-xro_sec = 17
-br1_sec = 10
-br2_sec = 11
-bl1_sec = 12
-bl2_sec = 13
-s1_sec = 14
-t = 9
-loop_cnt = 8
-keyop_time = 7
-
-.global camellia_6rounds
-camellia_6rounds:
- push r17
- push r16
- push r15
- push r14
- push r13
- push r12
- push r11
- push r10
- push r9
- push r8
- push r7
-
- ldi r17, 6
- mov loop_cnt, r17
- mov xro_sec, xro
- movw br1_sec, br1
- movw bl1_sec, bl1
- movw s1_sec, s1
- clr keyop_time
- inc keyop_time
- sec
- rol keyop_time // keyop_time == 3
- SBRC xro, 1 // KEY_INC2
- rjmp 1f
- SBRS xro, 0 // KEY_POSTC1
- inc keyop_time
- SBRS xro, 0 // KEY_POSTC1
- inc keyop_time
- rjmp 2f
-1: inc keyop_time
-2:
-main_loop:
- /* now we load the key to r18-r25 */
- movw r26, s1_sec
- SBRC kc, 0 /* select between KA and KL */
- adiw r26, 16
- SBRC xro_sec, 2 // KEY_DIR
- rjmp 2f
- SBRS loop_cnt, 0 /* enc */
- adiw r26, 8
- rjmp 3f
-2: SBRC loop_cnt, 0 /* dec */
- adiw r26, 8
- rjmp 3f
-3:
- lsr kc
- ld r18, X+
- ld r19, X+
- ld r20, X+
- ld r21, X+
- ld r22, X+
- ld r23, X+
- ld r24, X+
- ld r25, X+
- /* now we xor bl in */
- movw r26, bl1_sec
- ld r0, X+
- eor r18, r0
- ld r0, X+
- eor r19, r0
- ld r0, X+
- eor r20, r0
- ld r0, X+
- eor r21, r0
- ld r0, X+
- eor r22, r0
- ld r0, X+
- eor r23, r0
- ld r0, X+
- eor r24, r0
- ld r0, X+
- eor r25, r0
- /* f(x,k) = p(s(x xor k)) ; xor is done */
- call camellia_s;
- call camellia_p;
-
-// in r26, SPL
-// in r27, SPH
-// sbiw r26, 9
-// dbg_hexdump 10
- /* now we have to xor the result into br */
- clr r31
- ldi r30, 18
- movw r26, br1_sec
-; ldi r1, 8 ;-- this won't work
- clr r1
- sec
- ror r1
- swap r1
-1: ld r0, X
- ld t, Z+
- eor r0, t
- st X+, r0
- dec r1
- brne 1b
-
- /* check for keyop */
- cp loop_cnt, keyop_time
- brne 3f
- movw s1, s1_sec
- ldi r22, 1
- SBRS xro_sec, 3 // KEY_ROL17
- neg r22
- SBRS xro_sec, 2 // KEY_DIR
- rjmp 2f
- rcall camellia128_keyop_inv
- rjmp 3f
-2: rcall camellia128_keyop
-3: /* loop back */
- SWAP_R br1_sec, bl1_sec
- SWAP_R br2_sec, bl2_sec
- dec loop_cnt
- breq 2f
- rjmp main_loop
-2:
- pop r7
- pop r8
- pop r9
- pop r10
- pop r11
- pop r12
- pop r13
- pop r14
- pop r15
- pop r16
- pop r17
- ret
-
-;##############################################################################
-/*
-void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
- uint8_t i;
- s->kll = 0; //((uint64_t*)key)[0];
-
- / * load the key, endian-adjusted, to kll,klr * /
- for(i=0; i<8; ++i){
- s->kll <<= 8;
- s->kll |= *key++;
- }
- for(i=0; i<8; ++i){
- s->klr <<= 8;
- s->klr |= *key++;
- }
-
- s->kal = s->kll;
- s->kar = s->klr;
-
- s->kar ^= camellia_f(s->kal, camellia_sigma[0]);
- s->kal ^= camellia_f(s->kar, camellia_sigma[1]);
-
- s->kal ^= s->kll;
- s->kar ^= s->klr;
-
- s->kar ^= camellia_f(s->kal, camellia_sigma[2]);
- s->kal ^= camellia_f(s->kar, camellia_sigma[3]);
- / * * /
-// uart_putstr("\n\r----------------init finished--------------------");
-}
-*/
-/*
-X64_xor_in:
- ld r0, X+
- eor r18, r0
- ld r0, X+
- eor r19, r0
- ld r0, X+
- eor r20, r0
- ld r0, X+
- eor r21, r0
- ld r0, X+
- eor r22, r0
- ld r0, X+
- eor r23, r0
- ld r0, X+
- eor r24, r0
- ld r0, X+
- eor r25, r0
- ret
-
-X64_load:
- ld r18, X+
- ld r19, X+
- ld r20, X+
- ld r21, X+
- ld r22, X+
- ld r23, X+
- ld r24, X+
- ld r25, X+
- ret
-
-Y64_load_xor_store:
- ld r0, Y
- eor r18, r0
- st Y+, r18
- ld r0, Y
- eor r19, r0
- st Y+, r19
- ld r0, Y
- eor r20, r0
- st Y+, r20
- ld r0, Y
- eor r21, r0
- st Y+, r21
- ld r0, Y
- eor r22, r0
- st Y+, r22
- ld r0, Y
- eor r23, r0
- st Y+, r23
- ld r0, Y
- eor r24, r0
- st Y+, r24
- ld r0, Y
- eor r25, r0
- st Y+, r25
- ret
-
-; param s: r24-r25
-; param *k: r22-r23
-//.global camellia128_init
-camellia128_init:
- push r29
- push r28
- movw r30, r24 ; Z is statepointer
- movw r26, r22 ; X is keypointer
- clr r29
- ldi r28, 18
-// / * load key into kl, ka and kal to r18:r25 * /
- adiw r26, 128/8 ;-- 16
- ldi r16, (128/8)-1
-1: ld r17, -X
- std Z+(128/8), r17
- st Z+, r17
- sbrs r16, 3
- st Y+, r17 ; this should only be done the last 8 rounds 0<=r16<=7
- dec r16
- brpl 1b
-// / * step 1 * /
- ldi r26, lo8(camellia_sigma)
- ldi r27, hi8(camellia_sigma)
- rcall X64_xor_in
- rcall camellia_s
- rcall camellia_p // / * f(x,k) is done * /
- sbiw r30, 128/8
- movw r28, r30 ; Z&Y point on kar now
- call Y64_load_xor_store
-
-// / * step 2 now * /
- rcall X64_xor_in
- rcall camellia_s
- rcall camellia_p // / * f(x,k) is done * /
- rcall Y64_load_xor_store
-
-// / * now the xor part (kl and kr) * /
- sbiw r30, 128/8 ; Z points to klr
- ldi r16, 128/8
-1: ld r0, Z+
- ldd r1, Z+(128/8)-1
- eor r0, r1
- std Z+(128/8)-1, r0
- dec r16
- brne 1b
-
-// / * now s->kar ^= camellia_f(s->kal, camellia_sigma[2]); * /
- rcall X64_load ; load sigma[2]
- movw r26, r28 ; X&Y point at kal
- rcall X64_xor_in
- rcall camellia_s
- rcall camellia_p
- sbiw r28, 128/8/2 ; Y points at kar
- rcall Y64_load_xor_store
-
-// / * now s->kal ^= camellia_f(s->kar, camellia_sigma[3]); * /
- sbiw r26, 128/8 ;
- rcall X64_load ; load kar
- ldi r26, lo8(camellia_sigma+3*8)
- ldi r27, hi8(camellia_sigma+3*8)
- rcall X64_xor_in ; xor sigma[3] in
- rcall camellia_s
- rcall camellia_p
- rcall Y64_load_xor_store
-
- pop r28
- pop r29
- ret
-
-//*/
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* camellia.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef CAMELLIA_H_
-#define CAMELLIA_H_
-
-#include <stdint.h>
-
-typedef struct camellia128_ctx_s{
- uint64_t klr;
- uint64_t kll;
- uint64_t kar;
- uint64_t kal;
-}camellia128_ctx_t;
-
-
-void camellia128_init(const void* key, camellia128_ctx_t* s);
-void camellia128_enc(void* block, const camellia128_ctx_t* s);
-void camellia128_dec(void* block, const camellia128_ctx_t* s);
-
-
-#endif /*CAMELLIA_H_*/
--- /dev/null
+/* camellia-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * File: camellis-asm.S
+ * Author: Daniel Otte
+ * Date: 2006-11-10
+ * License: GPLv3 or later
+ * Description: Implementation of the camellia block cipher algorithm.
+ *
+ */
+
+.macro SWAP_R A, B
+ eor \A, \B
+ eor \B, \A
+ eor \A, \B
+.endm
+
+.macro precall
+ /* push r18 - r27, r30 - r31*/
+ push r0
+ push r1
+ push r18
+ push r19
+ push r20
+ push r21
+ push r22
+ push r23
+ push r24
+ push r25
+ push r26
+ push r27
+ push r30
+ push r31
+ clr r1
+.endm
+
+.macro postcall
+ pop r31
+ pop r30
+ pop r27
+ pop r26
+ pop r25
+ pop r24
+ pop r23
+ pop r22
+ pop r21
+ pop r20
+ pop r19
+ pop r18
+ pop r1
+ pop r0
+.endm
+
+
+.macro hexdump length
+ push r27
+ push r26
+ ldi r25, '\r'
+ mov r24, r25
+ call uart_putc
+ ldi r25, '\n'
+ mov r24, r25
+ call uart_putc
+ pop r26
+ pop r27
+ movw r24, r26
+.if \length > 16
+ ldi r22, lo8(16)
+ ldi r23, hi8(16)
+ push r27
+ push r26
+ call uart_hexdump
+ pop r26
+ pop r27
+ adiw r26, 16
+ hexdump \length-16
+.else
+ ldi r22, lo8(\length)
+ ldi r23, hi8(\length)
+ call uart_hexdump
+.endif
+.endm
+
+/* X points to Block */
+.macro dbg_hexdump length
+ precall
+ hexdump \length
+ postcall
+.endm
+
+SPL = 0x3D
+SPH = 0x3E
+SREG = 0x3F
+NULLr = 1
+
+
+camellia_sbox:
+.byte 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65
+.byte 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189
+.byte 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26
+.byte 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77
+.byte 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153
+.byte 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215
+.byte 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34
+.byte 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80
+.byte 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210
+.byte 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148
+.byte 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226
+.byte 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46
+.byte 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89
+.byte 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250
+.byte 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164
+.byte 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
+
+//.global camellia_sigma
+/*
+camellia_sigma:
+.quad 0xA09E667F3BCC908B
+.quad 0xB67AE8584CAA73B2
+.quad 0xC6EF372FE94F82BE
+.quad 0x54FF53A5F1D36F1C
+.quad 0x10E527FADE682D1D
+.quad 0xB05688C2B3E6C1FD
+*/
+
+
+
+/* uint8_t camellia_s1(uint8_t b) */
+.global camellia_s1
+camellia_s1:
+ ldi r30, lo8(camellia_sbox)
+ ldi r31, hi8(camellia_sbox)
+ add r30, r24
+ adc r31, NULLr
+ lpm r24, Z
+ clr r25
+ ret
+
+.global camellia_s2
+camellia_s2:
+ ldi r30, lo8(camellia_sbox)
+ ldi r31, hi8(camellia_sbox)
+ add r30, r24
+ adc r31, NULLr
+ lpm r24, Z
+ lsl r24
+ adc r24, NULLr
+ clr r25
+ ret
+
+.global camellia_s3
+camellia_s3:
+ ldi r30, lo8(camellia_sbox)
+ ldi r31, hi8(camellia_sbox)
+ add r30, r24
+ adc r31, NULLr
+ lpm r24, Z
+ bst r24, 0
+ lsr r24
+ bld r24, 7
+ clr r25
+ ret
+
+.global camellia_s4
+camellia_s4:
+ ldi r30, lo8(camellia_sbox)
+ ldi r31, hi8(camellia_sbox)
+ lsl r24
+ adc r24, NULLr
+ add r30, r24
+ adc r31, NULLr
+ lpm r24, Z
+ clr r25
+ ret
+
+.global camellia_s
+/* uint64_t camellia_s(uint64_t d){
+ #define D ((uint8_t*)(&d))
+ D[7] = camellia_s1(D[7]); // MSB
+ D[6] = camellia_s2(D[6]);
+ D[5] = camellia_s3(D[5]);
+ D[4] = camellia_s4(D[4]);
+
+ D[3] = camellia_s2(D[3]);
+ D[2] = camellia_s3(D[2]);
+ D[1] = camellia_s4(D[1]);
+ D[0] = camellia_s1(D[0]); // LSB
+ #undef D
+ return d;
+}*/
+; parameters
+; d: r18-r25 (r18 is LSB)
+camellia_s:
+ movw r26, r24 ; backup r24,r25 -> X
+ clr r25
+ rcall camellia_s2
+ mov r26, r24
+
+ mov r24, r27
+ rcall camellia_s1
+ mov r27, r24
+
+ mov r24, r23
+ rcall camellia_s3
+ mov r23, r24
+
+ mov r24, r22
+ rcall camellia_s4
+ mov r22, r24
+
+ mov r24, r21
+ rcall camellia_s2
+ mov r21, r24
+
+ mov r24, r20
+ rcall camellia_s3
+ mov r20, r24
+
+ mov r24, r19
+ rcall camellia_s4
+ mov r19, r24
+
+
+ mov r24, r18
+ rcall camellia_s1
+ mov r18, r24
+
+ movw r24, r26
+ ret
+
+;##############################################################################
+/* uint64_t camellia_p(uint64_t d) */
+; param: r18-r25 (r18 is LSB)
+z1 = 25
+z2 = 24
+z3 = 23
+z4 = 22
+z5 = 21
+z6 = 20
+z7 = 19
+z8 = 18
+
+.global camellia_p
+camellia_p:
+ eor z1, z6
+ eor z2, z7
+ eor z3, z8
+ eor z4, z5
+ eor z5, z3
+ eor z6, z4
+ eor z7, z1
+ eor z8, z2
+ ;---------
+ eor z1, z8
+ eor z2, z5
+ eor z3, z6
+ eor z4, z7
+ eor z5, z4
+ eor z6, z1
+ eor z7, z2
+ eor z8, z3
+ ;---------
+ movw r26, z8
+ movw r30, z6 ; backup z5 bis z8
+ movw z8, z4
+ movw z6, z2
+ movw z4, r26
+ movw z2, r30
+ ret
+
+
+;##############################################################################
+
+/* uint64_t camellia_f(uint64_t x, uint64_t k) */
+; param x: r18-r25
+; param k: r10-r17
+.global camellia_f
+camellia_f:
+ eor r18, r10
+ eor r19, r11
+ eor r20, r12
+ eor r21, r13
+ eor r22, r14
+ eor r23, r15
+ eor r24, r16
+ eor r25, r17
+ rcall camellia_s
+ rcall camellia_p
+ ret
+
+;##############################################################################
+
+/* uint64_t camellia_fl(uint64_t x, uint64_t k) */
+; param x: r18-r25 xl: r22-r25, xr: r18-r21
+; param k: r10-r17 kl: r14-r17, kr: r10-r13
+kl1 = 14
+kl2 = 15
+kl3 = 16
+kl4 = 17
+kr1 = 10
+kr2 = 11
+kr3 = 12
+kr4 = 13
+xr1 = 18
+xr2 = 19
+xr3 = 20
+xr4 = 21
+xl1 = 22
+xl2 = 23
+xl3 = 24
+xl4 = 25
+.global camellia_fl
+camellia_fl:
+ and kl1, xl1
+ and kl2, xl2
+ and kl3, xl3
+ and kl4, xl4
+ mov r26, kl4
+ rol r26
+ rol kl1
+ rol kl2
+ rol kl3
+ rol kl4
+ eor xr1, kl1
+ eor xr2, kl2
+ eor xr3, kl3
+ eor xr4, kl4
+ // that was part one
+ or kr1, xr1
+ or kr2, xr2
+ or kr3, xr3
+ or kr4, xr4
+ eor xl1, kr1
+ eor xl2, kr2
+ eor xl3, kr3
+ eor xl4, kr4
+ ret
+
+;##############################################################################
+
+/* uint64_t camellia_fl_inv(uint64_t y, uint64_t k) */
+; param y: r18-r25 yl: r22-r25, yr: r18-r21
+; param k: r10-r17 kl: r14-r17, kr: r10-r13
+kl1 = 14
+kl2 = 15
+kl3 = 16
+kl4 = 17
+kr1 = 10
+kr2 = 11
+kr3 = 12
+kr4 = 13
+yr1 = 18
+yr2 = 19
+yr3 = 20
+yr4 = 21
+yl1 = 22
+yl2 = 23
+yl3 = 24
+yl4 = 25
+.global camellia_fl_inv
+camellia_fl_inv:
+ or kr1, yr1
+ or kr2, yr2
+ or kr3, yr3
+ or kr4, yr4
+ eor yl1, kr1
+ eor yl2, kr2
+ eor yl3, kr3
+ eor yl4, kr4
+ // the first one is done
+ and kl1, yl1
+ and kl2, yl2
+ and kl3, yl3
+ and kl4, yl4
+ mov r26, kl4
+ rol r26
+ rol kl1
+ rol kl2
+ rol kl3
+ rol kl4
+ eor yr1, kl1
+ eor yr2, kl2
+ eor yr3, kl3
+ eor yr4, kl4
+ ret
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+B1 = 18
+B2 = 19
+.global camellia128_keyop_rot15
+camellia128_keyop_rot15:
+ movw r30, r24 ; Z points at LSB of kl ;-- 0
+ ldi r22, 2
+2: adiw r30, 15 ;-- 15
+ ld r21, Z
+ ld r20, -Z ;-- 14
+ movw B1, r20 ; store Backup of the 2 MSB of kl
+ ror r20
+
+ ldi r21, 14
+1: ld r20, -Z ;-- 13..0
+ ror r20
+ std Z+2, r20 ;-- (15..2)
+ dec r21
+ brne 1b
+
+ ror B2
+ ror B1
+ st Z+, B1 ;-- 1
+ st Z, B2
+ adiw r30, 15 ;-- 16
+
+ dec r22
+ brne 2b
+ ret
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+.global camellia128_keyop_rot17
+camellia128_keyop_rot17:
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+ push r16
+ push r17
+ clt
+ movw r30, r24
+ clr r27
+2: ldi r26, 8
+ mov r1, r26
+ lsl r1 ; r1=16
+ ;push r1
+ ; load 128bit value
+ ldd r0, Z+15
+ rol r0
+1: ld r0, Z+
+ rol r0
+ st X+, r0
+ dec r1
+ brne 1b
+
+ st -Z, 21
+ st -Z, 20
+ st -Z, 19
+ st -Z, 18
+ st -Z, 17
+ st -Z, 16
+ st -Z, 15
+ st -Z, 14 ;--
+ st -Z, 13
+ st -Z, 12
+ st -Z, 11
+ st -Z, 10
+ st -Z, 9
+ st -Z, 8
+ st -Z, 23
+ st -Z, 22
+
+ brts 2f
+ set
+ adiw r30, 16
+ rjmp 2b
+2:
+ pop r17
+ pop r16
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ ret
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+.global camellia128_keyop
+camellia128_keyop:
+ cpi r22, 1
+ breq camellia128_keyop_rot17
+ rjmp camellia128_keyop_rot15
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+B1 = 18
+B2 = 19
+.global camellia128_keyop_inv_rot15
+camellia128_keyop_inv_rot15:
+ movw r30, r24 ; Z points at LSB of kl ;-- 0
+ movw r26, r24 ; X also
+ ldi r22, 2
+2: ;-- 0
+ ld r20, Z+ ;-- 0/1
+ ld r21, Z+ ;-- 1/2
+ movw B1, r20 ; store Backup of the 2 LSB of kl
+ rol r21
+
+ ldi r20, 14
+1: ld r21, Z+ ;-- 2/14..3/16
+ rol r21
+ st X+, r21 ;-- (0..13)/(1..14)
+ dec r20
+ brne 1b
+
+ rol B1
+ rol B2
+ st X+, B1 ;-- 14/15
+ st X+, B2 ;-- 15/16
+
+ dec r22
+ brne 2b
+ ret
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+.global camellia128_keyop_inv_rot17
+camellia128_keyop_inv_rot17:
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+ push r16
+ push r17
+ clt
+ movw r30, r24
+ clr r27
+2: ldi r26, 8
+ mov r1, r26
+ lsl r1 ; r1=16
+ ; load 128bit value
+
+ ld r0, Z
+ adiw r30, 16
+ ror r0
+1: ld r0, -Z
+ ror r0
+ st X+, r0
+ dec r1
+ brne 1b
+
+ st Z+, 21
+ st Z+, 20
+ st Z+, 19
+ st Z+, 18
+ st Z+, 17
+ st Z+, 16
+ st Z+, 15
+ st Z+, 14 ;--
+ st Z+, 13
+ st Z+, 12
+ st Z+, 11
+ st Z+, 10
+ st Z+, 9
+ st Z+, 8
+ st Z+, 23
+ st Z+, 22
+
+ brts 2f
+ set
+; adiw r30, 16
+ rjmp 2b
+2:
+ pop r17
+ pop r16
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ ret
+
+;##############################################################################
+; param s: r24-r25
+; param q: r22
+.global camellia128_keyop_inv
+camellia128_keyop_inv:
+ cpi r22, 1
+ breq camellia128_keyop_inv_rot17
+ rjmp camellia128_keyop_inv_rot15
+
+;##############################################################################
+; param p: r24-r25 pointer to data
+; param l: r22 length of word
+.global change_endian
+change_endian:
+ movw r26, r24
+ movw r30, r24
+ add r30, r22
+ adc r31, r1
+ lsr r22
+1:
+ ld r20, X
+ ld r21, -Z
+ st X+, r21
+ st Z, r20
+ dec r22
+ brne 1b
+ ret
+
+;##############################################################################
+
+#define SEL_KA 1
+#define SEL_KL 0
+#define KEY_POSTC1 0x00
+#define KEY_POSTC2 0x01
+#define KEY_INC2 0x02
+#define KEY_DIR 0x04
+#define KEY_DIR_NORM 0x00
+#define KEY_DIR_INV 0x04
+#define KEY_AMMOUNT 0x08
+#define KEY_ROL17 0x08
+#define KEY_ROL15 0x00
+/*
+void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice){
+ uint8_t i;
+ uint64_t* k[4];
+ k[0] = &(s->kll);
+ k[1] = &(s->klr);
+ k[2] = &(s->kal);
+ k[3] = &(s->kar);
+ for(i=0; i<3; ++i){ / * each cycle * /
+ br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
+ keychoice >>= 1;
+
+ if((i == 1) && (roundop&KEY_INC2)){
+ ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
+ }
+
+ bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
+ keychoice >>= 1;
+
+ / * check if we should do some keyop * /
+ if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
+ ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
+ / * isn't it fuckin nice what we can do in C?! * /
+ }
+ }
+}
+*/
+; param s: r24-r25
+; param bl: r22-r23
+; param br: r20-r21
+; param roundop: r18
+; param keychoice: r16
+s1 = 24
+s2 = 25
+bl1 = 22
+bl2 = 23
+br1 = 20
+br2 = 22
+xro = 18
+kc = 16
+xro_sec = 17
+br1_sec = 10
+br2_sec = 11
+bl1_sec = 12
+bl2_sec = 13
+s1_sec = 14
+t = 9
+loop_cnt = 8
+keyop_time = 7
+
+.global camellia_6rounds
+camellia_6rounds:
+ push r17
+ push r16
+ push r15
+ push r14
+ push r13
+ push r12
+ push r11
+ push r10
+ push r9
+ push r8
+ push r7
+
+ ldi r17, 6
+ mov loop_cnt, r17
+ mov xro_sec, xro
+ movw br1_sec, br1
+ movw bl1_sec, bl1
+ movw s1_sec, s1
+ clr keyop_time
+ inc keyop_time
+ sec
+ rol keyop_time // keyop_time == 3
+ SBRC xro, 1 // KEY_INC2
+ rjmp 1f
+ SBRS xro, 0 // KEY_POSTC1
+ inc keyop_time
+ SBRS xro, 0 // KEY_POSTC1
+ inc keyop_time
+ rjmp 2f
+1: inc keyop_time
+2:
+main_loop:
+ /* now we load the key to r18-r25 */
+ movw r26, s1_sec
+ SBRC kc, 0 /* select between KA and KL */
+ adiw r26, 16
+ SBRC xro_sec, 2 // KEY_DIR
+ rjmp 2f
+ SBRS loop_cnt, 0 /* enc */
+ adiw r26, 8
+ rjmp 3f
+2: SBRC loop_cnt, 0 /* dec */
+ adiw r26, 8
+ rjmp 3f
+3:
+ lsr kc
+ ld r18, X+
+ ld r19, X+
+ ld r20, X+
+ ld r21, X+
+ ld r22, X+
+ ld r23, X+
+ ld r24, X+
+ ld r25, X+
+ /* now we xor bl in */
+ movw r26, bl1_sec
+ ld r0, X+
+ eor r18, r0
+ ld r0, X+
+ eor r19, r0
+ ld r0, X+
+ eor r20, r0
+ ld r0, X+
+ eor r21, r0
+ ld r0, X+
+ eor r22, r0
+ ld r0, X+
+ eor r23, r0
+ ld r0, X+
+ eor r24, r0
+ ld r0, X+
+ eor r25, r0
+ /* f(x,k) = p(s(x xor k)) ; xor is done */
+ call camellia_s;
+ call camellia_p;
+
+// in r26, SPL
+// in r27, SPH
+// sbiw r26, 9
+// dbg_hexdump 10
+ /* now we have to xor the result into br */
+ clr r31
+ ldi r30, 18
+ movw r26, br1_sec
+; ldi r1, 8 ;-- this won't work
+ clr r1
+ sec
+ ror r1
+ swap r1
+1: ld r0, X
+ ld t, Z+
+ eor r0, t
+ st X+, r0
+ dec r1
+ brne 1b
+
+ /* check for keyop */
+ cp loop_cnt, keyop_time
+ brne 3f
+ movw s1, s1_sec
+ ldi r22, 1
+ SBRS xro_sec, 3 // KEY_ROL17
+ neg r22
+ SBRS xro_sec, 2 // KEY_DIR
+ rjmp 2f
+ rcall camellia128_keyop_inv
+ rjmp 3f
+2: rcall camellia128_keyop
+3: /* loop back */
+ SWAP_R br1_sec, bl1_sec
+ SWAP_R br2_sec, bl2_sec
+ dec loop_cnt
+ breq 2f
+ rjmp main_loop
+2:
+ pop r7
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+ pop r12
+ pop r13
+ pop r14
+ pop r15
+ pop r16
+ pop r17
+ ret
+
+;##############################################################################
+/*
+void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
+ uint8_t i;
+ s->kll = 0; //((uint64_t*)key)[0];
+
+ / * load the key, endian-adjusted, to kll,klr * /
+ for(i=0; i<8; ++i){
+ s->kll <<= 8;
+ s->kll |= *key++;
+ }
+ for(i=0; i<8; ++i){
+ s->klr <<= 8;
+ s->klr |= *key++;
+ }
+
+ s->kal = s->kll;
+ s->kar = s->klr;
+
+ s->kar ^= camellia_f(s->kal, camellia_sigma[0]);
+ s->kal ^= camellia_f(s->kar, camellia_sigma[1]);
+
+ s->kal ^= s->kll;
+ s->kar ^= s->klr;
+
+ s->kar ^= camellia_f(s->kal, camellia_sigma[2]);
+ s->kal ^= camellia_f(s->kar, camellia_sigma[3]);
+ / * * /
+// uart_putstr("\n\r----------------init finished--------------------");
+}
+*/
+/*
+X64_xor_in:
+ ld r0, X+
+ eor r18, r0
+ ld r0, X+
+ eor r19, r0
+ ld r0, X+
+ eor r20, r0
+ ld r0, X+
+ eor r21, r0
+ ld r0, X+
+ eor r22, r0
+ ld r0, X+
+ eor r23, r0
+ ld r0, X+
+ eor r24, r0
+ ld r0, X+
+ eor r25, r0
+ ret
+
+X64_load:
+ ld r18, X+
+ ld r19, X+
+ ld r20, X+
+ ld r21, X+
+ ld r22, X+
+ ld r23, X+
+ ld r24, X+
+ ld r25, X+
+ ret
+
+Y64_load_xor_store:
+ ld r0, Y
+ eor r18, r0
+ st Y+, r18
+ ld r0, Y
+ eor r19, r0
+ st Y+, r19
+ ld r0, Y
+ eor r20, r0
+ st Y+, r20
+ ld r0, Y
+ eor r21, r0
+ st Y+, r21
+ ld r0, Y
+ eor r22, r0
+ st Y+, r22
+ ld r0, Y
+ eor r23, r0
+ st Y+, r23
+ ld r0, Y
+ eor r24, r0
+ st Y+, r24
+ ld r0, Y
+ eor r25, r0
+ st Y+, r25
+ ret
+
+; param s: r24-r25
+; param *k: r22-r23
+//.global camellia128_init
+camellia128_init:
+ push r29
+ push r28
+ movw r30, r24 ; Z is statepointer
+ movw r26, r22 ; X is keypointer
+ clr r29
+ ldi r28, 18
+// / * load key into kl, ka and kal to r18:r25 * /
+ adiw r26, 128/8 ;-- 16
+ ldi r16, (128/8)-1
+1: ld r17, -X
+ std Z+(128/8), r17
+ st Z+, r17
+ sbrs r16, 3
+ st Y+, r17 ; this should only be done the last 8 rounds 0<=r16<=7
+ dec r16
+ brpl 1b
+// / * step 1 * /
+ ldi r26, lo8(camellia_sigma)
+ ldi r27, hi8(camellia_sigma)
+ rcall X64_xor_in
+ rcall camellia_s
+ rcall camellia_p // / * f(x,k) is done * /
+ sbiw r30, 128/8
+ movw r28, r30 ; Z&Y point on kar now
+ call Y64_load_xor_store
+
+// / * step 2 now * /
+ rcall X64_xor_in
+ rcall camellia_s
+ rcall camellia_p // / * f(x,k) is done * /
+ rcall Y64_load_xor_store
+
+// / * now the xor part (kl and kr) * /
+ sbiw r30, 128/8 ; Z points to klr
+ ldi r16, 128/8
+1: ld r0, Z+
+ ldd r1, Z+(128/8)-1
+ eor r0, r1
+ std Z+(128/8)-1, r0
+ dec r16
+ brne 1b
+
+// / * now s->kar ^= camellia_f(s->kal, camellia_sigma[2]); * /
+ rcall X64_load ; load sigma[2]
+ movw r26, r28 ; X&Y point at kal
+ rcall X64_xor_in
+ rcall camellia_s
+ rcall camellia_p
+ sbiw r28, 128/8/2 ; Y points at kar
+ rcall Y64_load_xor_store
+
+// / * now s->kal ^= camellia_f(s->kar, camellia_sigma[3]); * /
+ sbiw r26, 128/8 ;
+ rcall X64_load ; load kar
+ ldi r26, lo8(camellia_sigma+3*8)
+ ldi r27, hi8(camellia_sigma+3*8)
+ rcall X64_xor_in ; xor sigma[3] in
+ rcall camellia_s
+ rcall camellia_p
+ rcall Y64_load_xor_store
+
+ pop r28
+ pop r29
+ ret
+
+//*/
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* camellia.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef CAMELLIA_H_
+#define CAMELLIA_H_
+
+#include <stdint.h>
+
+typedef struct camellia128_ctx_s{
+ uint64_t klr;
+ uint64_t kll;
+ uint64_t kar;
+ uint64_t kal;
+}camellia128_ctx_t;
+
+
+void camellia128_init(const void* key, camellia128_ctx_t* s);
+void camellia128_enc(void* block, const camellia128_ctx_t* s);
+void camellia128_dec(void* block, const camellia128_ctx_t* s);
+
+
+#endif /*CAMELLIA_H_*/
--- /dev/null
+/* camellia128-stub.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ *
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include "camellia.h"
+#if 0
+ #include "cli.h"
+ #include "debug.h"
+ #include <util/delay.h>
+#endif
+/*****************************************************************************/
+uint64_t camellia_f(uint64_t x, uint64_t k);
+/*****************************************************************************/
+uint64_t camellia_fl(uint64_t x, uint64_t k);
+/*****************************************************************************/
+uint64_t camellia_fl_inv(uint64_t y, uint64_t k);
+/*****************************************************************************/
+void change_endian(void* data, uint8_t length);
+/*
+uint64_t PROGMEM camellia_sigma[6]={ / * 64 byte table * /
+ 0xA09E667F3BCC908BLL,
+ 0xB67AE8584CAA73B2LL,
+ 0xC6EF372FE94F82BELL,
+ 0x54FF53A5F1D36F1CLL,
+ 0x10E527FADE682D1DLL,
+ 0xB05688C2B3E6C1FDLL
+};
+*/
+uint32_t PROGMEM camellia_sigma[12]={ /* 48 byte table */
+ 0x3BCC908BL, 0xA09E667FL,
+ 0x4CAA73B2L, 0xB67AE858L,
+ 0xE94F82BEL, 0xC6EF372FL,
+ 0xF1D36F1CL, 0x54FF53A5L,
+ 0xDE682D1DL, 0x10E527FAL,
+ 0xB3E6C1FDL, 0xB05688C2L
+};
+
+/* an ugly macro to load an entry form the table above */
+/*
+#define SIGMA(p) (( ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+1)))<<32) | \
+ ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+0))) )
+*/
+#define SIGMA(p) (( ((uint64_t)(pgm_read_dword(&(((prog_uint32_t*)camellia_sigma)[2*(p)+1]))))<<32) | \
+ ((uint64_t)(pgm_read_dword(&(((prog_uint32_t*)camellia_sigma)[2*(p)+0])))) )
+
+
+
+/*****************************************************************************/
+/*
+void camellia128_ctx_dump(camellia128_ctx_t *s){
+ cli_putstr_P(PSTR("\r\n==State Dump=="));
+ cli_putstr_P(PSTR("\n\rKAl: ")); cli_hexdump(&(s->kal), 8);
+ cli_putstr_P(PSTR("\n\rKAr: ")); cli_hexdump(&(s->kar), 8);
+ cli_putstr_P(PSTR("\n\rKLl: ")); cli_hexdump(&(s->kll), 8);
+ cli_putstr_P(PSTR("\n\rKLr: ")); cli_hexdump(&(s->klr), 8);
+ return;
+}
+*/
+/*****************************************************************************/
+/* extern prog_uint64_t camellia_sigma[6]; */
+
+void camellia128_init(const void* key, camellia128_ctx_t* s){
+ uint8_t i;
+ s->kll = 0; /* ((uint64_t*)key)[0]; */
+
+ /* load the key, endian-adjusted, to kll,klr */
+ for(i=0; i<8; ++i){
+ s->kll <<= 8;
+ s->kll |= *((uint8_t*)key);
+ key = (uint8_t*)key+1;
+ }
+ for(i=0; i<8; ++i){
+ s->klr <<= 8;
+ s->klr |= *((uint8_t*)key);
+ key = (uint8_t*)key+1;
+ }
+
+ s->kal = s->kll;
+ s->kar = s->klr;
+
+ s->kar ^= camellia_f(s->kal, SIGMA(0));
+ s->kal ^= camellia_f(s->kar, SIGMA(1));
+
+ s->kal ^= s->kll;
+ s->kar ^= s->klr;
+
+ s->kar ^= camellia_f(s->kal, SIGMA(2));
+ s->kal ^= camellia_f(s->kar, SIGMA(3));
+}
+
+/*****************************************************************************/
+void camellia128_keyop(camellia128_ctx_t* s, int8_t q);
+/*****************************************************************************/
+void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q);
+/*****************************************************************************/
+
+#define SEL_KA 1
+#define SEL_KL 0
+
+#define KEY_POSTC1 0x00
+#define KEY_POSTC2 0x01
+#define KEY_INC2 0x02
+
+#define KEY_DIR 0x04
+#define KEY_DIR_NORM 0x00
+#define KEY_DIR_INV 0x04
+
+#define KEY_AMMOUNT 0x08
+#define KEY_ROL17 0x08
+#define KEY_ROL15 0x00
+
+void camellia_6rounds(const camellia128_ctx_t* s, uint64_t* bl, uint64_t* br,
+ uint8_t roundop, uint8_t keychoice);
+/*****************************************************************************/
+
+
+void camellia128_enc(void* block, const camellia128_ctx_t* s){
+
+ #define BL (((uint64_t*)block)[0])
+ #define BR (((uint64_t*)block)[1])
+ /* endian adjustment */
+ /*BL*/
+ /* 1 2 3 4 5 6 7 8
+ * 8 7 6 5 4 3 2 1
+ */
+
+ uint64_t temp64;
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ /* Prewhitening */
+ BL ^= s->kll;
+ BR ^= s->klr;
+
+ /* the first 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
+ /* FL injection */
+ camellia128_keyop((camellia128_ctx_t*)s, -1);
+ BL = camellia_fl(BL, s->kal);
+ BR = camellia_fl_inv(BR, s->kar);
+ camellia128_keyop((camellia128_ctx_t*)s, -1);
+ /* middle 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
+ /* FL injection */
+ camellia128_keyop((camellia128_ctx_t*)s, 1);
+ BL = camellia_fl(BL, s->kll);
+ BR = camellia_fl_inv(BR, s->klr);
+ camellia128_keyop((camellia128_ctx_t*)s, 1);
+ /* last 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
+ /* Postwhitening */
+ BR ^= s->kal;
+ BL ^= s->kar;
+
+ temp64 = BR;
+ BR = BL;
+ BL = temp64;
+
+ camellia128_keyop((camellia128_ctx_t*)s,1);
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ #undef BL
+ #undef BR
+}
+
+/*****************************************************************************/
+
+void camellia128_dec(void* block, const camellia128_ctx_t* s){
+
+ #define BL (((uint64_t*)block)[1])
+ #define BR (((uint64_t*)block)[0])
+ /* endian adjustment */
+ /*BL*/
+ /* 1 2 3 4 5 6 7 8
+ * 8 7 6 5 4 3 2 1
+ */
+
+ uint64_t temp64;
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ /* Prewhitening */
+ BR ^= s->kal; /* kw3 */
+ BL ^= s->kar; /* kw4 */
+ /* the first 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
+ /* FL injection */
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ BR = camellia_fl(BR, s->klr);
+ BL = camellia_fl_inv(BL, s->kll);
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ /* middle 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
+ /* FL injection */
+ camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
+ BR = camellia_fl(BR, s->kar);
+ BL = camellia_fl_inv(BL, s->kal);
+ camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
+ /* last 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
+
+ /* Postwhitening */
+ BL ^= s->kll; /* kw1 */
+ BR ^= s->klr; /* kw2 */
+
+ temp64 = BR;
+ BR = BL;
+ BL = temp64;
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+
+
+/* EOF */
--- /dev/null
+/* camellia_C.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ *
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include "camellia.h"
+#if 0
+ #include "cli.h"
+ #include "debug.h"
+ #include <util/delay.h>
+#endif
+/*****************************************************************************/
+
+uint8_t rol(uint8_t a, uint8_t n){return ((a<<n) | (a>>(8-n)));}
+
+/*****************************************************************************/
+
+uint8_t ror(uint8_t a, uint8_t n){return ((a<<(8-n)) | (a>>n));}
+
+/*****************************************************************************/
+
+uint32_t rol32(uint32_t a, uint8_t n){
+ return ((a<<n)|(a>>(32-n)));
+}
+
+/*****************************************************************************/
+
+uint64_t rol64(uint64_t a, uint8_t n){
+ return ((a<<n)|(a>>(64-n)));
+}
+
+/*****************************************************************************/
+
+uint8_t camellia_s1_table[256] PROGMEM = {
+ 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
+ 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
+ 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
+ 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
+ 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
+ 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
+ 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
+ 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
+ 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
+ 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
+ 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
+ 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
+ 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
+ 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
+ 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
+ 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
+};
+
+/*****************************************************************************/
+
+uint8_t camellia_s1(uint8_t b){
+ return pgm_read_byte_near(&(camellia_s1_table[b]));
+}
+
+/*****************************************************************************/
+
+uint8_t camellia_s2(uint8_t b){
+ return rol(pgm_read_byte_near(&(camellia_s1_table[b])),1);
+}
+
+/*****************************************************************************/
+
+uint8_t camellia_s3(uint8_t b){
+ return ror(pgm_read_byte_near(&(camellia_s1_table[b])),1);
+}
+
+/*****************************************************************************/
+
+uint8_t camellia_s4(uint8_t b){
+ return pgm_read_byte_near(&(camellia_s1_table[rol(b,1)]));
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_s(uint64_t d){
+// cli_putstr("\n\r S von "); cli_hexdump(&(d), 8);
+ #define D ((uint8_t*)(&d))
+ D[7] = camellia_s1(D[7]);
+ D[6] = camellia_s2(D[6]);
+ D[5] = camellia_s3(D[5]);
+ D[4] = camellia_s4(D[4]);
+
+ D[3] = camellia_s2(D[3]);
+ D[2] = camellia_s3(D[2]);
+ D[1] = camellia_s4(D[1]);
+ D[0] = camellia_s1(D[0]);
+ #undef D
+// cli_putstr(" ist "); cli_hexdump(&(d), 8);
+ return d;
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_p(uint64_t d){
+ uint64_t z=0;
+ #define D ((uint8_t*)(&d))
+ #define Z ((uint8_t*)(&z))
+/*
+ Z[0] = D[4] ^ D[3] ^ D[1];
+ Z[1] = D[5] ^ D[0] ^ D[2];
+ Z[2] = D[6] ^ D[1] ^ D[3];
+ Z[3] = D[7] ^ D[2] ^ D[0];
+ Z[4] = D[0] ^ D[6] ^ D[5];
+ Z[5] = D[1] ^ D[7] ^ D[6];
+ Z[6] = D[2] ^ D[4] ^ D[7];
+ Z[7] = D[3] ^ D[5] ^ D[4];
+*/
+// Z[7] = z1 z3 z4 z6 z7 z8
+// cli_putstr("\n\r P von "); cli_hexdump(&(d), 8);
+
+ Z[7] = D[7] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ D[0];
+ Z[6] = D[7] ^ D[6] ^ D[4] ^ D[3] ^ D[1] ^ D[0];
+ Z[5] = D[7] ^ D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[0];
+ Z[4] = D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ;
+ Z[3] = D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0];
+ Z[2] = D[6] ^ D[5] ^ D[3] ^ D[1] ^ D[0];
+ Z[1] = D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[0];
+ Z[0] = D[7] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ;
+
+// cli_putstr(" ist "); cli_hexdump(&(z), 8);
+
+ #undef Z
+ #undef D
+ return z;
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_f(uint64_t x, uint64_t k){
+ uint64_t y;
+ y = camellia_p(camellia_s(x ^ k));
+ return y;
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_fl(uint64_t x, uint64_t k){
+// uint64_t lx, lk, y;
+ uint32_t lx[2], lk[2], yr, yl;
+ lx[0]=(uint32_t)x;
+ lx[1]=(uint32_t)(x>>32);
+ lk[0]=(uint32_t)k;
+ lk[1]=(uint32_t)(k>>32);
+ #define Y ((uint32_t*)y)
+ #define X ((uint32_t*)lx)
+ #define K ((uint32_t*)lk)
+
+ yr = rol32((X[1]) & (K[1]) ,1) ^ (X[0]); /* Yr */
+ yl = (yr | K[0]) ^ (X[1]); /* Yl */
+
+/*
+ cli_putstr("\r\nFL(");
+ cli_hexdump(&(x), 8);
+ cli_putstr(", ");
+ cli_hexdump(&(k), 8);
+ cli_putstr(") = ");
+ cli_hexdump(y, 8);
+*/
+ #undef K
+ #undef X
+ #undef Y
+ return (((uint64_t)yl)<<32 | yr);
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_fl_inv(uint64_t y, uint64_t k){
+//volatile uint32_t xl, xr;
+ uint32_t ly[2], lk[2], x[2];
+ ly[0]=(uint32_t)y;
+ ly[1]=(uint32_t)(y>>32);
+ lk[0]=(uint32_t)k;
+ lk[1]=(uint32_t)(k>>32);
+ #define Y ((uint32_t*)ly)
+ #define X ((uint32_t*)x)
+ #define K ((uint32_t*)lk)
+
+ X[1]=(Y[0] | K[0]) ^ Y[1];
+ X[0]=rol32((X[1] & K[1]),1) ^ Y[0];
+
+/*
+ cli_putstr("\r\nFL_inv(");
+ cli_hexdump(&(y), 8);
+ cli_putstr(", ");
+ cli_hexdump(&(k), 8);
+ cli_putstr(") = ");
+*/
+ #undef K
+ #undef X
+ #undef Y
+ return ((uint64_t)(x[1]))<<32 | x[0];
+}
+
+/*****************************************************************************/
+
+uint64_t camellia_sigma[6]={
+ 0xA09E667F3BCC908BLL,
+ 0xB67AE8584CAA73B2LL,
+ 0xC6EF372FE94F82BELL,
+ 0x54FF53A5F1D36F1CLL,
+ 0x10E527FADE682D1DLL,
+ 0xB05688C2B3E6C1FDLL
+};
+
+/*****************************************************************************/
+#if 0
+void camellia128_ctx_dump(camellia128_ctx_t *s){
+ cli_putstr("\r\n==State Dump==");
+ cli_putstr("\n\rKAl: "); cli_hexdump(&(s->kal), 8);
+ cli_putstr("\n\rKAr: "); cli_hexdump(&(s->kar), 8);
+ cli_putstr("\n\rKLl: "); cli_hexdump(&(s->kll), 8);
+ cli_putstr("\n\rKLr: "); cli_hexdump(&(s->klr), 8);
+ return;
+}
+#endif
+/*****************************************************************************/
+
+void camellia128_init(const void* key, camellia128_ctx_t* s){
+ uint8_t i;
+ s->kll = 0; //((uint64_t*)key)[0];
+
+ /* load the key, endian-adjusted, to kll,klr */
+ for(i=0; i<8; ++i){
+ s->kll <<= 8;
+ s->kll |= *((uint8_t*)key);
+ key = (uint8_t*)key+1;
+ }
+ for(i=0; i<8; ++i){
+ s->klr <<= 8;
+ s->klr |= *((uint8_t*)key);
+ key = (uint8_t*)key+1;
+ }
+
+ s->kal = s->kll;
+ s->kar = s->klr;
+
+ s->kar ^= camellia_f(s->kal, camellia_sigma[0]);
+ s->kal ^= camellia_f(s->kar, camellia_sigma[1]);
+
+ s->kal ^= s->kll;
+ s->kar ^= s->klr;
+
+ s->kar ^= camellia_f(s->kal, camellia_sigma[2]);
+ s->kal ^= camellia_f(s->kar, camellia_sigma[3]);
+ /**/
+// cli_putstr("\n\r----------------init finished--------------------");
+}
+
+/*****************************************************************************/
+
+void camellia128_keyop(camellia128_ctx_t* s, int8_t q){
+ /* first we do 16 bit left-rols for kl and ka (128bit each) */
+ uint32_t temp;
+
+ temp = (s->kal)>>(64-16-q);
+ s->kal = s->kal<<(16+q) | s->kar>>(64-16-q);
+ s->kar = s->kar<<(16+q) | temp;
+
+ temp = (s->kll)>>(64-16-q);
+ s->kll = s->kll<<(16+q) | s->klr>>(64-16-q);
+ s->klr = s->klr<<(16+q) | temp;
+ /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
+}
+
+/*****************************************************************************/
+
+void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q){
+ /* first we do 16 bit right-rols for kl and ka (128bit each) */
+ uint32_t temp;
+
+ temp = (s->kar)&(0xffffff>>(24-16-q));
+ s->kar = s->kar>>(16+q) | s->kal<<(64-16-q);
+ s->kal = s->kal>>(16+q) | ((uint64_t)temp)<<(64-16-q);
+
+ temp = (s->klr)&(0xffffff>>(24-16-q));
+ s->klr = s->klr>>(16+q) | s->kll<<(64-16-q);
+ s->kll = s->kll>>(16+q) | ((uint64_t)temp)<<(64-16-q);
+ /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
+}
+
+/*****************************************************************************/
+
+#define SEL_KA 1
+#define SEL_KL 0
+
+#define KEY_POSTC1 0x00
+#define KEY_POSTC2 0x01
+#define KEY_INC2 0x02
+
+#define KEY_DIR 0x04
+#define KEY_DIR_NORM 0x00
+#define KEY_DIR_INV 0x04
+
+#define KEY_AMMOUNT 0x08
+#define KEY_ROL17 0x08
+#define KEY_ROL15 0x00
+
+void camellia_6rounds(const camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice){
+ uint8_t i;
+ uint64_t* k[4];
+ k[0] = &(((camellia128_ctx_t*)s)->kll);
+ k[1] = &(((camellia128_ctx_t*)s)->klr);
+ k[2] = &(((camellia128_ctx_t*)s)->kal);
+ k[3] = &(((camellia128_ctx_t*)s)->kar);
+ for(i=0; i<3; ++i){ /* each cycle */
+ br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
+ keychoice >>= 1;
+
+ if((i == 1) && (roundop&KEY_INC2)){
+ ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
+ }
+
+ bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
+ keychoice >>= 1;
+
+ /* check if we should do some keyop */
+ if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
+ ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
+ /* isn't it fuckin nice what we can do in C?! */
+ }
+ }
+}
+
+/*****************************************************************************/
+
+void change_endian(void* data, uint8_t length){
+ uint8_t i,a;
+ for(i=0; i<length/2; ++i){
+ a = ((uint8_t*)data)[i];
+ ((uint8_t*)data)[i] = ((uint8_t*)data)[length-i-1];
+ ((uint8_t*)data)[length-i-1] = a;
+ }
+}
+
+/*****************************************************************************/
+
+void camellia128_enc(void* block, const camellia128_ctx_t* s){
+
+ #define BL (((uint64_t*)block)[0])
+ #define BR (((uint64_t*)block)[1])
+ /* endian adjustment */
+ /*BL*/
+ /* 1 2 3 4 5 6 7 8
+ * 8 7 6 5 4 3 2 1
+ */
+
+ uint64_t temp64;
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ /* Prewhitening */
+ BL ^= s->kll;
+ BR ^= s->klr;
+
+ /* the first 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
+ /* FL injection */
+ camellia128_keyop((camellia128_ctx_t*)s, -1);
+ BL = camellia_fl(BL, s->kal);
+ BR = camellia_fl_inv(BR, s->kar);
+ camellia128_keyop((camellia128_ctx_t*)s, -1);
+ /* middle 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
+ /* FL injection */
+ camellia128_keyop((camellia128_ctx_t*)s, 1);
+ BL = camellia_fl(BL, s->kll);
+ BR = camellia_fl_inv(BR, s->klr);
+ camellia128_keyop((camellia128_ctx_t*)s, 1);
+ /* last 6 */
+ camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
+ /* Postwhitening */
+ BR ^= s->kal;
+ BL ^= s->kar;
+
+ temp64 = BR;
+ BR = BL;
+ BL = temp64;
+
+ camellia128_keyop((camellia128_ctx_t*)s,1);
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ #undef BL
+ #undef BR
+}
+
+/*****************************************************************************/
+
+void camellia128_dec(void* block, const camellia128_ctx_t* s){
+
+ #define BL (((uint64_t*)block)[1])
+ #define BR (((uint64_t*)block)[0])
+ /* endian adjustment */
+ /*BL*/
+ /* 1 2 3 4 5 6 7 8
+ * 8 7 6 5 4 3 2 1
+ */
+
+ uint64_t temp64;
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ /* Prewhitening */
+ BR ^= s->kal; /* kw3 */
+ BL ^= s->kar; /* kw4 */
+ /* the first 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
+ /* FL injection */
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ BR = camellia_fl(BR, s->klr);
+ BL = camellia_fl_inv(BL, s->kll);
+ camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
+ /* middle 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
+ /* FL injection */
+ camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
+ BR = camellia_fl(BR, s->kar);
+ BL = camellia_fl_inv(BL, s->kal);
+ camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
+ /* last 6 */
+ camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
+
+ /* Postwhitening */
+ BL ^= s->kll; /* kw1 */
+ BR ^= s->klr; /* kw2 */
+
+ temp64 = BR;
+ BR = BL;
+ BL = temp64;
+
+ change_endian(&BL, 64/8);
+ change_endian(&BR, 64/8);
+
+}
+
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+
+
+/* EOF */
+++ /dev/null
-/* camellia128-stub.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- *
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include "camellia.h"
-#if 0
- #include "cli.h"
- #include "debug.h"
- #include <util/delay.h>
-#endif
-/*****************************************************************************/
-uint64_t camellia_f(uint64_t x, uint64_t k);
-/*****************************************************************************/
-uint64_t camellia_fl(uint64_t x, uint64_t k);
-/*****************************************************************************/
-uint64_t camellia_fl_inv(uint64_t y, uint64_t k);
-/*****************************************************************************/
-void change_endian(void* data, uint8_t length);
-/*
-uint64_t PROGMEM camellia_sigma[6]={ / * 64 byte table * /
- 0xA09E667F3BCC908BLL,
- 0xB67AE8584CAA73B2LL,
- 0xC6EF372FE94F82BELL,
- 0x54FF53A5F1D36F1CLL,
- 0x10E527FADE682D1DLL,
- 0xB05688C2B3E6C1FDLL
-};
-*/
-uint32_t PROGMEM camellia_sigma[12]={ /* 48 byte table */
- 0x3BCC908BL, 0xA09E667FL,
- 0x4CAA73B2L, 0xB67AE858L,
- 0xE94F82BEL, 0xC6EF372FL,
- 0xF1D36F1CL, 0x54FF53A5L,
- 0xDE682D1DL, 0x10E527FAL,
- 0xB3E6C1FDL, 0xB05688C2L
-};
-
-/* an ugly macro to load an entry form the table above */
-/*
-#define SIGMA(p) (( ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+1)))<<32) | \
- ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+0))) )
-*/
-#define SIGMA(p) (( ((uint64_t)(pgm_read_dword(&(((prog_uint32_t*)camellia_sigma)[2*(p)+1]))))<<32) | \
- ((uint64_t)(pgm_read_dword(&(((prog_uint32_t*)camellia_sigma)[2*(p)+0])))) )
-
-
-
-/*****************************************************************************/
-/*
-void camellia128_ctx_dump(camellia128_ctx_t *s){
- cli_putstr_P(PSTR("\r\n==State Dump=="));
- cli_putstr_P(PSTR("\n\rKAl: ")); cli_hexdump(&(s->kal), 8);
- cli_putstr_P(PSTR("\n\rKAr: ")); cli_hexdump(&(s->kar), 8);
- cli_putstr_P(PSTR("\n\rKLl: ")); cli_hexdump(&(s->kll), 8);
- cli_putstr_P(PSTR("\n\rKLr: ")); cli_hexdump(&(s->klr), 8);
- return;
-}
-*/
-/*****************************************************************************/
-/* extern prog_uint64_t camellia_sigma[6]; */
-
-void camellia128_init(const void* key, camellia128_ctx_t* s){
- uint8_t i;
- s->kll = 0; /* ((uint64_t*)key)[0]; */
-
- /* load the key, endian-adjusted, to kll,klr */
- for(i=0; i<8; ++i){
- s->kll <<= 8;
- s->kll |= *((uint8_t*)key);
- key = (uint8_t*)key+1;
- }
- for(i=0; i<8; ++i){
- s->klr <<= 8;
- s->klr |= *((uint8_t*)key);
- key = (uint8_t*)key+1;
- }
-
- s->kal = s->kll;
- s->kar = s->klr;
-
- s->kar ^= camellia_f(s->kal, SIGMA(0));
- s->kal ^= camellia_f(s->kar, SIGMA(1));
-
- s->kal ^= s->kll;
- s->kar ^= s->klr;
-
- s->kar ^= camellia_f(s->kal, SIGMA(2));
- s->kal ^= camellia_f(s->kar, SIGMA(3));
-}
-
-/*****************************************************************************/
-void camellia128_keyop(camellia128_ctx_t* s, int8_t q);
-/*****************************************************************************/
-void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q);
-/*****************************************************************************/
-
-#define SEL_KA 1
-#define SEL_KL 0
-
-#define KEY_POSTC1 0x00
-#define KEY_POSTC2 0x01
-#define KEY_INC2 0x02
-
-#define KEY_DIR 0x04
-#define KEY_DIR_NORM 0x00
-#define KEY_DIR_INV 0x04
-
-#define KEY_AMMOUNT 0x08
-#define KEY_ROL17 0x08
-#define KEY_ROL15 0x00
-
-void camellia_6rounds(const camellia128_ctx_t* s, uint64_t* bl, uint64_t* br,
- uint8_t roundop, uint8_t keychoice);
-/*****************************************************************************/
-
-
-void camellia128_enc(void* block, const camellia128_ctx_t* s){
-
- #define BL (((uint64_t*)block)[0])
- #define BR (((uint64_t*)block)[1])
- /* endian adjustment */
- /*BL*/
- /* 1 2 3 4 5 6 7 8
- * 8 7 6 5 4 3 2 1
- */
-
- uint64_t temp64;
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- /* Prewhitening */
- BL ^= s->kll;
- BR ^= s->klr;
-
- /* the first 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
- /* FL injection */
- camellia128_keyop((camellia128_ctx_t*)s, -1);
- BL = camellia_fl(BL, s->kal);
- BR = camellia_fl_inv(BR, s->kar);
- camellia128_keyop((camellia128_ctx_t*)s, -1);
- /* middle 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
- /* FL injection */
- camellia128_keyop((camellia128_ctx_t*)s, 1);
- BL = camellia_fl(BL, s->kll);
- BR = camellia_fl_inv(BR, s->klr);
- camellia128_keyop((camellia128_ctx_t*)s, 1);
- /* last 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
- /* Postwhitening */
- BR ^= s->kal;
- BL ^= s->kar;
-
- temp64 = BR;
- BR = BL;
- BL = temp64;
-
- camellia128_keyop((camellia128_ctx_t*)s,1);
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- #undef BL
- #undef BR
-}
-
-/*****************************************************************************/
-
-void camellia128_dec(void* block, const camellia128_ctx_t* s){
-
- #define BL (((uint64_t*)block)[1])
- #define BR (((uint64_t*)block)[0])
- /* endian adjustment */
- /*BL*/
- /* 1 2 3 4 5 6 7 8
- * 8 7 6 5 4 3 2 1
- */
-
- uint64_t temp64;
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- /* Prewhitening */
- BR ^= s->kal; /* kw3 */
- BL ^= s->kar; /* kw4 */
- /* the first 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
- /* FL injection */
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- BR = camellia_fl(BR, s->klr);
- BL = camellia_fl_inv(BL, s->kll);
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- /* middle 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
- /* FL injection */
- camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
- BR = camellia_fl(BR, s->kar);
- BL = camellia_fl_inv(BL, s->kal);
- camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
- /* last 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
-
- /* Postwhitening */
- BL ^= s->kll; /* kw1 */
- BR ^= s->klr; /* kw2 */
-
- temp64 = BR;
- BR = BL;
- BL = temp64;
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-
-
-
-/* EOF */
+++ /dev/null
-/* camellia_C.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- *
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <avr/io.h>
-#include <avr/pgmspace.h>
-#include "camellia.h"
-#if 0
- #include "cli.h"
- #include "debug.h"
- #include <util/delay.h>
-#endif
-/*****************************************************************************/
-
-uint8_t rol(uint8_t a, uint8_t n){return ((a<<n) | (a>>(8-n)));}
-
-/*****************************************************************************/
-
-uint8_t ror(uint8_t a, uint8_t n){return ((a<<(8-n)) | (a>>n));}
-
-/*****************************************************************************/
-
-uint32_t rol32(uint32_t a, uint8_t n){
- return ((a<<n)|(a>>(32-n)));
-}
-
-/*****************************************************************************/
-
-uint64_t rol64(uint64_t a, uint8_t n){
- return ((a<<n)|(a>>(64-n)));
-}
-
-/*****************************************************************************/
-
-uint8_t camellia_s1_table[256] PROGMEM = {
- 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
- 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
- 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
- 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
- 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
- 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
- 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
- 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
- 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
- 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
- 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
- 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
- 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
- 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
- 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
- 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158
-};
-
-/*****************************************************************************/
-
-uint8_t camellia_s1(uint8_t b){
- return pgm_read_byte_near(&(camellia_s1_table[b]));
-}
-
-/*****************************************************************************/
-
-uint8_t camellia_s2(uint8_t b){
- return rol(pgm_read_byte_near(&(camellia_s1_table[b])),1);
-}
-
-/*****************************************************************************/
-
-uint8_t camellia_s3(uint8_t b){
- return ror(pgm_read_byte_near(&(camellia_s1_table[b])),1);
-}
-
-/*****************************************************************************/
-
-uint8_t camellia_s4(uint8_t b){
- return pgm_read_byte_near(&(camellia_s1_table[rol(b,1)]));
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_s(uint64_t d){
-// cli_putstr("\n\r S von "); cli_hexdump(&(d), 8);
- #define D ((uint8_t*)(&d))
- D[7] = camellia_s1(D[7]);
- D[6] = camellia_s2(D[6]);
- D[5] = camellia_s3(D[5]);
- D[4] = camellia_s4(D[4]);
-
- D[3] = camellia_s2(D[3]);
- D[2] = camellia_s3(D[2]);
- D[1] = camellia_s4(D[1]);
- D[0] = camellia_s1(D[0]);
- #undef D
-// cli_putstr(" ist "); cli_hexdump(&(d), 8);
- return d;
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_p(uint64_t d){
- uint64_t z=0;
- #define D ((uint8_t*)(&d))
- #define Z ((uint8_t*)(&z))
-/*
- Z[0] = D[4] ^ D[3] ^ D[1];
- Z[1] = D[5] ^ D[0] ^ D[2];
- Z[2] = D[6] ^ D[1] ^ D[3];
- Z[3] = D[7] ^ D[2] ^ D[0];
- Z[4] = D[0] ^ D[6] ^ D[5];
- Z[5] = D[1] ^ D[7] ^ D[6];
- Z[6] = D[2] ^ D[4] ^ D[7];
- Z[7] = D[3] ^ D[5] ^ D[4];
-*/
-// Z[7] = z1 z3 z4 z6 z7 z8
-// cli_putstr("\n\r P von "); cli_hexdump(&(d), 8);
-
- Z[7] = D[7] ^ D[5] ^ D[4] ^ D[2] ^ D[1] ^ D[0];
- Z[6] = D[7] ^ D[6] ^ D[4] ^ D[3] ^ D[1] ^ D[0];
- Z[5] = D[7] ^ D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[0];
- Z[4] = D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ;
- Z[3] = D[7] ^ D[6] ^ D[2] ^ D[1] ^ D[0];
- Z[2] = D[6] ^ D[5] ^ D[3] ^ D[1] ^ D[0];
- Z[1] = D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[0];
- Z[0] = D[7] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ;
-
-// cli_putstr(" ist "); cli_hexdump(&(z), 8);
-
- #undef Z
- #undef D
- return z;
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_f(uint64_t x, uint64_t k){
- uint64_t y;
- y = camellia_p(camellia_s(x ^ k));
- return y;
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_fl(uint64_t x, uint64_t k){
-// uint64_t lx, lk, y;
- uint32_t lx[2], lk[2], yr, yl;
- lx[0]=(uint32_t)x;
- lx[1]=(uint32_t)(x>>32);
- lk[0]=(uint32_t)k;
- lk[1]=(uint32_t)(k>>32);
- #define Y ((uint32_t*)y)
- #define X ((uint32_t*)lx)
- #define K ((uint32_t*)lk)
-
- yr = rol32((X[1]) & (K[1]) ,1) ^ (X[0]); /* Yr */
- yl = (yr | K[0]) ^ (X[1]); /* Yl */
-
-/*
- cli_putstr("\r\nFL(");
- cli_hexdump(&(x), 8);
- cli_putstr(", ");
- cli_hexdump(&(k), 8);
- cli_putstr(") = ");
- cli_hexdump(y, 8);
-*/
- #undef K
- #undef X
- #undef Y
- return (((uint64_t)yl)<<32 | yr);
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_fl_inv(uint64_t y, uint64_t k){
-//volatile uint32_t xl, xr;
- uint32_t ly[2], lk[2], x[2];
- ly[0]=(uint32_t)y;
- ly[1]=(uint32_t)(y>>32);
- lk[0]=(uint32_t)k;
- lk[1]=(uint32_t)(k>>32);
- #define Y ((uint32_t*)ly)
- #define X ((uint32_t*)x)
- #define K ((uint32_t*)lk)
-
- X[1]=(Y[0] | K[0]) ^ Y[1];
- X[0]=rol32((X[1] & K[1]),1) ^ Y[0];
-
-/*
- cli_putstr("\r\nFL_inv(");
- cli_hexdump(&(y), 8);
- cli_putstr(", ");
- cli_hexdump(&(k), 8);
- cli_putstr(") = ");
-*/
- #undef K
- #undef X
- #undef Y
- return ((uint64_t)(x[1]))<<32 | x[0];
-}
-
-/*****************************************************************************/
-
-uint64_t camellia_sigma[6]={
- 0xA09E667F3BCC908BLL,
- 0xB67AE8584CAA73B2LL,
- 0xC6EF372FE94F82BELL,
- 0x54FF53A5F1D36F1CLL,
- 0x10E527FADE682D1DLL,
- 0xB05688C2B3E6C1FDLL
-};
-
-/*****************************************************************************/
-#if 0
-void camellia128_ctx_dump(camellia128_ctx_t *s){
- cli_putstr("\r\n==State Dump==");
- cli_putstr("\n\rKAl: "); cli_hexdump(&(s->kal), 8);
- cli_putstr("\n\rKAr: "); cli_hexdump(&(s->kar), 8);
- cli_putstr("\n\rKLl: "); cli_hexdump(&(s->kll), 8);
- cli_putstr("\n\rKLr: "); cli_hexdump(&(s->klr), 8);
- return;
-}
-#endif
-/*****************************************************************************/
-
-void camellia128_init(const void* key, camellia128_ctx_t* s){
- uint8_t i;
- s->kll = 0; //((uint64_t*)key)[0];
-
- /* load the key, endian-adjusted, to kll,klr */
- for(i=0; i<8; ++i){
- s->kll <<= 8;
- s->kll |= *((uint8_t*)key);
- key = (uint8_t*)key+1;
- }
- for(i=0; i<8; ++i){
- s->klr <<= 8;
- s->klr |= *((uint8_t*)key);
- key = (uint8_t*)key+1;
- }
-
- s->kal = s->kll;
- s->kar = s->klr;
-
- s->kar ^= camellia_f(s->kal, camellia_sigma[0]);
- s->kal ^= camellia_f(s->kar, camellia_sigma[1]);
-
- s->kal ^= s->kll;
- s->kar ^= s->klr;
-
- s->kar ^= camellia_f(s->kal, camellia_sigma[2]);
- s->kal ^= camellia_f(s->kar, camellia_sigma[3]);
- /**/
-// cli_putstr("\n\r----------------init finished--------------------");
-}
-
-/*****************************************************************************/
-
-void camellia128_keyop(camellia128_ctx_t* s, int8_t q){
- /* first we do 16 bit left-rols for kl and ka (128bit each) */
- uint32_t temp;
-
- temp = (s->kal)>>(64-16-q);
- s->kal = s->kal<<(16+q) | s->kar>>(64-16-q);
- s->kar = s->kar<<(16+q) | temp;
-
- temp = (s->kll)>>(64-16-q);
- s->kll = s->kll<<(16+q) | s->klr>>(64-16-q);
- s->klr = s->klr<<(16+q) | temp;
- /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
-}
-
-/*****************************************************************************/
-
-void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q){
- /* first we do 16 bit right-rols for kl and ka (128bit each) */
- uint32_t temp;
-
- temp = (s->kar)&(0xffffff>>(24-16-q));
- s->kar = s->kar>>(16+q) | s->kal<<(64-16-q);
- s->kal = s->kal>>(16+q) | ((uint64_t)temp)<<(64-16-q);
-
- temp = (s->klr)&(0xffffff>>(24-16-q));
- s->klr = s->klr>>(16+q) | s->kll<<(64-16-q);
- s->kll = s->kll>>(16+q) | ((uint64_t)temp)<<(64-16-q);
- /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
-}
-
-/*****************************************************************************/
-
-#define SEL_KA 1
-#define SEL_KL 0
-
-#define KEY_POSTC1 0x00
-#define KEY_POSTC2 0x01
-#define KEY_INC2 0x02
-
-#define KEY_DIR 0x04
-#define KEY_DIR_NORM 0x00
-#define KEY_DIR_INV 0x04
-
-#define KEY_AMMOUNT 0x08
-#define KEY_ROL17 0x08
-#define KEY_ROL15 0x00
-
-void camellia_6rounds(const camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice){
- uint8_t i;
- uint64_t* k[4];
- k[0] = &(((camellia128_ctx_t*)s)->kll);
- k[1] = &(((camellia128_ctx_t*)s)->klr);
- k[2] = &(((camellia128_ctx_t*)s)->kal);
- k[3] = &(((camellia128_ctx_t*)s)->kar);
- for(i=0; i<3; ++i){ /* each cycle */
- br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
- keychoice >>= 1;
-
- if((i == 1) && (roundop&KEY_INC2)){
- ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
- }
-
- bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
- keychoice >>= 1;
-
- /* check if we should do some keyop */
- if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
- ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
- /* isn't it fuckin nice what we can do in C?! */
- }
- }
-}
-
-/*****************************************************************************/
-
-void change_endian(void* data, uint8_t length){
- uint8_t i,a;
- for(i=0; i<length/2; ++i){
- a = ((uint8_t*)data)[i];
- ((uint8_t*)data)[i] = ((uint8_t*)data)[length-i-1];
- ((uint8_t*)data)[length-i-1] = a;
- }
-}
-
-/*****************************************************************************/
-
-void camellia128_enc(void* block, const camellia128_ctx_t* s){
-
- #define BL (((uint64_t*)block)[0])
- #define BR (((uint64_t*)block)[1])
- /* endian adjustment */
- /*BL*/
- /* 1 2 3 4 5 6 7 8
- * 8 7 6 5 4 3 2 1
- */
-
- uint64_t temp64;
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- /* Prewhitening */
- BL ^= s->kll;
- BR ^= s->klr;
-
- /* the first 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
- /* FL injection */
- camellia128_keyop((camellia128_ctx_t*)s, -1);
- BL = camellia_fl(BL, s->kal);
- BR = camellia_fl_inv(BR, s->kar);
- camellia128_keyop((camellia128_ctx_t*)s, -1);
- /* middle 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
- /* FL injection */
- camellia128_keyop((camellia128_ctx_t*)s, 1);
- BL = camellia_fl(BL, s->kll);
- BR = camellia_fl_inv(BR, s->klr);
- camellia128_keyop((camellia128_ctx_t*)s, 1);
- /* last 6 */
- camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
- /* Postwhitening */
- BR ^= s->kal;
- BL ^= s->kar;
-
- temp64 = BR;
- BR = BL;
- BL = temp64;
-
- camellia128_keyop((camellia128_ctx_t*)s,1);
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- #undef BL
- #undef BR
-}
-
-/*****************************************************************************/
-
-void camellia128_dec(void* block, const camellia128_ctx_t* s){
-
- #define BL (((uint64_t*)block)[1])
- #define BR (((uint64_t*)block)[0])
- /* endian adjustment */
- /*BL*/
- /* 1 2 3 4 5 6 7 8
- * 8 7 6 5 4 3 2 1
- */
-
- uint64_t temp64;
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- /* Prewhitening */
- BR ^= s->kal; /* kw3 */
- BL ^= s->kar; /* kw4 */
- /* the first 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
- /* FL injection */
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- BR = camellia_fl(BR, s->klr);
- BL = camellia_fl_inv(BL, s->kll);
- camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
- /* middle 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
- /* FL injection */
- camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
- BR = camellia_fl(BR, s->kar);
- BL = camellia_fl_inv(BL, s->kal);
- camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
- /* last 6 */
- camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
-
- /* Postwhitening */
- BL ^= s->kll; /* kw1 */
- BR ^= s->klr; /* kw2 */
-
- temp64 = BR;
- BR = BL;
- BL = temp64;
-
- change_endian(&BL, 64/8);
- change_endian(&BR, 64/8);
-
-}
-
-
-
-/*****************************************************************************/
-/*****************************************************************************/
-
-
-
-/* EOF */
#define UART0_DATABITS UART_DATABITS_8
#define UART0_RXBUFFER_SIZE 64
#define UART0_TXBUFFER_SIZE 64
-#define UART0_SWFLOWCTRL 0
+#define UART0_SWFLOWCTRL 1
#define UART0_THRESH_LOW 10
#define UART0_THRESH_HIGH 48
--- /dev/null
+/* aes sbox */
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+uint8_t aes_sbox[256] PROGMEM = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
--- /dev/null
+/* aes_sbox.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_sbox.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_SBOX_H_
+#define AES_SBOX_H_
+#include <stdint.h>
+
+extern uint8_t aes_sbox[];
+
+#endif
--- /dev/null
+/* gf256mul.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: gf256mul.S
+ * Author: Daniel Otte
+ * Date: 2008-12-19
+ * License: GPLv3 or later
+ * Description: peasant's algorithm for multiplication in GF(2^8)
+ *
+ */
+
+#include <avr/io.h>
+#define OPTIMIZE_SMALL_A
+
+/*
+ * param a: r24
+ * param b: r22
+ * param reducer: r20
+ */
+A = 23
+B = 22
+P = 24
+.global gf256mul
+
+#ifdef OPTIMIZE_SMALL_A
+gf256mul:
+ mov A, r24
+ clr r24
+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
+
+#else
+
+gf256mul:
+ mov r21, r24
+ clr r24
+ ldi r25, 8
+1:
+ lsr A
+ brcc 2f
+ eor P, B
+2:
+ lsl B
+ brcc 3f
+ eor B, r20
+3:
+ dec r25
+ brne 1b
+ ret
+
+#endif
--- /dev/null
+/* gf256mul.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2008-12-19
+ * \license GPLv3
+ * \brief
+ *
+ *
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
--- /dev/null
+/* groestl_large.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file groestl_large.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-06-11
+ * \license GPLv3 or later
+ *
+ */
+
+#include "groestl_large.h"
+#include "aes_sbox.h"
+#include "gf256mul.h"
+#include "memxor.h"
+#include <stdint.h>
+#include <avr/pgmspace.h>
+#include <string.h>
+
+#define ROUNDS 14
+#define POLYNOM 0x1b
+
+#define DEBUG 0
+
+#if DEBUG
+ #include "cli.h"
+ void dump_m(const uint8_t* m){
+ uint8_t i,j;
+ for(i=0; i<16; ++i){
+ cli_putstr_P(PSTR("\r\n"));
+ for(j=0; j<8; ++j){
+ cli_putc(' ');
+ cli_hexdump(m+8*i+j, 1);
+ }
+ }
+ }
+#else
+ #define dump_m(m)
+#endif
+
+static uint8_t matrix[] PROGMEM = {
+ 2, 2, 3, 4, 5, 3, 5, 7,
+ 7, 2, 2, 3, 4, 5, 3, 5,
+ 5, 7, 2, 2, 3, 4, 5, 3,
+ 3, 5, 7, 2, 2, 3, 4, 5,
+ 5, 3, 5, 7, 2, 2, 3, 4,
+ 4, 5, 3, 5, 7, 2, 2, 3,
+ 3, 4, 5, 3, 5, 7, 2, 2,
+ 2, 3, 4, 5, 3, 5, 7, 2
+};
+
+void groestl_large_rounds(uint8_t *m, uint8_t q){
+ uint8_t r,i,j;
+ uint8_t tmp[16];
+ for(r=0; r<ROUNDS; ++r){
+ if(q){
+ m[7] ^= 0xff ^ r;
+ }else{
+ m[0] ^= r;
+ }
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost add-const"));
+ dump_m(m);
+ }
+#endif
+ for(i=0;i<16*8; ++i){
+ m[i] = pgm_read_byte(aes_sbox+m[i]);
+ }
+ for(i=1; i<7; ++i){
+ for(j=0; j<16; ++j)
+ tmp[j] = m[i+8*j];
+ for(j=0; j<16; ++j){
+ m[i+((j-i+16)%16)*8] = tmp[j];
+ }
+ }
+ for(j=0; j<16; ++j)
+ tmp[j] = m[7+8*j];
+ for(j=0; j<16; ++j){
+ m[7+((j-11+16)%16)*8] = tmp[j];
+ }
+
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost shift-bytes"));
+ dump_m(m);
+ }
+#endif
+ for(i=0; i<16; ++i){
+ memcpy(tmp, m+8*i, 8);
+ for(j=0; j<8; ++j){
+ m[j+i*8] = gf256mul(pgm_read_byte(matrix+8*j+0),tmp[0], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+1),tmp[1], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+2),tmp[2], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+3),tmp[3], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+4),tmp[4], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+5),tmp[5], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+6),tmp[6], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+7),tmp[7], POLYNOM);
+ }
+ }
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost mix-bytes"));
+ dump_m(m);
+ }
+#endif
+ }
+}
+
+void groestl384_init(groestl384_ctx_t* ctx){
+ memset(ctx->h, 0, 16*8);
+ ctx->h[8*16-1] = (uint8_t)384;
+ ctx->h[8*16-2] = (uint8_t)(384>>8);
+ ctx->counter = 0;
+}
+
+void groestl512_init(groestl512_ctx_t* ctx){
+ memset(ctx->h, 0, 16*8);
+ ctx->h[8*16-2] = 2;
+ ctx->counter = 0;
+}
+
+void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block){
+ uint8_t tmp1[128], tmp2[128];
+/*
+ for(i=0; i<8; ++i){
+ for(j=0; j<8; ++j){
+ tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
+ }
+ }
+*/
+ memcpy(tmp1, block, 128);
+ memcpy(tmp2, tmp1, 128);
+ memxor(tmp1, ctx->h, 128);
+ groestl_large_rounds(tmp1, 0);
+ groestl_large_rounds(tmp2, 1);
+ memxor(ctx->h, tmp1, 128);
+ memxor(ctx->h, tmp2, 128);
+ ctx->counter++;
+}
+
+void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b){
+ uint8_t buffer[128];
+ while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+ groestl_large_nextBlock(ctx, block);
+ length_b -= GROESTL_LARGE_BLOCKSIZE;
+ block = (uint8_t*)block + GROESTL_LARGE_BLOCKSIZE_B;
+ }
+ memset(buffer, 0, 128);
+ memcpy(buffer, block, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80>>(length_b%8);
+ if(length_b>1024-65){
+ groestl_large_nextBlock(ctx, buffer);
+ memset(buffer, 0, 128-4);
+ }
+ ctx->counter++;
+ buffer[128-1] = (uint8_t)(ctx->counter);
+ buffer[128-2] = (uint8_t)((ctx->counter)>>8);
+ buffer[128-3] = (uint8_t)((ctx->counter)>>16);
+ buffer[128-4] = (uint8_t)((ctx->counter)>>24);
+ groestl_large_nextBlock(ctx, buffer);
+}
+
+void groestl_large_ctx2hash(void* dest, const groestl_large_ctx_t* ctx, uint16_t outlength_b){
+ uint8_t tmp[128];
+ memcpy(tmp, ctx->h, 128);
+ groestl_large_rounds(tmp, 0);
+ memxor(tmp, ctx->h, 128);
+#if DEBUG
+ cli_putstr_P(PSTR("\r\npost finalisation"));
+ dump_m(tmp);
+#endif
+ memcpy(dest, tmp+128-outlength_b/8, outlength_b/8);
+}
+
+void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx){
+ groestl_large_ctx2hash(dest, ctx, 384);
+}
+
+void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx){
+ groestl_large_ctx2hash(dest, ctx, 512);
+}
+
+void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block){
+ groestl_large_nextBlock(ctx, block);
+}
+
+void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block){
+ groestl_large_nextBlock(ctx, block);
+}
+
+void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b){
+ groestl_large_lastBlock(ctx, block, length_b);
+}
+
+void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b){
+ groestl_large_lastBlock(ctx, block, length_b);
+}
+
+void groestl384(void* dest, const void* msg, uint32_t length_b){
+ groestl_large_ctx_t ctx;
+ groestl384_init(&ctx);
+ while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+ groestl_large_nextBlock(&ctx, msg);
+ length_b -= GROESTL_LARGE_BLOCKSIZE;
+ msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
+ }
+ groestl_large_lastBlock(&ctx, msg, length_b);
+ groestl_large_ctx2hash(dest, &ctx, 384);
+}
+
+void groestl512(void* dest, const void* msg, uint32_t length_b){
+ groestl_large_ctx_t ctx;
+ groestl512_init(&ctx);
+ while(length_b>=GROESTL_LARGE_BLOCKSIZE){
+ groestl_large_nextBlock(&ctx, msg);
+ length_b -= GROESTL_LARGE_BLOCKSIZE;
+ msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
+ }
+ groestl_large_lastBlock(&ctx, msg, length_b);
+ groestl_large_ctx2hash(dest, &ctx, 512);
+}
+
+
+
--- /dev/null
+/* groestl_large.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file groestl_large.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-19
+ * \license GPLv3 or later
+ *
+ */
+#ifndef GROESTL_LARGE_H_
+#define GROESTL_LARGE_H_
+
+#include <stdint.h>
+
+#define GROESTL_LARGE_BLOCKSIZE 1024
+#define GROESTL_LARGE_BLOCKSIZE_B ((GROESTL_LARGE_BLOCKSIZE+7)/8)
+#define GROESTL384_BLOCKSIZE GROESTL_LARGE_BLOCKSIZE
+#define GROESTL384_BLOCKSIZE_B GROESTL_LARGE_BLOCKSIZE_B
+#define GROESTL512_BLOCKSIZE GROESTL_LARGE_BLOCKSIZE
+#define GROESTL512_BLOCKSIZE_B GROESTL_LARGE_BLOCKSIZE_B
+
+typedef struct {
+ uint8_t h[8*16];
+ uint32_t counter;
+} groestl_large_ctx_t;
+
+typedef groestl_large_ctx_t groestl384_ctx_t;
+typedef groestl_large_ctx_t groestl512_ctx_t;
+
+void groestl384_init(groestl384_ctx_t* ctx);
+void groestl512_init(groestl512_ctx_t* ctx);
+
+void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block);
+void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block);
+void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block);
+void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx);
+void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx);
+
+void groestl384(void* dest, const void* msg, uint32_t length_b);
+void groestl512(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* GROESTL_GROESTL_H_ */
--- /dev/null
+/* groestl_small.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file groestl_small.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-19
+ * \license GPLv3 or later
+ *
+ */
+
+#include "groestl_small.h"
+#include "aes_sbox.h"
+#include "gf256mul.h"
+#include "memxor.h"
+#include <stdint.h>
+#include <avr/pgmspace.h>
+#include <string.h>
+
+#define ROUNDS 10
+#define POLYNOM 0x1b
+
+#define DEBUG 0
+
+#if DEBUG
+ #include "cli.h"
+ void dump_m(const uint8_t* m){
+ uint8_t i,j;
+ for(i=0; i<8; ++i){
+ cli_putstr_P(PSTR("\r\n"));
+ for(j=0; j<8; ++j){
+ cli_putc(' ');
+ cli_hexdump(m+8*i+j, 1);
+ }
+ }
+ }
+#else
+ #define dump_m(m)
+#endif
+
+static uint8_t matrix[] PROGMEM = {
+ 2, 2, 3, 4, 5, 3, 5, 7,
+ 7, 2, 2, 3, 4, 5, 3, 5,
+ 5, 7, 2, 2, 3, 4, 5, 3,
+ 3, 5, 7, 2, 2, 3, 4, 5,
+ 5, 3, 5, 7, 2, 2, 3, 4,
+ 4, 5, 3, 5, 7, 2, 2, 3,
+ 3, 4, 5, 3, 5, 7, 2, 2,
+ 2, 3, 4, 5, 3, 5, 7, 2
+};
+
+void groestl_small_rounds(uint8_t *m, uint8_t q){
+ uint8_t r,i,j;
+ uint8_t tmp[8];
+ for(r=0; r<ROUNDS; ++r){
+ if(q){
+ m[7] ^= 0xff ^ r;
+ }else{
+ m[0] ^= r;
+ }
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost add-const"));
+ dump_m(m);
+ }
+#endif
+ for(i=0;i<8*8; ++i){
+ m[i] = pgm_read_byte(aes_sbox+m[i]);
+ }
+ for(i=1; i<8; ++i){
+ for(j=0; j<8; ++j)
+ tmp[j] = m[i+8*j];
+ for(j=0; j<8; ++j){
+ m[i+((j-i+8)%8)*8] = tmp[j];
+ }
+ }
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost shift-bytes"));
+ dump_m(m);
+ }
+#endif
+ for(i=0; i<8; ++i){
+ memcpy(tmp, m+8*i, 8);
+ for(j=0; j<8; ++j){
+ m[j+i*8] = gf256mul(pgm_read_byte(matrix+8*j+0),tmp[0], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+1),tmp[1], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+2),tmp[2], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+3),tmp[3], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+4),tmp[4], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+5),tmp[5], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+6),tmp[6], POLYNOM)
+ ^ gf256mul(pgm_read_byte(matrix+8*j+7),tmp[7], POLYNOM);
+ }
+ }
+#if DEBUG
+ if(r<2){
+ cli_putstr_P(PSTR("\r\npost mix-bytes"));
+ dump_m(m);
+ }
+#endif
+ }
+}
+
+void groestl224_init(groestl224_ctx_t* ctx){
+ memset(ctx->h, 0, 8*8);
+ ctx->h[8*8-1] = 224;
+ ctx->counter = 0;
+}
+
+void groestl256_init(groestl256_ctx_t* ctx){
+ memset(ctx->h, 0, 8*8);
+ ctx->h[8*8-2] = 1;
+ ctx->counter = 0;
+}
+
+void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block){
+ uint8_t tmp1[64], tmp2[64];
+/* for(i=0; i<8; ++i){
+ for(j=0; j<8; ++j){
+ tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
+ }
+ }
+*/
+ memcpy(tmp1, block, 64);
+ memcpy(tmp2, tmp1, 64);
+ memxor(tmp1, ctx->h, 64);
+ groestl_small_rounds(tmp1, 0);
+ groestl_small_rounds(tmp2, 1);
+ memxor(ctx->h, tmp1, 64);
+ memxor(ctx->h, tmp2, 64);
+ ctx->counter++;
+}
+
+void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b){
+ uint8_t buffer[64];
+ while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+ groestl_small_nextBlock(ctx, block);
+ length_b -= GROESTL_SMALL_BLOCKSIZE;
+ block = (uint8_t*)block + GROESTL_SMALL_BLOCKSIZE_B;
+ }
+ memset(buffer, 0, 64);
+ memcpy(buffer, block, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80>>(length_b%8);
+ if(length_b>512-65){
+ groestl_small_nextBlock(ctx, buffer);
+ memset(buffer, 0, 64-4);
+ }
+ ctx->counter++;
+ buffer[64-1] = (uint8_t)(ctx->counter);
+ buffer[64-2] = (uint8_t)((ctx->counter)>>8);
+ buffer[64-3] = (uint8_t)((ctx->counter)>>16);
+ buffer[64-4] = (uint8_t)((ctx->counter)>>24);
+ groestl_small_nextBlock(ctx, buffer);
+}
+
+void groestl_small_ctx2hash(void* dest, const groestl_small_ctx_t* ctx, uint16_t outlength_b){
+ uint8_t tmp[64];
+ memcpy(tmp, ctx->h, 64);
+ groestl_small_rounds(tmp, 0);
+ memxor(tmp, ctx->h, 64);
+#if DEBUG
+ cli_putstr_P(PSTR("\r\npost finalisation"));
+ dump_m(tmp);
+#endif
+ memcpy(dest, tmp+64-outlength_b/8, outlength_b/8);
+}
+
+void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx){
+ groestl_small_ctx2hash(dest, ctx, 224);
+}
+
+void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx){
+ groestl_small_ctx2hash(dest, ctx, 256);
+}
+
+void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block){
+ groestl_small_nextBlock(ctx, block);
+}
+
+void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block){
+ groestl_small_nextBlock(ctx, block);
+}
+
+void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b){
+ groestl_small_lastBlock(ctx, block, length_b);
+}
+
+void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b){
+ groestl_small_lastBlock(ctx, block, length_b);
+}
+
+void groestl224(void* dest, const void* msg, uint32_t length_b){
+ groestl_small_ctx_t ctx;
+ groestl224_init(&ctx);
+ while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+ groestl_small_nextBlock(&ctx, msg);
+ length_b -= GROESTL_SMALL_BLOCKSIZE;
+ msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
+ }
+ groestl_small_lastBlock(&ctx, msg, length_b);
+ groestl_small_ctx2hash(dest, &ctx, 224);
+}
+
+void groestl256(void* dest, const void* msg, uint32_t length_b){
+ groestl_small_ctx_t ctx;
+ groestl256_init(&ctx);
+ while(length_b>=GROESTL_SMALL_BLOCKSIZE){
+ groestl_small_nextBlock(&ctx, msg);
+ length_b -= GROESTL_SMALL_BLOCKSIZE;
+ msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
+ }
+ groestl_small_lastBlock(&ctx, msg, length_b);
+ groestl_small_ctx2hash(dest, &ctx, 256);
+}
+
+
+
--- /dev/null
+/* groestl_small.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file groestl_small.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-05-19
+ * \license GPLv3 or later
+ *
+ */
+#ifndef GROESTL_SMALL_H_
+#define GROESTL_SMALL_H_
+
+#include <stdint.h>
+
+#define GROESTL_SMALL_BLOCKSIZE 512
+#define GROESTL_SMALL_BLOCKSIZE_B ((GROESTL_SMALL_BLOCKSIZE+7)/8)
+#define GROESTL224_BLOCKSIZE GROESTL_SMALL_BLOCKSIZE
+#define GROESTL224_BLOCKSIZE_B GROESTL_SMALL_BLOCKSIZE_B
+#define GROESTL256_BLOCKSIZE GROESTL_SMALL_BLOCKSIZE
+#define GROESTL256_BLOCKSIZE_B GROESTL_SMALL_BLOCKSIZE_B
+
+typedef struct {
+ uint8_t h[8*8];
+ uint32_t counter;
+} groestl_small_ctx_t;
+
+typedef groestl_small_ctx_t groestl224_ctx_t;
+typedef groestl_small_ctx_t groestl256_ctx_t;
+
+void groestl224_init(groestl224_ctx_t* ctx);
+void groestl256_init(groestl256_ctx_t* ctx);
+
+void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block);
+void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block);
+void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block);
+void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx);
+void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx);
+
+void groestl224(void* dest, const void* msg, uint32_t length_b);
+void groestl256(void* dest, const void* msg, uint32_t length_b);
+
+#endif /* GROESTL_GROESTL_H_ */
--- /dev/null
+/* memxor.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: memxor.S
+ * Author: Daniel Otte
+ * Date: 2008-08-07
+ * License: GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+ * param dest is passed in r24:r25
+ * param src is passed in r22:r23
+ * param n is passed in r20:r21
+ */
+.global memxor
+memxor:
+ movw r30, r24
+ movw r26, r22
+ movw r24, r20
+ adiw r24, 0
+ breq 2f
+1:
+ ld r20, X+
+ ld r21, Z
+ eor r20, r21
+ st Z+, r20
+ sbiw r24, 1
+ brne 1b
+2:
+ ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
+++ /dev/null
-/* groestl_large.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file groestl_large.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-06-11
- * \license GPLv3 or later
- *
- */
-
-#include "groestl_large.h"
-#include "aes_sbox.h"
-#include "gf256mul.h"
-#include "memxor.h"
-#include <stdint.h>
-#include <avr/pgmspace.h>
-#include <string.h>
-
-#define ROUNDS 14
-#define POLYNOM 0x1b
-
-#define DEBUG 0
-
-#if DEBUG
- #include "cli.h"
- void dump_m(const uint8_t* m){
- uint8_t i,j;
- for(i=0; i<16; ++i){
- cli_putstr_P(PSTR("\r\n"));
- for(j=0; j<8; ++j){
- cli_putc(' ');
- cli_hexdump(m+8*i+j, 1);
- }
- }
- }
-#else
- #define dump_m(m)
-#endif
-
-static uint8_t matrix[] PROGMEM = {
- 2, 2, 3, 4, 5, 3, 5, 7,
- 7, 2, 2, 3, 4, 5, 3, 5,
- 5, 7, 2, 2, 3, 4, 5, 3,
- 3, 5, 7, 2, 2, 3, 4, 5,
- 5, 3, 5, 7, 2, 2, 3, 4,
- 4, 5, 3, 5, 7, 2, 2, 3,
- 3, 4, 5, 3, 5, 7, 2, 2,
- 2, 3, 4, 5, 3, 5, 7, 2
-};
-
-void groestl_large_rounds(uint8_t *m, uint8_t q){
- uint8_t r,i,j;
- uint8_t tmp[16];
- for(r=0; r<ROUNDS; ++r){
- if(q){
- m[7] ^= 0xff ^ r;
- }else{
- m[0] ^= r;
- }
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost add-const"));
- dump_m(m);
- }
-#endif
- for(i=0;i<16*8; ++i){
- m[i] = pgm_read_byte(aes_sbox+m[i]);
- }
- for(i=1; i<7; ++i){
- for(j=0; j<16; ++j)
- tmp[j] = m[i+8*j];
- for(j=0; j<16; ++j){
- m[i+((j-i+16)%16)*8] = tmp[j];
- }
- }
- for(j=0; j<16; ++j)
- tmp[j] = m[7+8*j];
- for(j=0; j<16; ++j){
- m[7+((j-11+16)%16)*8] = tmp[j];
- }
-
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost shift-bytes"));
- dump_m(m);
- }
-#endif
- for(i=0; i<16; ++i){
- memcpy(tmp, m+8*i, 8);
- for(j=0; j<8; ++j){
- m[j+i*8] = gf256mul(pgm_read_byte(matrix+8*j+0),tmp[0], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+1),tmp[1], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+2),tmp[2], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+3),tmp[3], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+4),tmp[4], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+5),tmp[5], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+6),tmp[6], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+7),tmp[7], POLYNOM);
- }
- }
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost mix-bytes"));
- dump_m(m);
- }
-#endif
- }
-}
-
-void groestl384_init(groestl384_ctx_t* ctx){
- memset(ctx->h, 0, 16*8);
- ctx->h[8*16-1] = (uint8_t)384;
- ctx->h[8*16-2] = (uint8_t)(384>>8);
- ctx->counter = 0;
-}
-
-void groestl512_init(groestl512_ctx_t* ctx){
- memset(ctx->h, 0, 16*8);
- ctx->h[8*16-2] = 2;
- ctx->counter = 0;
-}
-
-void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block){
- uint8_t tmp1[128], tmp2[128];
-/*
- for(i=0; i<8; ++i){
- for(j=0; j<8; ++j){
- tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
- }
- }
-*/
- memcpy(tmp1, block, 128);
- memcpy(tmp2, tmp1, 128);
- memxor(tmp1, ctx->h, 128);
- groestl_large_rounds(tmp1, 0);
- groestl_large_rounds(tmp2, 1);
- memxor(ctx->h, tmp1, 128);
- memxor(ctx->h, tmp2, 128);
- ctx->counter++;
-}
-
-void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b){
- uint8_t buffer[128];
- while(length_b>=GROESTL_LARGE_BLOCKSIZE){
- groestl_large_nextBlock(ctx, block);
- length_b -= GROESTL_LARGE_BLOCKSIZE;
- block = (uint8_t*)block + GROESTL_LARGE_BLOCKSIZE_B;
- }
- memset(buffer, 0, 128);
- memcpy(buffer, block, (length_b+7)/8);
- buffer[length_b/8] |= 0x80>>(length_b%8);
- if(length_b>1024-65){
- groestl_large_nextBlock(ctx, buffer);
- memset(buffer, 0, 128-4);
- }
- ctx->counter++;
- buffer[128-1] = (uint8_t)(ctx->counter);
- buffer[128-2] = (uint8_t)((ctx->counter)>>8);
- buffer[128-3] = (uint8_t)((ctx->counter)>>16);
- buffer[128-4] = (uint8_t)((ctx->counter)>>24);
- groestl_large_nextBlock(ctx, buffer);
-}
-
-void groestl_large_ctx2hash(void* dest, const groestl_large_ctx_t* ctx, uint16_t outlength_b){
- uint8_t tmp[128];
- memcpy(tmp, ctx->h, 128);
- groestl_large_rounds(tmp, 0);
- memxor(tmp, ctx->h, 128);
-#if DEBUG
- cli_putstr_P(PSTR("\r\npost finalisation"));
- dump_m(tmp);
-#endif
- memcpy(dest, tmp+128-outlength_b/8, outlength_b/8);
-}
-
-void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx){
- groestl_large_ctx2hash(dest, ctx, 384);
-}
-
-void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx){
- groestl_large_ctx2hash(dest, ctx, 512);
-}
-
-void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block){
- groestl_large_nextBlock(ctx, block);
-}
-
-void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block){
- groestl_large_nextBlock(ctx, block);
-}
-
-void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b){
- groestl_large_lastBlock(ctx, block, length_b);
-}
-
-void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b){
- groestl_large_lastBlock(ctx, block, length_b);
-}
-
-void groestl384(void* dest, const void* msg, uint32_t length_b){
- groestl_large_ctx_t ctx;
- groestl384_init(&ctx);
- while(length_b>=GROESTL_LARGE_BLOCKSIZE){
- groestl_large_nextBlock(&ctx, msg);
- length_b -= GROESTL_LARGE_BLOCKSIZE;
- msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
- }
- groestl_large_lastBlock(&ctx, msg, length_b);
- groestl_large_ctx2hash(dest, &ctx, 384);
-}
-
-void groestl512(void* dest, const void* msg, uint32_t length_b){
- groestl_large_ctx_t ctx;
- groestl512_init(&ctx);
- while(length_b>=GROESTL_LARGE_BLOCKSIZE){
- groestl_large_nextBlock(&ctx, msg);
- length_b -= GROESTL_LARGE_BLOCKSIZE;
- msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
- }
- groestl_large_lastBlock(&ctx, msg, length_b);
- groestl_large_ctx2hash(dest, &ctx, 512);
-}
-
-
-
+++ /dev/null
-/* groestl_large.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file groestl_large.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-19
- * \license GPLv3 or later
- *
- */
-#ifndef GROESTL_LARGE_H_
-#define GROESTL_LARGE_H_
-
-#include <stdint.h>
-
-#define GROESTL_LARGE_BLOCKSIZE 1024
-#define GROESTL_LARGE_BLOCKSIZE_B ((GROESTL_LARGE_BLOCKSIZE+7)/8)
-#define GROESTL384_BLOCKSIZE GROESTL_LARGE_BLOCKSIZE
-#define GROESTL384_BLOCKSIZE_B GROESTL_LARGE_BLOCKSIZE_B
-#define GROESTL512_BLOCKSIZE GROESTL_LARGE_BLOCKSIZE
-#define GROESTL512_BLOCKSIZE_B GROESTL_LARGE_BLOCKSIZE_B
-
-typedef struct {
- uint8_t h[8*16];
- uint32_t counter;
-} groestl_large_ctx_t;
-
-typedef groestl_large_ctx_t groestl384_ctx_t;
-typedef groestl_large_ctx_t groestl512_ctx_t;
-
-void groestl384_init(groestl384_ctx_t* ctx);
-void groestl512_init(groestl512_ctx_t* ctx);
-
-void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block);
-void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block);
-void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block);
-void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx);
-void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx);
-
-void groestl384(void* dest, const void* msg, uint32_t length_b);
-void groestl512(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* GROESTL_GROESTL_H_ */
+++ /dev/null
-/* groestl_small.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file groestl_small.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-19
- * \license GPLv3 or later
- *
- */
-
-#include "groestl_small.h"
-#include "aes_sbox.h"
-#include "gf256mul.h"
-#include "memxor.h"
-#include <stdint.h>
-#include <avr/pgmspace.h>
-#include <string.h>
-
-#define ROUNDS 10
-#define POLYNOM 0x1b
-
-#define DEBUG 0
-
-#if DEBUG
- #include "cli.h"
- void dump_m(const uint8_t* m){
- uint8_t i,j;
- for(i=0; i<8; ++i){
- cli_putstr_P(PSTR("\r\n"));
- for(j=0; j<8; ++j){
- cli_putc(' ');
- cli_hexdump(m+8*i+j, 1);
- }
- }
- }
-#else
- #define dump_m(m)
-#endif
-
-static uint8_t matrix[] PROGMEM = {
- 2, 2, 3, 4, 5, 3, 5, 7,
- 7, 2, 2, 3, 4, 5, 3, 5,
- 5, 7, 2, 2, 3, 4, 5, 3,
- 3, 5, 7, 2, 2, 3, 4, 5,
- 5, 3, 5, 7, 2, 2, 3, 4,
- 4, 5, 3, 5, 7, 2, 2, 3,
- 3, 4, 5, 3, 5, 7, 2, 2,
- 2, 3, 4, 5, 3, 5, 7, 2
-};
-
-void groestl_small_rounds(uint8_t *m, uint8_t q){
- uint8_t r,i,j;
- uint8_t tmp[8];
- for(r=0; r<ROUNDS; ++r){
- if(q){
- m[7] ^= 0xff ^ r;
- }else{
- m[0] ^= r;
- }
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost add-const"));
- dump_m(m);
- }
-#endif
- for(i=0;i<8*8; ++i){
- m[i] = pgm_read_byte(aes_sbox+m[i]);
- }
- for(i=1; i<8; ++i){
- for(j=0; j<8; ++j)
- tmp[j] = m[i+8*j];
- for(j=0; j<8; ++j){
- m[i+((j-i+8)%8)*8] = tmp[j];
- }
- }
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost shift-bytes"));
- dump_m(m);
- }
-#endif
- for(i=0; i<8; ++i){
- memcpy(tmp, m+8*i, 8);
- for(j=0; j<8; ++j){
- m[j+i*8] = gf256mul(pgm_read_byte(matrix+8*j+0),tmp[0], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+1),tmp[1], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+2),tmp[2], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+3),tmp[3], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+4),tmp[4], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+5),tmp[5], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+6),tmp[6], POLYNOM)
- ^ gf256mul(pgm_read_byte(matrix+8*j+7),tmp[7], POLYNOM);
- }
- }
-#if DEBUG
- if(r<2){
- cli_putstr_P(PSTR("\r\npost mix-bytes"));
- dump_m(m);
- }
-#endif
- }
-}
-
-void groestl224_init(groestl224_ctx_t* ctx){
- memset(ctx->h, 0, 8*8);
- ctx->h[8*8-1] = 224;
- ctx->counter = 0;
-}
-
-void groestl256_init(groestl256_ctx_t* ctx){
- memset(ctx->h, 0, 8*8);
- ctx->h[8*8-2] = 1;
- ctx->counter = 0;
-}
-
-void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block){
- uint8_t tmp1[64], tmp2[64];
-/* for(i=0; i<8; ++i){
- for(j=0; j<8; ++j){
- tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
- }
- }
-*/
- memcpy(tmp1, block, 64);
- memcpy(tmp2, tmp1, 64);
- memxor(tmp1, ctx->h, 64);
- groestl_small_rounds(tmp1, 0);
- groestl_small_rounds(tmp2, 1);
- memxor(ctx->h, tmp1, 64);
- memxor(ctx->h, tmp2, 64);
- ctx->counter++;
-}
-
-void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b){
- uint8_t buffer[64];
- while(length_b>=GROESTL_SMALL_BLOCKSIZE){
- groestl_small_nextBlock(ctx, block);
- length_b -= GROESTL_SMALL_BLOCKSIZE;
- block = (uint8_t*)block + GROESTL_SMALL_BLOCKSIZE_B;
- }
- memset(buffer, 0, 64);
- memcpy(buffer, block, (length_b+7)/8);
- buffer[length_b/8] |= 0x80>>(length_b%8);
- if(length_b>512-65){
- groestl_small_nextBlock(ctx, buffer);
- memset(buffer, 0, 64-4);
- }
- ctx->counter++;
- buffer[64-1] = (uint8_t)(ctx->counter);
- buffer[64-2] = (uint8_t)((ctx->counter)>>8);
- buffer[64-3] = (uint8_t)((ctx->counter)>>16);
- buffer[64-4] = (uint8_t)((ctx->counter)>>24);
- groestl_small_nextBlock(ctx, buffer);
-}
-
-void groestl_small_ctx2hash(void* dest, const groestl_small_ctx_t* ctx, uint16_t outlength_b){
- uint8_t tmp[64];
- memcpy(tmp, ctx->h, 64);
- groestl_small_rounds(tmp, 0);
- memxor(tmp, ctx->h, 64);
-#if DEBUG
- cli_putstr_P(PSTR("\r\npost finalisation"));
- dump_m(tmp);
-#endif
- memcpy(dest, tmp+64-outlength_b/8, outlength_b/8);
-}
-
-void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx){
- groestl_small_ctx2hash(dest, ctx, 224);
-}
-
-void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx){
- groestl_small_ctx2hash(dest, ctx, 256);
-}
-
-void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block){
- groestl_small_nextBlock(ctx, block);
-}
-
-void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block){
- groestl_small_nextBlock(ctx, block);
-}
-
-void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b){
- groestl_small_lastBlock(ctx, block, length_b);
-}
-
-void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b){
- groestl_small_lastBlock(ctx, block, length_b);
-}
-
-void groestl224(void* dest, const void* msg, uint32_t length_b){
- groestl_small_ctx_t ctx;
- groestl224_init(&ctx);
- while(length_b>=GROESTL_SMALL_BLOCKSIZE){
- groestl_small_nextBlock(&ctx, msg);
- length_b -= GROESTL_SMALL_BLOCKSIZE;
- msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
- }
- groestl_small_lastBlock(&ctx, msg, length_b);
- groestl_small_ctx2hash(dest, &ctx, 224);
-}
-
-void groestl256(void* dest, const void* msg, uint32_t length_b){
- groestl_small_ctx_t ctx;
- groestl256_init(&ctx);
- while(length_b>=GROESTL_SMALL_BLOCKSIZE){
- groestl_small_nextBlock(&ctx, msg);
- length_b -= GROESTL_SMALL_BLOCKSIZE;
- msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
- }
- groestl_small_lastBlock(&ctx, msg, length_b);
- groestl_small_ctx2hash(dest, &ctx, 256);
-}
-
-
-
+++ /dev/null
-/* groestl_small.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file groestl_small.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-05-19
- * \license GPLv3 or later
- *
- */
-#ifndef GROESTL_SMALL_H_
-#define GROESTL_SMALL_H_
-
-#include <stdint.h>
-
-#define GROESTL_SMALL_BLOCKSIZE 512
-#define GROESTL_SMALL_BLOCKSIZE_B ((GROESTL_SMALL_BLOCKSIZE+7)/8)
-#define GROESTL224_BLOCKSIZE GROESTL_SMALL_BLOCKSIZE
-#define GROESTL224_BLOCKSIZE_B GROESTL_SMALL_BLOCKSIZE_B
-#define GROESTL256_BLOCKSIZE GROESTL_SMALL_BLOCKSIZE
-#define GROESTL256_BLOCKSIZE_B GROESTL_SMALL_BLOCKSIZE_B
-
-typedef struct {
- uint8_t h[8*8];
- uint32_t counter;
-} groestl_small_ctx_t;
-
-typedef groestl_small_ctx_t groestl224_ctx_t;
-typedef groestl_small_ctx_t groestl256_ctx_t;
-
-void groestl224_init(groestl224_ctx_t* ctx);
-void groestl256_init(groestl256_ctx_t* ctx);
-
-void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block);
-void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block);
-void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block);
-void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx);
-void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx);
-
-void groestl224(void* dest, const void* msg, uint32_t length_b);
-void groestl256(void* dest, const void* msg, uint32_t length_b);
-
-#endif /* GROESTL_GROESTL_H_ */
init_system()
+errors = 0
for i in (5..(ARGV.size-1))
errors = run_test(ARGV[i])
if errors == 0
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
* File: memxor.S
* Author: Daniel Otte
* Date: 2008-08-07
* License: GPLv3 or later
* Description: memxor, XORing one block into another
- *
+ *
*/
-
+
/*
* void memxor(void* dest, const void* src, uint16_t n);
*/
movw r30, r24
movw r26, r22
movw r24, r20
- tst r24
- brne 1f
- tst r25
+ adiw r24, 0
breq 2f
1:
ld r20, X+
brne 1b
2:
ret
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
# comment out the following line for removement of AES from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := aes/
$(ALGO_NAME)_OBJ := aes_enc-asm.o aes_dec-asm.o aes_sbox-asm.o aes_invsbox-asm.o \
- aes_keyschedule-asm.o
+ aes_keyschedule-asm.o
$(ALGO_NAME)_TEST_BIN := main-aes-test.o $(CLI_STD) \
nessie_bc_test.o nessie_common.o performance_test.o
$(ALGO_NAME)_NESSIE_TEST := test nessie
BLOCK_CIPHERS += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := aes/
$(ALGO_NAME)_OBJ := aes_enc-asm.o aes_dec-asm_faster.o aes_sbox-asm.o aes_invsbox-asm.o \
- aes_keyschedule-asm.o
+ aes_keyschedule-asm.o
$(ALGO_NAME)_TEST_BIN := main-aes-test.o $(CLI_STD) \
nessie_bc_test.o nessie_common.o performance_test.o
$(ALGO_NAME)_NESSIE_TEST := test nessie
BLOCK_CIPHERS += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := aes/
$(ALGO_NAME)_OBJ := aes_enc.o aes_dec.o aes_sbox.o aes_invsbox.o \
aes_keyschedule.o gf256mul.o \
aes128_enc.o aes128_dec.o aes192_enc.o aes192_dec.o \
# comment out the following line for removement of Blake from the build process
HASHES += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := blake/
$(ALGO_NAME)_OBJ := blake_small.o blake_large.o blake_common.o memxor.o
$(ALGO_NAME)_TEST_BIN := main-blake-test.o hfal_blake_small.o hfal_blake_large.o $(CLI_STD) $(HFAL_STD)
$(ALGO_NAME)_NESSIE_TEST := test nessie
# comment out the following line for removement of Camellia from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := camellia/
$(ALGO_NAME)_OBJ := camellia128-stub.o camellia-asm.o
$(ALGO_NAME)_TEST_BIN := main-camellia-test.o $(CLI_STD) nessie_bc_test.o \
nessie_common.o performance_test.o
# comment out the following line for removement of Grøstl from the build process
HASHES += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := groestl/
$(ALGO_NAME)_OBJ := groestl_small.o groestl_large.o memxor.o aes_sbox.o gf256mul.o
$(ALGO_NAME)_TEST_BIN := hfal_groestl_large.o hfal_groestl_small.o main-groestl-test.o $(CLI_STD) $(HFAL_STD)
$(ALGO_NAME)_NESSIE_TEST := test nessie
# comment out the following line for removement of MUGI_C from the build process
STREAM_CIPHERS += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := mugi/
$(ALGO_NAME)_OBJ := mugi.o gf256mul.o aes_sbox.o
$(ALGO_NAME)_TEST_BIN := main-mugi-test.o $(CLI_STD) \
nessie_stream_test.o nessie_common.o \
# comment out the following line for removement of Skein from the build process
HASHES += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := shabal/
$(ALGO_NAME)_OBJ := shabal-asm.o shabal192-asm.o shabal224-asm.o \
shabal256-asm.o shabal384-asm.o shabal512-asm.o
$(ALGO_NAME)_TEST_BIN := main-shabal-test.o hfal_shabal.o $(CLI_STD) $(HFAL_STD)
# comment out the following line for removement of Skein from the build process
HASHES += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := shabal/
$(ALGO_NAME)_OBJ := shabal.o shabal192.o shabal224.o shabal256.o shabal384.o shabal512.o
$(ALGO_NAME)_TEST_BIN := main-shabal-test.o hfal_shabal.o $(CLI_STD) $(HFAL_STD)
$(ALGO_NAME)_NESSIE_TEST := test nessie
# comment out the following line for removement of Skein from the build process
HASHES += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := skein/
$(ALGO_NAME)_OBJ := threefish_mix.o \
threefish256_enc_asm.o ubi256_asm.o skein256_asm.o \
threefish512_enc_asm.o ubi512_asm.o skein512_asm.o \
# comment out the following line for removement of threefish from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := skein/
$(ALGO_NAME)_OBJ := threefish256_enc_asm.o threefish512_enc_asm.o threefish1024_enc_asm.o\
threefish_mix.o threefish_invmix.o \
threefish256_dec_asm.o threefish512_dec_asm.o threefish1024_dec_asm.o
# comment out the following line for removement of TWISTER from the build process
HASHES += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := twister/
$(ALGO_NAME)_OBJ := twister-small-asm.o twister-large-asm.o twister-asm.o \
twister224.o twister256.o twister384.o twister512.o
$(ALGO_NAME)_TEST_BIN := main-twister-test.o hfal_twister224.o hfal_twister256.o \
# comment out the following line for removement of TWISTER from the build process
HASHES += $(ALGO_NAME)
+$(ALGO_NAME)_DIR := twister/
$(ALGO_NAME)_OBJ := twister.o twister-small.o twister-large.o memxor.o gf256mul.o
$(ALGO_NAME)_TEST_BIN := main-twister-test.o hfal_twister224.o hfal_twister256.o \
hfal_twister384.o hfal_twister512.o $(CLI_STD) $(HFAL_STD)
# comment out the following line for removement of ubi from the build process
AUX += $(ALGO_NAME)
-
+$(ALGO_NAME)_DIR := skein/
$(ALGO_NAME)_OBJ := threefish_mix.o threefish256_enc_asm.o ubi256_asm.o \
threefish512_enc_asm.o ubi512_asm.o threefish1024_enc_asm.o \
ubi1024_asm.o memxor.o
+++ /dev/null
-/* mugi.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file mugi.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-02-15
- * \brief implementation of the MUGI key stream generator
- * \license GPLv3 or later
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <avr/pgmspace.h>
-#include "aes_sbox.h"
-#include "mugi.h"
-#include "gf256mul.h"
-
-/*
-#include "test_src/cli.h" / * only for debugging * /
-
-void dump_mugi_ctx(mugi_ctx_t* ctx){
- uint8_t i;
- cli_putstr_P(PSTR("\r\n== MUGI CTX DUMP==\r\n a:"));
- cli_hexdump(&(ctx->a[0]), 8);
- cli_putc(' ');
- cli_hexdump(&(ctx->a[1]), 8);
- cli_putc(' ');
- cli_hexdump(&(ctx->a[2]), 8);
- cli_putstr_P(PSTR("\r\n b: "));
- for(i=0; i<4; ++i){
- cli_putstr_P(PSTR("\r\n "));
- cli_hexdump(&(ctx->b[i*4+0]), 8);
- cli_putc(' ');
- cli_hexdump(&(ctx->b[i*4+1]), 8);
- cli_putc(' ');
- cli_hexdump(&(ctx->b[i*4+2]), 8);
- cli_putc(' ');
- cli_hexdump(&(ctx->b[i*4+3]), 8);
- }
-}
-*/
-
-#define C0 0x08c9bcf367e6096all
-#define C1 0x3ba7ca8485ae67bbll
-#define C2 0x2bf894fe72f36e3cll
-
-#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
-
-uint64_t changeendian64(uint64_t a){
- uint8_t r[8];
- r[0] = ((uint8_t*)&a)[7];
- r[1] = ((uint8_t*)&a)[6];
- r[2] = ((uint8_t*)&a)[5];
- r[3] = ((uint8_t*)&a)[4];
- r[4] = ((uint8_t*)&a)[3];
- r[5] = ((uint8_t*)&a)[2];
- r[6] = ((uint8_t*)&a)[1];
- r[7] = ((uint8_t*)&a)[0];
- return *((uint64_t*)r);
-}
-
-static
-uint64_t rotl64(uint64_t a, uint8_t i){
- uint64_t r;
- r=changeendian64(a);
- r=(r<<i | r>>(64-i));
- r=changeendian64(r);
- return r;
-}
-
-static
-uint64_t rotr64(uint64_t a, uint8_t i){
- uint64_t r;
- r=changeendian64(a);
- r=(r>>i | r<<(64-i));
- r=changeendian64(r);
- return r;
-}
-
-
-#define T(x) (((uint8_t*)&t)[(x)])
-#define D(y) (((uint8_t*)dest)[(y)])
-static void mugi_f(uint64_t* dest, uint64_t* a, uint64_t* b){
- uint64_t t;
- uint8_t i,x;
- t = (*a);
- if(b)
- t ^= (*b);
- for(i=0; i<8; ++i)
- T(i) = pgm_read_byte(aes_sbox+T(i));
-
- x = T(0) ^ T(1) ^ T(2) ^ T(3);
- D(4) =
- GF256MUL_2(T(0)^T(1))
- ^ T(0)
- ^ x;
- D(5) =
- GF256MUL_2(T(1)^T(2))
- ^ T(1)
- ^ x;
- D(2) =
- GF256MUL_2(T(2)^T(3))
- ^ T(2)
- ^ x;
- D(3) =
- GF256MUL_2(T(3)^T(0))
- ^ T(3)
- ^ x;
- x = T(4) ^ T(5) ^ T(6) ^ T(7);
- D(0) =
- GF256MUL_2(T(4)^T(5))
- ^ T(4)
- ^ x;
- D(1) =
- GF256MUL_2(T(5)^T(6))
- ^ T(5)
- ^ x;
- D(6) =
- GF256MUL_2(T(6)^T(7))
- ^ T(6)
- ^ x;
- D(7) =
- GF256MUL_2(T(7)^T(4))
- ^ T(7)
- ^ x;
-}
-
-static
-void mugi_rho(mugi_ctx_t* ctx){
- uint64_t t,bx;
- t = ctx->a[1];
- ctx->a[1] = ctx->a[2];
- ctx->a[2] = ctx->a[0];
- ctx->a[0] = t;
- mugi_f(&t, &(ctx->a[0]), &(ctx->b[4]));
- ctx->a[1] ^= t ^ C1;
- bx = rotl64(ctx->b[10], 17);
- mugi_f(&t, &(ctx->a[0]), &bx);
- ctx->a[2] ^= t ^ C2;
-}
-
-static
-void mugi_rho_init(uint64_t* a){
- uint64_t t;
- t = a[1];
- a[1] = a[2];
- a[2] = a[0];
- a[0] = t;
- mugi_f(&t, &(a[0]), NULL);
- a[1] ^= t ^ C1;
- mugi_f(&t, &(a[0]), NULL);
- a[2] ^= t ^ C2;
-}
-
-static
-void mugi_lambda(uint64_t* b, uint64_t *a){
- uint8_t i;
- uint64_t t;
- t=b[15];
- for(i=15; i!=0; --i){
- b[i]=b[i-1];
- }
- b[0] = t ^ *a;
- b[4] ^= b[8];
- b[10] ^= rotl64(b[14], 32);
-}
-
-void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx){
- uint8_t i;
- uint64_t a0;
- memcpy(ctx->a, key, 128/8);
- ctx->a[2] = rotl64(ctx->a[0], 7) ^ rotr64(ctx->a[1], 7) ^ C0;
- for(i=0; i<16;i++){
- mugi_rho_init(ctx->a);
- ctx->b[15-i] = ctx->a[0];
- }
- ctx->a[0] ^= ((uint64_t*)iv)[0];
- ctx->a[1] ^= ((uint64_t*)iv)[1];
- ctx->a[2] ^= rotl64(((uint64_t*)iv)[0], 7) ^ rotr64(((uint64_t*)iv)[1], 7) ^ C0;
- for(i=0; i<16;i++){
- mugi_rho_init(ctx->a);
- }
- for(i=0; i<15;i++){
- a0 = ctx->a[0];
- mugi_rho(ctx);
- mugi_lambda(ctx->b, &a0);
- }
- a0=0x00;
-}
-
-uint64_t mugi_gen(mugi_ctx_t* ctx){
- uint64_t r;
- r=ctx->a[0];
- mugi_rho(ctx);
- mugi_lambda(ctx->b, &r);
- r=ctx->a[2];
- return r;
-}
+++ /dev/null
-/* mugi.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file mugi.h
- * \author Daniel Otte
- * \date 2009-02-15
- * \brief implementation of the MUGI key stream generator
- * \license GPLv3 or later
- */
-
-#ifndef MUGI_H_
-#define MUGI_H_
-
-#include <stdint.h>
-
-typedef struct{
- uint64_t a[3];
- uint64_t b[16];
-}mugi_ctx_t; /* 152 bytes in total */
-
-void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx);
-uint64_t mugi_gen(mugi_ctx_t* ctx);
-
-
-#endif /* MUGI_H_ */
--- /dev/null
+/* aes sbox */
+
+#include <stdint.h>
+#include <avr/pgmspace.h>
+uint8_t aes_sbox[256] PROGMEM = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
--- /dev/null
+/* aes_sbox.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file aes_sbox.h
+ * \email daniel.otte@rub.de
+ * \author Daniel Otte
+ * \date 2008-12-30
+ * \license GPLv3 or later
+ *
+ */
+#ifndef AES_SBOX_H_
+#define AES_SBOX_H_
+#include <stdint.h>
+
+extern uint8_t aes_sbox[];
+
+#endif
--- /dev/null
+/* gf256mul.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: gf256mul.S
+ * Author: Daniel Otte
+ * Date: 2008-12-19
+ * License: GPLv3 or later
+ * Description: peasant's algorithm for multiplication in GF(2^8)
+ *
+ */
+
+#include <avr/io.h>
+#define OPTIMIZE_SMALL_A
+
+/*
+ * param a: r24
+ * param b: r22
+ * param reducer: r20
+ */
+A = 23
+B = 22
+P = 24
+.global gf256mul
+
+#ifdef OPTIMIZE_SMALL_A
+gf256mul:
+ mov A, r24
+ clr r24
+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
+
+#else
+
+gf256mul:
+ mov r21, r24
+ clr r24
+ ldi r25, 8
+1:
+ lsr A
+ brcc 2f
+ eor P, B
+2:
+ lsl B
+ brcc 3f
+ eor B, r20
+3:
+ dec r25
+ brne 1b
+ ret
+
+#endif
--- /dev/null
+/* gf256mul.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2008-12-19
+ * \license GPLv3
+ * \brief
+ *
+ *
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
--- /dev/null
+/* mugi.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file mugi.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-02-15
+ * \brief implementation of the MUGI key stream generator
+ * \license GPLv3 or later
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "aes_sbox.h"
+#include "mugi.h"
+#include "gf256mul.h"
+
+/*
+#include "test_src/cli.h" / * only for debugging * /
+
+void dump_mugi_ctx(mugi_ctx_t* ctx){
+ uint8_t i;
+ cli_putstr_P(PSTR("\r\n== MUGI CTX DUMP==\r\n a:"));
+ cli_hexdump(&(ctx->a[0]), 8);
+ cli_putc(' ');
+ cli_hexdump(&(ctx->a[1]), 8);
+ cli_putc(' ');
+ cli_hexdump(&(ctx->a[2]), 8);
+ cli_putstr_P(PSTR("\r\n b: "));
+ for(i=0; i<4; ++i){
+ cli_putstr_P(PSTR("\r\n "));
+ cli_hexdump(&(ctx->b[i*4+0]), 8);
+ cli_putc(' ');
+ cli_hexdump(&(ctx->b[i*4+1]), 8);
+ cli_putc(' ');
+ cli_hexdump(&(ctx->b[i*4+2]), 8);
+ cli_putc(' ');
+ cli_hexdump(&(ctx->b[i*4+3]), 8);
+ }
+}
+*/
+
+#define C0 0x08c9bcf367e6096all
+#define C1 0x3ba7ca8485ae67bbll
+#define C2 0x2bf894fe72f36e3cll
+
+#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
+
+uint64_t changeendian64(uint64_t a){
+ uint8_t r[8];
+ r[0] = ((uint8_t*)&a)[7];
+ r[1] = ((uint8_t*)&a)[6];
+ r[2] = ((uint8_t*)&a)[5];
+ r[3] = ((uint8_t*)&a)[4];
+ r[4] = ((uint8_t*)&a)[3];
+ r[5] = ((uint8_t*)&a)[2];
+ r[6] = ((uint8_t*)&a)[1];
+ r[7] = ((uint8_t*)&a)[0];
+ return *((uint64_t*)r);
+}
+
+static
+uint64_t rotl64(uint64_t a, uint8_t i){
+ uint64_t r;
+ r=changeendian64(a);
+ r=(r<<i | r>>(64-i));
+ r=changeendian64(r);
+ return r;
+}
+
+static
+uint64_t rotr64(uint64_t a, uint8_t i){
+ uint64_t r;
+ r=changeendian64(a);
+ r=(r>>i | r<<(64-i));
+ r=changeendian64(r);
+ return r;
+}
+
+
+#define T(x) (((uint8_t*)&t)[(x)])
+#define D(y) (((uint8_t*)dest)[(y)])
+static void mugi_f(uint64_t* dest, uint64_t* a, uint64_t* b){
+ uint64_t t;
+ uint8_t i,x;
+ t = (*a);
+ if(b)
+ t ^= (*b);
+ for(i=0; i<8; ++i)
+ T(i) = pgm_read_byte(aes_sbox+T(i));
+
+ x = T(0) ^ T(1) ^ T(2) ^ T(3);
+ D(4) =
+ GF256MUL_2(T(0)^T(1))
+ ^ T(0)
+ ^ x;
+ D(5) =
+ GF256MUL_2(T(1)^T(2))
+ ^ T(1)
+ ^ x;
+ D(2) =
+ GF256MUL_2(T(2)^T(3))
+ ^ T(2)
+ ^ x;
+ D(3) =
+ GF256MUL_2(T(3)^T(0))
+ ^ T(3)
+ ^ x;
+ x = T(4) ^ T(5) ^ T(6) ^ T(7);
+ D(0) =
+ GF256MUL_2(T(4)^T(5))
+ ^ T(4)
+ ^ x;
+ D(1) =
+ GF256MUL_2(T(5)^T(6))
+ ^ T(5)
+ ^ x;
+ D(6) =
+ GF256MUL_2(T(6)^T(7))
+ ^ T(6)
+ ^ x;
+ D(7) =
+ GF256MUL_2(T(7)^T(4))
+ ^ T(7)
+ ^ x;
+}
+
+static
+void mugi_rho(mugi_ctx_t* ctx){
+ uint64_t t,bx;
+ t = ctx->a[1];
+ ctx->a[1] = ctx->a[2];
+ ctx->a[2] = ctx->a[0];
+ ctx->a[0] = t;
+ mugi_f(&t, &(ctx->a[0]), &(ctx->b[4]));
+ ctx->a[1] ^= t ^ C1;
+ bx = rotl64(ctx->b[10], 17);
+ mugi_f(&t, &(ctx->a[0]), &bx);
+ ctx->a[2] ^= t ^ C2;
+}
+
+static
+void mugi_rho_init(uint64_t* a){
+ uint64_t t;
+ t = a[1];
+ a[1] = a[2];
+ a[2] = a[0];
+ a[0] = t;
+ mugi_f(&t, &(a[0]), NULL);
+ a[1] ^= t ^ C1;
+ mugi_f(&t, &(a[0]), NULL);
+ a[2] ^= t ^ C2;
+}
+
+static
+void mugi_lambda(uint64_t* b, uint64_t *a){
+ uint8_t i;
+ uint64_t t;
+ t=b[15];
+ for(i=15; i!=0; --i){
+ b[i]=b[i-1];
+ }
+ b[0] = t ^ *a;
+ b[4] ^= b[8];
+ b[10] ^= rotl64(b[14], 32);
+}
+
+void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx){
+ uint8_t i;
+ uint64_t a0;
+ memcpy(ctx->a, key, 128/8);
+ ctx->a[2] = rotl64(ctx->a[0], 7) ^ rotr64(ctx->a[1], 7) ^ C0;
+ for(i=0; i<16;i++){
+ mugi_rho_init(ctx->a);
+ ctx->b[15-i] = ctx->a[0];
+ }
+ ctx->a[0] ^= ((uint64_t*)iv)[0];
+ ctx->a[1] ^= ((uint64_t*)iv)[1];
+ ctx->a[2] ^= rotl64(((uint64_t*)iv)[0], 7) ^ rotr64(((uint64_t*)iv)[1], 7) ^ C0;
+ for(i=0; i<16;i++){
+ mugi_rho_init(ctx->a);
+ }
+ for(i=0; i<15;i++){
+ a0 = ctx->a[0];
+ mugi_rho(ctx);
+ mugi_lambda(ctx->b, &a0);
+ }
+ a0=0x00;
+}
+
+uint64_t mugi_gen(mugi_ctx_t* ctx){
+ uint64_t r;
+ r=ctx->a[0];
+ mugi_rho(ctx);
+ mugi_lambda(ctx->b, &r);
+ r=ctx->a[2];
+ return r;
+}
--- /dev/null
+/* mugi.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file mugi.h
+ * \author Daniel Otte
+ * \date 2009-02-15
+ * \brief implementation of the MUGI key stream generator
+ * \license GPLv3 or later
+ */
+
+#ifndef MUGI_H_
+#define MUGI_H_
+
+#include <stdint.h>
+
+typedef struct{
+ uint64_t a[3];
+ uint64_t b[16];
+}mugi_ctx_t; /* 152 bytes in total */
+
+void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx);
+uint64_t mugi_gen(mugi_ctx_t* ctx);
+
+
+#endif /* MUGI_H_ */
+++ /dev/null
-/* shabal-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void shabal_p(shabal_ctx_t* ctx, const void* m){
- uint8_t i,j;
- for(i=0;i<16;++i){
- ctx->b[i] = ROTL32(ctx->b[i],17);
- }
- for(j=0;j<SHABAL_P;++j){
- for(i=0;i<16;++i){
- ctx->a[(i+16*j)%SHABAL_R] =
- shabal_u(ctx->a[(i+16*j)%SHABAL_R]
- ^ shabal_v(ROTL32(ctx->a[(i+16*j+SHABAL_R-1)%SHABAL_R],15))
- ^ ctx->c[(8-i+16)%16])
- ^ ctx->b[(i+SHABAL_O1)%16]
- ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
- ^ ((uint32_t*)m)[i];
- ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+16*j)%SHABAL_R]);
- }
- }
-
- for(j=0;j<36;++j){
- ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
- }
-}
-*/
-MB0 = 2
-MB1 = 3
-AB0 = 4
-AB1 = 5
-BB0 = 6
-BB1 = 7
-CB0 = 8
-CB1 = 9
-AL0 = 10
-AL1 = 11
-AL2 = 12
-AL3 = 13
-A0 = 14
-A1 = 15
-A2 = 16
-A3 = 17
-B0 = 18
-B1 = 19
-B2 = 20
-B3 = 21
-I = 22
-J = 23
-T0 = 26
-T1 = 27
-T2 = 28
-T3 = 29
-/*
- * param ctx: r24:r25
- * param m: r22:r23
- */
-; .global shabal_p
-shabal_p:
- push_range 2, 17
- push r28
- push r29
- movw MB0, r22
- movw r30, r24
- adiw r30, 8
- ld BB0, Z+
- ld BB1, Z+
- ld CB0, Z+
- ld CB1, Z+
- movw AB0, r30
- movw r30, BB0
- adiw r30, 16*4-1
- adiw r30, 1
- ldi r24, 16
-1:
- ld A3, -Z
- ld A2, -Z
- ld A1, -Z
- ld A0, -Z
- mov r0, A3
- rol r0
- rol A0
- rol A1
- rol A2
- rol A3
- std Z+0, A2
- std Z+1, A3
- std Z+2, A0
- std Z+3, A1
- dec r24
- brne 1b
- movw B0, A2
- movw B2, A0
- /* load ctx->a[(i+16*j-1)%12]*/
- movw r26, AB0
- adiw r26, 4*11
- ld AL0, X+
- ld AL1, X+
- ld AL2, X+
- ld AL3, X+
- clr I
- clr J
-1:
- /* ROTL32(AL, 15)*/
- movw T0, AL2
- movw T2, AL0
- mov r0, T0
- ror r0
- ror T3
- ror T2
- ror T1
- ror T0
- movw AL0, T0
- movw AL2, T2
- /* apply V to AL */
- movw A0, AL0
- movw A2, AL2
- lsl A0
- rol A1
- rol A2
- rol A3
- lsl A0
- rol A1
- rol A2
- rol A3
- add A0, AL0
- adc A1, AL1
- adc A2, AL2
- adc A3, AL3
- /* xor in ctx->c[(8-i+16)%16] */
- ldi T0, 24
- sub T0, I
- andi T0, 0x0f
- lsl T0
- lsl T0
- movw r30, CB0
- add r30, T0
- adc r31, r1
- ld r0, Z+
- eor A0, r0
- ld r0, Z+
- eor A1, r0
- ld r0, Z+
- eor A2, r0
- ld r0, Z+
- eor A3, r0
- /* xor in ctx->a[(i+16*j)%12] */
- mov T0, J
- swap T0 /* *=16 */
- add T0, I
- ldi r30, lo8(mod12table)
- ldi r31, hi8(mod12table)
- add r30, T0
- adc r31, r1
- lpm T0, Z
- movw r30, AB0
- add r30, T0
- adc r31, r1
- movw T2, r30
- ld r0, Z+
- eor A0, r0
- ld r0, Z+
- eor A1, r0
- ld r0, Z+
- eor A2, r0
- ld r0, Z+
- eor A3, r0
- /* AL = 3*A */
- movw AL0, A0
- movw AL2, A2
- lsl AL0
- rol AL1
- rol AL2
- rol AL3
- add AL0, A0
- adc AL1, A1
- adc AL2, A2
- adc AL3, A3
- /* xor in ctx->b[(i+13)%16] */
- ldi T0, 13
- add T0, I
- andi T0, 0x0f
- lsl T0
- lsl T0
- movw r30, BB0
- add r30, T0
- adc r31, r1
- ld r0, Z+
- eor AL0, r0
- ld r0, Z+
- eor AL1, r0
- ld r0, Z+
- eor AL2, r0
- ld r0, Z+
- eor AL3, r0
- /* load ctx->b[(i+9)%16] into A */
- ldi T0, 9
- add T0, I
- andi T0, 0x0f
- lsl T0
- lsl T0
- movw r30, BB0
- add r30, T0
- adc r31, r1
- ld A0, Z+
- ld A1, Z+
- ld A2, Z+
- ld A3, Z+
- /* and in ~(ctx->b[(i+6)%16]) */
- ldi T0, 6
- add T0, I
- andi T0, 0x0f
- lsl T0
- lsl T0
- movw r30, BB0
- add r30, T0
- adc r31, r1
- ld r0, Z+
- com r0
- and A0, r0
- ld r0, Z+
- com r0
- and A1, r0
- ld r0, Z+
- com r0
- and A2, r0
- ld r0, Z+
- com r0
- and A3, r0
- /* xor A into AL */
- eor AL0, A0
- eor AL1, A1
- eor AL2, A2
- eor AL3, A3
- /* xor m[i] into AL */
- mov T0, I
- lsl T0
- lsl T0
- movw r30, MB0
- add r30, T0
- adc r31, r1
- ld r0, Z+
- eor AL0, r0
- ld r0, Z+
- eor AL1, r0
- ld r0, Z+
- eor AL2, r0
- ld r0, Z+
- eor AL3, r0
- /* A (AL) is done, now store it */
- movw r30, T2
- st Z+, AL0
- st Z+, AL1
- st Z+, AL2
- st Z+, AL3
- /* process ctx->b[i] */
- /* ROTL32(b, 1)*/
- mov r0, B3
- rol r0
- rol B0
- rol B1
- rol B2
- rol B3
- /* xor in ~(ctx->a[(i+16*j)%SHABAL_R]) */
- movw A0, AL0
- movw A2, AL2
- com A0
- com A1
- com A2
- com A3
- eor B0, A0
- eor B1, A1
- eor B2, A2
- eor B3, A3
- /* store B */
- movw r30, BB0
- mov T0, I
- lsl T0
- lsl T0
- add r30, T0
- adc r31, r1
- st Z+, B0
- st Z+, B1
- st Z+, B2
- st Z+, B3
- inc I
- cpi I, 16
- brne local_reload
- inc J
- cpi J, 3
- brne global_reload
- rjmp addition
-global_reload:
- clr I
-local_reload:
- mov T0, I
- lsl T0
- lsl T0
- movw r30, BB0
- add r30, T0
- adc r31, r1
- ld B0, Z+
- ld B1, Z+
- ld B2, Z+
- ld B3, Z+
-
- rjmp 1b
-addition:
- clr J
- movw r30, AB0
- movw r26, CB0
- adiw r26, 3*4
-1:
- /* J = 0..11 */
- ld AL0, X+
- ld A0, Z
- add A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- inc J
- cpi J, 12
- brne 1b
- /* J = 12 */
- movw r30, AB0
- ld AL0, X+
- ld A0, Z
- add A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- inc J
- /* J= 13..23*/
- movw r26, CB0
-1:
- ld AL0, X+
- ld A0, Z
- add A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- inc J
- cpi J, 24
- brne 1b
- /* J= 24..28*/
- movw r30, AB0
-1:
- ld AL0, X+
- ld A0, Z
- add A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- inc J
- cpi J, 29
- brne 1b
-
- /* J= 29..35*/
- movw r26, CB0
-1:
- ld AL0, X+
- ld A0, Z
- add A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- ld AL0, X+
- ld A0, Z
- adc A0, AL0
- st Z+, A0
- inc J
- cpi J, 36
- brne 1b
-exit:
- pop r29
- pop r28
- pop_range 2, 17
- ret
-
-mod12table:
- .byte 0, 4, 8, 12, 16, 20, 24, 28
- .byte 32, 36, 40, 44, 0, 4, 8, 12
- .byte 16, 20, 24, 28, 32, 36, 40, 44
- .byte 0, 4, 8, 12, 16, 20, 24, 28
- .byte 32, 36, 40, 44, 0, 4, 8, 12
- .byte 16, 20, 24, 28, 32, 36, 40, 44
-
-/******************************************************************************/
-/*
-void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
- uint8_t i;
- uint32_t* t;
- for(i=0;i<16;++i){
- ctx->b[i] += ((uint32_t*)block)[i];
- }
- ctx->a[0] ^= ctx->w.w32[0];
- ctx->a[1] ^= ctx->w.w32[1];
- shabal_p(ctx, block);
- for(i=0;i<16;++i){
- ctx->c[i] -= ((uint32_t*)block)[i];
- }
- ctx->w.w64++;
- t = ctx->c;
- ctx->c = ctx->b;
- ctx->b = t;
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- */
-MB0 = 14
-MB1 = 15
-CTX0 = 16
-CTX1 = 17
-.global shabal_nextBlock
-shabal_nextBlock:
- push_range 14, 17
- movw CTX0, r24
- movw MB0, r22
- /* xor W into A and increment W */
- movw r30, CTX0
- ldi r19, 8
- sec
-1:
- ld r20, Z
- ldd r21, Z+(8+4)
- eor r21, r20
- std Z+(8+4), r21
- adc r20, r1
- st Z+, r20
- dec r19
- brne 1b
- /* add block to ctx->b */
- ld r26, Z+
- ld r27, Z
- movw r30, MB0
- ldi r19, 16
-1:
- ld r0, X
- ld r18, Z+
- add r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- adc r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- adc r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- adc r0, r18
- st X+, r0
- dec r19
- brne 1b
- /* call shbal_p */
- rcall shabal_p
- /* sub block from ctx->c */
- movw r30, CTX0
- adiw r30, 8+2
- ld r26, Z+
- ld r27, Z
- movw r30, MB0
- ldi r19, 16
-1:
- ld r0, X
- ld r18, Z+
- sub r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- sbc r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- sbc r0, r18
- st X+, r0
- ld r0, X
- ld r18, Z+
- sbc r0, r18
- st X+, r0
- dec r19
- brne 1b
- /* xchange ctx->b with ctx->c*/
- movw r30, CTX0
- ldd r22, Z+8
- ldd r23, Z+9
- ldd r24, Z+10
- ldd r25, Z+11
- std Z+10, r22
- std Z+11, r23
- std Z+8, r24
- std Z+9, r25
- pop_range 14, 17
- ret
-
-/******************************************************************************/
-/*
-void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
- uint8_t i,j;
- uint32_t* t;
- uint8_t buffer[64];
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(ctx, block);
- block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- memset(buffer, 0, 64);
- memcpy(buffer, block, (length_b+7)/8);
- buffer[length_b/8] |= 0x80>>(length_b%8);
- for(i=0;i<16;++i){
- ctx->b[i] += ((uint32_t*)buffer)[i];
- }
- for(j=0; j<4;++j){
- ctx->a[0] ^= ctx->w.w32[0];
- ctx->a[1] ^= ctx->w.w32[1];
- shabal_p(ctx, buffer);
- t = ctx->c;
- ctx->c = ctx->b;
- ctx->b = t;
- }
-}
-*/
-I = 16
-LEN0 = 16
-LEN1 = 17
-CTX0 = 14
-CTX1 = 15
-MB0 = 12
-MB1 = 13
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- * param length_b: r20:r21
- */
-.global shabal_lastBlock
-shabal_lastBlock:
- push_range 12, 17
- movw CTX0, r24
- movw MB0, r22
- movw LEN0, r20
-1:
- cpi LEN1, 0x02
- brlo 2f
- movw r24, CTX0
- movw r22, MB0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- ldi r18, 64
- add MB0, r18
- adc MB1, r1
- rjmp 1b
-2:
- stack_alloc_large 64
- adiw r30, 1 /* Z points at buffer */
- movw r26, MB0
- /* r24 = LEN/8*/
- movw r24, LEN0
- lsr r25
- ror r24
- lsr r24
- lsr r24
- ldi r25, 64-1
- sub r25, r24
- tst r24
- breq 32f
-31:
- ld r0, X+
- st Z+, r0
- dec r24
- brne 31b
-32:
- ldi r18, 0x80
- andi LEN0, 0x07
- breq append_0x80
- ld r0, X+
-33:
- lsr r18
- dec LEN0
- brne 33b
- or r0, r18
- st Z+, r0
- rjmp append_zeros
-append_0x80:
- st Z+, r18
-append_zeros:
- tst r25
- breq 4f
-34: st Z+, r1
- dec r25
- brne 34b
-4:
- sbiw r30, 63
- sbiw r30, 1
- movw MB0, r30
- movw r26, CTX0
- adiw r26, 8
- ld r24, X+
- ld r25, X
- movw r26, r24
- ldi r18, 16
-41:
- ld r24, X
- ld r25, Z+
- add r24, r25
- st X+, r24
- ld r24, X
- ld r25, Z+
- adc r24, r25
- st X+, r24
- ld r24, X
- ld r25, Z+
- adc r24, r25
- st X+, r24
- ld r24, X
- ld r25, Z+
- adc r24, r25
- st X+, r24
- dec r18
- brne 41b
- /* final loop */
- ldi I, 4
-5:
- /* xor W into A */
- movw r30, CTX0
- ldi r19, 8
-51:
- ld r24, Z+
- ldd r25, Z+(8+4-1)
- eor r24, r25
- std Z+(8+4-1), r24
- dec r19
- brne 51b
- movw r24, CTX0
- movw r22, MB0
- rcall shabal_p
- movw r30, CTX0
- ldd r22, Z+8
- ldd r23, Z+9
- ldd r24, Z+10
- ldd r25, Z+11
- std Z+10, r22
- std Z+11, r23
- std Z+8, r24
- std Z+9, r25
- dec I
- brne 5b
-
- stack_free_large 64
- pop_range 12, 17
- ret
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* shabal.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-17
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <string.h>
-
-#define SHABAL_O1 13
-#define SHABAL_O2 9
-#define SHABAL_O3 6
-
-
-static inline
-uint32_t shabal_u(uint32_t a){
- return (a<<1)+a; /* a*3 */
-}
-
-static inline
-uint32_t shabal_v(uint32_t a){
- return (a<<2)+a; /* a*5 */
-}
-
-#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
-
-static
-void shabal_p(shabal_ctx_t* ctx, const void* m){
- uint8_t i,j;
- for(i=0;i<16;++i){
- ctx->b[i] = ROTL32(ctx->b[i],17);
- }
- for(j=0;j<SHABAL_P;j++){
- for(i=0;i<16;++i){
- ctx->a[(i+j*16)%SHABAL_R] =
- shabal_u(ctx->a[(i+j*16)%SHABAL_R]
- ^ shabal_v(ROTL32(ctx->a[(i+j*16+SHABAL_R-1)%SHABAL_R],15))
- ^ ctx->c[(8-i+16)%16])
- ^ ctx->b[(i+SHABAL_O1)%16]
- ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
- ^ ((uint32_t*)m)[i];
- ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+j*16)%SHABAL_R]);
- }
- }
-
- for(j=0;j<36;++j){
- ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
- }
-}
-
-void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
- uint8_t i;
- uint32_t* t;
- for(i=0;i<16;++i){
- ctx->b[i] += ((uint32_t*)block)[i];
- }
- ctx->a[0] ^= ctx->w.w32[0];
- ctx->a[1] ^= ctx->w.w32[1];
- shabal_p(ctx, block);
- for(i=0;i<16;++i){
- ctx->c[i] -= ((uint32_t*)block)[i];
- }
- ctx->w.w64++;
- t = ctx->c;
- ctx->c = ctx->b;
- ctx->b = t;
-}
-
-void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
- uint8_t i,j;
- uint32_t* t;
- uint8_t buffer[64];
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(ctx, block);
- block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- memset(buffer, 0, 64);
- memcpy(buffer, block, (length_b+7)/8);
- buffer[length_b/8] |= 0x80>>(length_b%8);
-
- for(i=0;i<16;++i){
- ctx->b[i] += ((uint32_t*)buffer)[i];
- }
-
- for(j=0; j<4;++j){
- ctx->a[0] ^= ctx->w.w32[0];
- ctx->a[1] ^= ctx->w.w32[1];
- shabal_p(ctx, buffer);
- t = ctx->c;
- ctx->c = ctx->b;
- ctx->b = t;
- }
-
-}
-
-void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b){
- memcpy(dest, &(ctx->c[16-outlength_b/32]), outlength_b/8);
-}
+++ /dev/null
-/* shabal.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-17
- * \license GPLv3 or later
- *
- */
-
-#ifndef SHABAL_H_
-#define SHABAL_H_
-
-#include <stdint.h>
-
-#define SHABAL_BLOCKSIZE 512
-#define SHABAL_BLOCKSIZE_B ((SHABAL_BLOCKSIZE+7)/8)
-
-#define SHABAL_R 12
-#define SHABAL_P 3
-
-typedef struct{
- union{
- uint64_t w64;
- uint32_t w32[2];
- } w; /* the counter */
- uint32_t *b;
- uint32_t *c;
- uint32_t a[SHABAL_R];
- uint32_t b_buffer[16];
- uint32_t c_buffer[16];
-}shabal_ctx_t;
-
-
-void shabal192_init(shabal_ctx_t* ctx);
-void shabal224_init(shabal_ctx_t* ctx);
-void shabal256_init(shabal_ctx_t* ctx);
-void shabal384_init(shabal_ctx_t* ctx);
-void shabal512_init(shabal_ctx_t* ctx);
-
-void shabal_nextBlock(shabal_ctx_t* ctx, const void* block);
-void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b);
-
-void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx);
-void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx);
-void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx);
-void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx);
-void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx);
-
-void shabal192(void* dest, void* msg, uint32_t length_b);
-void shabal224(void* dest, void* msg, uint32_t length_b);
-void shabal256(void* dest, void* msg, uint32_t length_b);
-void shabal384(void* dest, void* msg, uint32_t length_b);
-void shabal512(void* dest, void* msg, uint32_t length_b);
-
-void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b);
-
-#endif /* SHABAL_H_ */
--- /dev/null
+/* shabal-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void shabal_p(shabal_ctx_t* ctx, const void* m){
+ uint8_t i,j;
+ for(i=0;i<16;++i){
+ ctx->b[i] = ROTL32(ctx->b[i],17);
+ }
+ for(j=0;j<SHABAL_P;++j){
+ for(i=0;i<16;++i){
+ ctx->a[(i+16*j)%SHABAL_R] =
+ shabal_u(ctx->a[(i+16*j)%SHABAL_R]
+ ^ shabal_v(ROTL32(ctx->a[(i+16*j+SHABAL_R-1)%SHABAL_R],15))
+ ^ ctx->c[(8-i+16)%16])
+ ^ ctx->b[(i+SHABAL_O1)%16]
+ ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
+ ^ ((uint32_t*)m)[i];
+ ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+16*j)%SHABAL_R]);
+ }
+ }
+
+ for(j=0;j<36;++j){
+ ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
+ }
+}
+*/
+MB0 = 2
+MB1 = 3
+AB0 = 4
+AB1 = 5
+BB0 = 6
+BB1 = 7
+CB0 = 8
+CB1 = 9
+AL0 = 10
+AL1 = 11
+AL2 = 12
+AL3 = 13
+A0 = 14
+A1 = 15
+A2 = 16
+A3 = 17
+B0 = 18
+B1 = 19
+B2 = 20
+B3 = 21
+I = 22
+J = 23
+T0 = 26
+T1 = 27
+T2 = 28
+T3 = 29
+/*
+ * param ctx: r24:r25
+ * param m: r22:r23
+ */
+; .global shabal_p
+shabal_p:
+ push_range 2, 17
+ push r28
+ push r29
+ movw MB0, r22
+ movw r30, r24
+ adiw r30, 8
+ ld BB0, Z+
+ ld BB1, Z+
+ ld CB0, Z+
+ ld CB1, Z+
+ movw AB0, r30
+ movw r30, BB0
+ adiw r30, 16*4-1
+ adiw r30, 1
+ ldi r24, 16
+1:
+ ld A3, -Z
+ ld A2, -Z
+ ld A1, -Z
+ ld A0, -Z
+ mov r0, A3
+ rol r0
+ rol A0
+ rol A1
+ rol A2
+ rol A3
+ std Z+0, A2
+ std Z+1, A3
+ std Z+2, A0
+ std Z+3, A1
+ dec r24
+ brne 1b
+ movw B0, A2
+ movw B2, A0
+ /* load ctx->a[(i+16*j-1)%12]*/
+ movw r26, AB0
+ adiw r26, 4*11
+ ld AL0, X+
+ ld AL1, X+
+ ld AL2, X+
+ ld AL3, X+
+ clr I
+ clr J
+1:
+ /* ROTL32(AL, 15)*/
+ movw T0, AL2
+ movw T2, AL0
+ mov r0, T0
+ ror r0
+ ror T3
+ ror T2
+ ror T1
+ ror T0
+ movw AL0, T0
+ movw AL2, T2
+ /* apply V to AL */
+ movw A0, AL0
+ movw A2, AL2
+ lsl A0
+ rol A1
+ rol A2
+ rol A3
+ lsl A0
+ rol A1
+ rol A2
+ rol A3
+ add A0, AL0
+ adc A1, AL1
+ adc A2, AL2
+ adc A3, AL3
+ /* xor in ctx->c[(8-i+16)%16] */
+ ldi T0, 24
+ sub T0, I
+ andi T0, 0x0f
+ lsl T0
+ lsl T0
+ movw r30, CB0
+ add r30, T0
+ adc r31, r1
+ ld r0, Z+
+ eor A0, r0
+ ld r0, Z+
+ eor A1, r0
+ ld r0, Z+
+ eor A2, r0
+ ld r0, Z+
+ eor A3, r0
+ /* xor in ctx->a[(i+16*j)%12] */
+ mov T0, J
+ swap T0 /* *=16 */
+ add T0, I
+ ldi r30, lo8(mod12table)
+ ldi r31, hi8(mod12table)
+ add r30, T0
+ adc r31, r1
+ lpm T0, Z
+ movw r30, AB0
+ add r30, T0
+ adc r31, r1
+ movw T2, r30
+ ld r0, Z+
+ eor A0, r0
+ ld r0, Z+
+ eor A1, r0
+ ld r0, Z+
+ eor A2, r0
+ ld r0, Z+
+ eor A3, r0
+ /* AL = 3*A */
+ movw AL0, A0
+ movw AL2, A2
+ lsl AL0
+ rol AL1
+ rol AL2
+ rol AL3
+ add AL0, A0
+ adc AL1, A1
+ adc AL2, A2
+ adc AL3, A3
+ /* xor in ctx->b[(i+13)%16] */
+ ldi T0, 13
+ add T0, I
+ andi T0, 0x0f
+ lsl T0
+ lsl T0
+ movw r30, BB0
+ add r30, T0
+ adc r31, r1
+ ld r0, Z+
+ eor AL0, r0
+ ld r0, Z+
+ eor AL1, r0
+ ld r0, Z+
+ eor AL2, r0
+ ld r0, Z+
+ eor AL3, r0
+ /* load ctx->b[(i+9)%16] into A */
+ ldi T0, 9
+ add T0, I
+ andi T0, 0x0f
+ lsl T0
+ lsl T0
+ movw r30, BB0
+ add r30, T0
+ adc r31, r1
+ ld A0, Z+
+ ld A1, Z+
+ ld A2, Z+
+ ld A3, Z+
+ /* and in ~(ctx->b[(i+6)%16]) */
+ ldi T0, 6
+ add T0, I
+ andi T0, 0x0f
+ lsl T0
+ lsl T0
+ movw r30, BB0
+ add r30, T0
+ adc r31, r1
+ ld r0, Z+
+ com r0
+ and A0, r0
+ ld r0, Z+
+ com r0
+ and A1, r0
+ ld r0, Z+
+ com r0
+ and A2, r0
+ ld r0, Z+
+ com r0
+ and A3, r0
+ /* xor A into AL */
+ eor AL0, A0
+ eor AL1, A1
+ eor AL2, A2
+ eor AL3, A3
+ /* xor m[i] into AL */
+ mov T0, I
+ lsl T0
+ lsl T0
+ movw r30, MB0
+ add r30, T0
+ adc r31, r1
+ ld r0, Z+
+ eor AL0, r0
+ ld r0, Z+
+ eor AL1, r0
+ ld r0, Z+
+ eor AL2, r0
+ ld r0, Z+
+ eor AL3, r0
+ /* A (AL) is done, now store it */
+ movw r30, T2
+ st Z+, AL0
+ st Z+, AL1
+ st Z+, AL2
+ st Z+, AL3
+ /* process ctx->b[i] */
+ /* ROTL32(b, 1)*/
+ mov r0, B3
+ rol r0
+ rol B0
+ rol B1
+ rol B2
+ rol B3
+ /* xor in ~(ctx->a[(i+16*j)%SHABAL_R]) */
+ movw A0, AL0
+ movw A2, AL2
+ com A0
+ com A1
+ com A2
+ com A3
+ eor B0, A0
+ eor B1, A1
+ eor B2, A2
+ eor B3, A3
+ /* store B */
+ movw r30, BB0
+ mov T0, I
+ lsl T0
+ lsl T0
+ add r30, T0
+ adc r31, r1
+ st Z+, B0
+ st Z+, B1
+ st Z+, B2
+ st Z+, B3
+ inc I
+ cpi I, 16
+ brne local_reload
+ inc J
+ cpi J, 3
+ brne global_reload
+ rjmp addition
+global_reload:
+ clr I
+local_reload:
+ mov T0, I
+ lsl T0
+ lsl T0
+ movw r30, BB0
+ add r30, T0
+ adc r31, r1
+ ld B0, Z+
+ ld B1, Z+
+ ld B2, Z+
+ ld B3, Z+
+
+ rjmp 1b
+addition:
+ clr J
+ movw r30, AB0
+ movw r26, CB0
+ adiw r26, 3*4
+1:
+ /* J = 0..11 */
+ ld AL0, X+
+ ld A0, Z
+ add A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ inc J
+ cpi J, 12
+ brne 1b
+ /* J = 12 */
+ movw r30, AB0
+ ld AL0, X+
+ ld A0, Z
+ add A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ inc J
+ /* J= 13..23*/
+ movw r26, CB0
+1:
+ ld AL0, X+
+ ld A0, Z
+ add A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ inc J
+ cpi J, 24
+ brne 1b
+ /* J= 24..28*/
+ movw r30, AB0
+1:
+ ld AL0, X+
+ ld A0, Z
+ add A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ inc J
+ cpi J, 29
+ brne 1b
+
+ /* J= 29..35*/
+ movw r26, CB0
+1:
+ ld AL0, X+
+ ld A0, Z
+ add A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ ld AL0, X+
+ ld A0, Z
+ adc A0, AL0
+ st Z+, A0
+ inc J
+ cpi J, 36
+ brne 1b
+exit:
+ pop r29
+ pop r28
+ pop_range 2, 17
+ ret
+
+mod12table:
+ .byte 0, 4, 8, 12, 16, 20, 24, 28
+ .byte 32, 36, 40, 44, 0, 4, 8, 12
+ .byte 16, 20, 24, 28, 32, 36, 40, 44
+ .byte 0, 4, 8, 12, 16, 20, 24, 28
+ .byte 32, 36, 40, 44, 0, 4, 8, 12
+ .byte 16, 20, 24, 28, 32, 36, 40, 44
+
+/******************************************************************************/
+/*
+void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
+ uint8_t i;
+ uint32_t* t;
+ for(i=0;i<16;++i){
+ ctx->b[i] += ((uint32_t*)block)[i];
+ }
+ ctx->a[0] ^= ctx->w.w32[0];
+ ctx->a[1] ^= ctx->w.w32[1];
+ shabal_p(ctx, block);
+ for(i=0;i<16;++i){
+ ctx->c[i] -= ((uint32_t*)block)[i];
+ }
+ ctx->w.w64++;
+ t = ctx->c;
+ ctx->c = ctx->b;
+ ctx->b = t;
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ */
+MB0 = 14
+MB1 = 15
+CTX0 = 16
+CTX1 = 17
+.global shabal_nextBlock
+shabal_nextBlock:
+ push_range 14, 17
+ movw CTX0, r24
+ movw MB0, r22
+ /* xor W into A and increment W */
+ movw r30, CTX0
+ ldi r19, 8
+ sec
+1:
+ ld r20, Z
+ ldd r21, Z+(8+4)
+ eor r21, r20
+ std Z+(8+4), r21
+ adc r20, r1
+ st Z+, r20
+ dec r19
+ brne 1b
+ /* add block to ctx->b */
+ ld r26, Z+
+ ld r27, Z
+ movw r30, MB0
+ ldi r19, 16
+1:
+ ld r0, X
+ ld r18, Z+
+ add r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ adc r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ adc r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ adc r0, r18
+ st X+, r0
+ dec r19
+ brne 1b
+ /* call shbal_p */
+ rcall shabal_p
+ /* sub block from ctx->c */
+ movw r30, CTX0
+ adiw r30, 8+2
+ ld r26, Z+
+ ld r27, Z
+ movw r30, MB0
+ ldi r19, 16
+1:
+ ld r0, X
+ ld r18, Z+
+ sub r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ sbc r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ sbc r0, r18
+ st X+, r0
+ ld r0, X
+ ld r18, Z+
+ sbc r0, r18
+ st X+, r0
+ dec r19
+ brne 1b
+ /* xchange ctx->b with ctx->c*/
+ movw r30, CTX0
+ ldd r22, Z+8
+ ldd r23, Z+9
+ ldd r24, Z+10
+ ldd r25, Z+11
+ std Z+10, r22
+ std Z+11, r23
+ std Z+8, r24
+ std Z+9, r25
+ pop_range 14, 17
+ ret
+
+/******************************************************************************/
+/*
+void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
+ uint8_t i,j;
+ uint32_t* t;
+ uint8_t buffer[64];
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(ctx, block);
+ block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ memset(buffer, 0, 64);
+ memcpy(buffer, block, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80>>(length_b%8);
+ for(i=0;i<16;++i){
+ ctx->b[i] += ((uint32_t*)buffer)[i];
+ }
+ for(j=0; j<4;++j){
+ ctx->a[0] ^= ctx->w.w32[0];
+ ctx->a[1] ^= ctx->w.w32[1];
+ shabal_p(ctx, buffer);
+ t = ctx->c;
+ ctx->c = ctx->b;
+ ctx->b = t;
+ }
+}
+*/
+I = 16
+LEN0 = 16
+LEN1 = 17
+CTX0 = 14
+CTX1 = 15
+MB0 = 12
+MB1 = 13
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ * param length_b: r20:r21
+ */
+.global shabal_lastBlock
+shabal_lastBlock:
+ push_range 12, 17
+ movw CTX0, r24
+ movw MB0, r22
+ movw LEN0, r20
+1:
+ cpi LEN1, 0x02
+ brlo 2f
+ movw r24, CTX0
+ movw r22, MB0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ ldi r18, 64
+ add MB0, r18
+ adc MB1, r1
+ rjmp 1b
+2:
+ stack_alloc_large 64
+ adiw r30, 1 /* Z points at buffer */
+ movw r26, MB0
+ /* r24 = LEN/8*/
+ movw r24, LEN0
+ lsr r25
+ ror r24
+ lsr r24
+ lsr r24
+ ldi r25, 64-1
+ sub r25, r24
+ tst r24
+ breq 32f
+31:
+ ld r0, X+
+ st Z+, r0
+ dec r24
+ brne 31b
+32:
+ ldi r18, 0x80
+ andi LEN0, 0x07
+ breq append_0x80
+ ld r0, X+
+33:
+ lsr r18
+ dec LEN0
+ brne 33b
+ or r0, r18
+ st Z+, r0
+ rjmp append_zeros
+append_0x80:
+ st Z+, r18
+append_zeros:
+ tst r25
+ breq 4f
+34: st Z+, r1
+ dec r25
+ brne 34b
+4:
+ sbiw r30, 63
+ sbiw r30, 1
+ movw MB0, r30
+ movw r26, CTX0
+ adiw r26, 8
+ ld r24, X+
+ ld r25, X
+ movw r26, r24
+ ldi r18, 16
+41:
+ ld r24, X
+ ld r25, Z+
+ add r24, r25
+ st X+, r24
+ ld r24, X
+ ld r25, Z+
+ adc r24, r25
+ st X+, r24
+ ld r24, X
+ ld r25, Z+
+ adc r24, r25
+ st X+, r24
+ ld r24, X
+ ld r25, Z+
+ adc r24, r25
+ st X+, r24
+ dec r18
+ brne 41b
+ /* final loop */
+ ldi I, 4
+5:
+ /* xor W into A */
+ movw r30, CTX0
+ ldi r19, 8
+51:
+ ld r24, Z+
+ ldd r25, Z+(8+4-1)
+ eor r24, r25
+ std Z+(8+4-1), r24
+ dec r19
+ brne 51b
+ movw r24, CTX0
+ movw r22, MB0
+ rcall shabal_p
+ movw r30, CTX0
+ ldd r22, Z+8
+ ldd r23, Z+9
+ ldd r24, Z+10
+ ldd r25, Z+11
+ std Z+10, r22
+ std Z+11, r23
+ std Z+8, r24
+ std Z+9, r25
+ dec I
+ brne 5b
+
+ stack_free_large 64
+ pop_range 12, 17
+ ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* shabal.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-17
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <string.h>
+
+#define SHABAL_O1 13
+#define SHABAL_O2 9
+#define SHABAL_O3 6
+
+
+static inline
+uint32_t shabal_u(uint32_t a){
+ return (a<<1)+a; /* a*3 */
+}
+
+static inline
+uint32_t shabal_v(uint32_t a){
+ return (a<<2)+a; /* a*5 */
+}
+
+#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
+
+static
+void shabal_p(shabal_ctx_t* ctx, const void* m){
+ uint8_t i,j;
+ for(i=0;i<16;++i){
+ ctx->b[i] = ROTL32(ctx->b[i],17);
+ }
+ for(j=0;j<SHABAL_P;j++){
+ for(i=0;i<16;++i){
+ ctx->a[(i+j*16)%SHABAL_R] =
+ shabal_u(ctx->a[(i+j*16)%SHABAL_R]
+ ^ shabal_v(ROTL32(ctx->a[(i+j*16+SHABAL_R-1)%SHABAL_R],15))
+ ^ ctx->c[(8-i+16)%16])
+ ^ ctx->b[(i+SHABAL_O1)%16]
+ ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
+ ^ ((uint32_t*)m)[i];
+ ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+j*16)%SHABAL_R]);
+ }
+ }
+
+ for(j=0;j<36;++j){
+ ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
+ }
+}
+
+void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
+ uint8_t i;
+ uint32_t* t;
+ for(i=0;i<16;++i){
+ ctx->b[i] += ((uint32_t*)block)[i];
+ }
+ ctx->a[0] ^= ctx->w.w32[0];
+ ctx->a[1] ^= ctx->w.w32[1];
+ shabal_p(ctx, block);
+ for(i=0;i<16;++i){
+ ctx->c[i] -= ((uint32_t*)block)[i];
+ }
+ ctx->w.w64++;
+ t = ctx->c;
+ ctx->c = ctx->b;
+ ctx->b = t;
+}
+
+void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
+ uint8_t i,j;
+ uint32_t* t;
+ uint8_t buffer[64];
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(ctx, block);
+ block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ memset(buffer, 0, 64);
+ memcpy(buffer, block, (length_b+7)/8);
+ buffer[length_b/8] |= 0x80>>(length_b%8);
+
+ for(i=0;i<16;++i){
+ ctx->b[i] += ((uint32_t*)buffer)[i];
+ }
+
+ for(j=0; j<4;++j){
+ ctx->a[0] ^= ctx->w.w32[0];
+ ctx->a[1] ^= ctx->w.w32[1];
+ shabal_p(ctx, buffer);
+ t = ctx->c;
+ ctx->c = ctx->b;
+ ctx->b = t;
+ }
+
+}
+
+void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b){
+ memcpy(dest, &(ctx->c[16-outlength_b/32]), outlength_b/8);
+}
--- /dev/null
+/* shabal.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-17
+ * \license GPLv3 or later
+ *
+ */
+
+#ifndef SHABAL_H_
+#define SHABAL_H_
+
+#include <stdint.h>
+
+#define SHABAL_BLOCKSIZE 512
+#define SHABAL_BLOCKSIZE_B ((SHABAL_BLOCKSIZE+7)/8)
+
+#define SHABAL_R 12
+#define SHABAL_P 3
+
+typedef struct{
+ union{
+ uint64_t w64;
+ uint32_t w32[2];
+ } w; /* the counter */
+ uint32_t *b;
+ uint32_t *c;
+ uint32_t a[SHABAL_R];
+ uint32_t b_buffer[16];
+ uint32_t c_buffer[16];
+}shabal_ctx_t;
+
+
+void shabal192_init(shabal_ctx_t* ctx);
+void shabal224_init(shabal_ctx_t* ctx);
+void shabal256_init(shabal_ctx_t* ctx);
+void shabal384_init(shabal_ctx_t* ctx);
+void shabal512_init(shabal_ctx_t* ctx);
+
+void shabal_nextBlock(shabal_ctx_t* ctx, const void* block);
+void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b);
+
+void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx);
+
+void shabal192(void* dest, void* msg, uint32_t length_b);
+void shabal224(void* dest, void* msg, uint32_t length_b);
+void shabal256(void* dest, void* msg, uint32_t length_b);
+void shabal384(void* dest, void* msg, uint32_t length_b);
+void shabal512(void* dest, void* msg, uint32_t length_b);
+
+void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b);
+
+#endif /* SHABAL_H_ */
--- /dev/null
+/* shabal192-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal192-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+shabal192_iv:
+ /* A */
+.long 0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E
+.long 0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465
+.long 0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9
+ /* B */
+.long 0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824
+.long 0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7
+.long 0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319
+.long 0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C
+ /* C */
+.long 0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B
+.long 0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640
+.long 0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3
+.long 0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
+
+
+/******************************************************************************/
+/*
+void shabal192_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal192_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+16+i]));
+ }
+}
+*/
+/*
+ * param ctx: r24,r25
+ */
+.global shabal192_init
+shabal192_init:
+ movw r26, r24
+ ldi r24, 1
+ st X+, r24
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ movw r24, r26
+ adiw r24, 12*4+2+2
+ st X+, r24
+ st X+, r25
+ adiw r24, 4*16-1
+ adiw r24, 1
+ st X+, r24
+ st X+, r25
+ ldi r24, (12+16+16)
+ ldi r30, lo8(shabal192_iv)
+ ldi r31, hi8(shabal192_iv)
+1: lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+ * param dest: r24:r25
+ * param ctx: r22:r23
+ */
+.global shabal192_ctx2hash
+shabal192_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ ldd r24, Z+(8+2)
+ ldd r25, Z+(8+2+1)
+ movw r30, r24
+ adiw r30, (16-192/32)*4
+ ldi r24, 192/8
+1: ld r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+void shabal192(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal192_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal192_ctx2hash(dest, &ctx);
+}
+*/
+/*
+ * param dest: r24:r25
+ * param msg: r22:r23
+ * param length_b: r18:r21
+ */
+DST0 = 8
+DST1 = 9
+CTX0 = 10
+CTX1 = 11
+MSG0 = 12
+MSG1 = 13
+LEN2 = 14
+LEN3 = 15
+LEN0 = 16
+LEN1 = 17
+.global shabal192
+shabal192:
+ push_range 8, 17
+ stack_alloc_large 188
+ adiw r30, 1 /* Z points to stack space (ctx) */
+ movw CTX0, r30
+ movw DST0, r24
+ movw MSG0, r22
+ movw LEN0, r18
+ movw LEN2, r20
+ movw r24, r30
+ rcall shabal192_init
+2:
+ tst LEN2
+ brne 3f
+ tst LEN3
+ breq 4f
+3:
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ sbc LEN2, r1
+ sbc LEN3, r1
+ ldi r18, 64
+ add MSG0, r18
+ adc MSG1, r1
+ rjmp 2b
+4:
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LEN0
+ rcall shabal_lastBlock
+ movw r24, DST0
+ movw r22, CTX0
+ rcall shabal192_ctx2hash
+ stack_free_large2 188
+ pop_range 8, 17
+ ret
+
+
--- /dev/null
+/* shabal192.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal192.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <avr/pgmspace.h>
+#include <string.h>
+
+uint32_t shabal192_iv[] PROGMEM = {
+ /* A */
+ 0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E,
+ 0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465,
+ 0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9,
+ /* B */
+ 0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824,
+ 0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7,
+ 0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319,
+ 0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C,
+ /* C */
+ 0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B,
+ 0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640,
+ 0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3,
+ 0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
+};
+
+void shabal192_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal192_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+16+i]));
+ }
+}
+
+void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+ shabal_ctx2hash(dest, ctx, 192);
+}
+
+void shabal192(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal192_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal192_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* shabal224-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal224-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+
+shabal224_iv:
+ /* A */
+.long 0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B
+.long 0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F
+.long 0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061
+ /* B */
+.long 0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498
+.long 0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5
+.long 0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0
+.long 0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C
+ /* C */
+.long 0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD
+.long 0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18
+.long 0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2
+.long 0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
+
+
+/******************************************************************************/
+/*
+ * param ctx: r24,r25
+ */
+.global shabal224_init
+shabal224_init:
+ movw r26, r24
+ ldi r24, 1
+ st X+, r24
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ movw r24, r26
+ adiw r24, 12*4+4
+ st X+, r24
+ st X+, r25
+ adiw r24, 4*16-1
+ adiw r24, 1
+ st X+, r24
+ st X+, r25
+ ldi r24, (12+16+16)
+ ldi r30, lo8(shabal224_iv)
+ ldi r31, hi8(shabal224_iv)
+1: lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+
+.global shabal224_ctx2hash
+shabal224_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ ldd r24, Z+(8+2)
+ ldd r25, Z+(8+2+1)
+ movw r30, r24
+ adiw r30, (16-224/32)*4
+ ldi r24, 224/8
+1: ld r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+ * param dest: r24:r25
+ * param msg: r22:r23
+ * param length_b: r18:r21
+ */
+DST0 = 8
+DST1 = 9
+CTX0 = 10
+CTX1 = 11
+MSG0 = 12
+MSG1 = 13
+LEN2 = 14
+LEN3 = 15
+LEN0 = 16
+LEN1 = 17
+.global shabal224
+shabal224:
+ push_range 8, 17
+ stack_alloc_large 188
+ adiw r30, 1 /* Z points to stack space (ctx) */
+ movw CTX0, r30
+ movw DST0, r24
+ movw MSG0, r22
+ movw LEN0, r18
+ movw LEN2, r20
+ movw r24, r30
+ rcall shabal224_init
+2:
+ tst LEN2
+ brne 3f
+ tst LEN3
+ breq 4f
+3:
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ sbc LEN2, r1
+ sbc LEN3, r1
+ ldi r18, 64
+ add MSG0, r18
+ adc MSG1, r1
+ rjmp 2b
+4:
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LEN0
+ rcall shabal_lastBlock
+ movw r24, DST0
+ movw r22, CTX0
+ rcall shabal224_ctx2hash
+ stack_free_large2 188
+ pop_range 8, 17
+ ret
+
+
--- /dev/null
+/* shabal224.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal224.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <avr/pgmspace.h>
+#include <string.h>
+
+uint32_t shabal224_iv[] PROGMEM = {
+ /* A */
+ 0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B,
+ 0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F,
+ 0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061,
+ /* B */
+ 0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498,
+ 0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5,
+ 0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0,
+ 0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C,
+ /* C */
+ 0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD,
+ 0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18,
+ 0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2,
+ 0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
+};
+
+void shabal224_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal224_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+16+i]));
+ }
+}
+
+void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+ shabal_ctx2hash(dest, ctx, 224);
+}
+
+void shabal224(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal224_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal224_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* shabal256-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal256-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+
+shabal256_iv:
+ /* A */
+.long 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191
+.long 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C
+.long 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A
+ /* B */
+.long 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F
+.long 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002
+.long 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890
+.long 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5
+ /* C */
+.long 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55
+.long 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433
+.long 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F
+.long 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
+
+/******************************************************************************/
+/*
+ * param ctx: r24,r25
+ */
+.global shabal256_init
+shabal256_init:
+ movw r26, r24
+ ldi r24, 1
+ st X+, r24
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ movw r24, r26
+ adiw r24, 12*4+4
+ st X+, r24
+ st X+, r25
+ adiw r24, 4*16-1
+ adiw r24, 1
+ st X+, r24
+ st X+, r25
+ ldi r24, (12+16+16)
+ ldi r30, lo8(shabal256_iv)
+ ldi r31, hi8(shabal256_iv)
+1: lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+
+.global shabal256_ctx2hash
+shabal256_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ ldd r24, Z+(8+2)
+ ldd r25, Z+(8+2+1)
+ movw r30, r24
+ adiw r30, (16-256/32)*4
+ ldi r24, 256/8
+1: ld r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+ * param dest: r24:r25
+ * param msg: r22:r23
+ * param length_b: r18:r21
+ */
+DST0 = 8
+DST1 = 9
+CTX0 = 10
+CTX1 = 11
+MSG0 = 12
+MSG1 = 13
+LEN2 = 14
+LEN3 = 15
+LEN0 = 16
+LEN1 = 17
+.global shabal256
+shabal256:
+ push_range 8, 17
+ stack_alloc_large 188
+ adiw r30, 1 /* Z points to stack space (ctx) */
+ movw CTX0, r30
+ movw DST0, r24
+ movw MSG0, r22
+ movw LEN0, r18
+ movw LEN2, r20
+ movw r24, r30
+ rcall shabal256_init
+2:
+ tst LEN2
+ brne 3f
+ tst LEN3
+ breq 4f
+3:
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ sbc LEN2, r1
+ sbc LEN3, r1
+ ldi r18, 64
+ add MSG0, r18
+ adc MSG1, r1
+ rjmp 2b
+4:
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LEN0
+ rcall shabal_lastBlock
+ movw r24, DST0
+ movw r22, CTX0
+ rcall shabal256_ctx2hash
+ stack_free_large2 188
+ pop_range 8, 17
+ ret
+
+
--- /dev/null
+/* shabal256.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal256.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <avr/pgmspace.h>
+#include <string.h>
+
+uint32_t shabal256_iv[] PROGMEM = {
+ /* A */
+ 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191,
+ 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C,
+ 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A,
+ /* B */
+ 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F,
+ 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002,
+ 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890,
+ 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5,
+ /* C */
+ 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55,
+ 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433,
+ 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F,
+ 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
+};
+
+void shabal256_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal256_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+16+i]));
+ }
+}
+
+void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+ shabal_ctx2hash(dest, ctx, 256);
+}
+
+void shabal256(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal256_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal256_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* shabal384-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal384-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+
+shabal384_iv:
+ /* A */
+.long 0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83
+.long 0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF
+.long 0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D
+ /* B */
+.long 0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F
+.long 0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641
+.long 0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8
+.long 0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36
+ /* C */
+.long 0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399
+.long 0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261
+.long 0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C
+.long 0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
+
+/******************************************************************************/
+/*
+ * param ctx: r24,r25
+ */
+.global shabal384_init
+shabal384_init:
+ movw r26, r24
+ ldi r24, 1
+ st X+, r24
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ movw r24, r26
+ adiw r24, 12*4+4
+ st X+, r24
+ st X+, r25
+ adiw r24, 4*16-1
+ adiw r24, 1
+ st X+, r24
+ st X+, r25
+ ldi r24, (12+16+16)
+ ldi r30, lo8(shabal384_iv)
+ ldi r31, hi8(shabal384_iv)
+1: lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+
+.global shabal384_ctx2hash
+shabal384_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ ldd r24, Z+(8+2)
+ ldd r25, Z+(8+2+1)
+ movw r30, r24
+ adiw r30, (16-384/32)*4
+ ldi r24, 384/8
+1: ld r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+ * param dest: r24:r25
+ * param msg: r22:r23
+ * param length_b: r18:r21
+ */
+DST0 = 8
+DST1 = 9
+CTX0 = 10
+CTX1 = 11
+MSG0 = 12
+MSG1 = 13
+LEN2 = 14
+LEN3 = 15
+LEN0 = 16
+LEN1 = 17
+.global shabal384
+shabal384:
+ push_range 8, 17
+ stack_alloc_large 188
+ adiw r30, 1 /* Z points to stack space (ctx) */
+ movw CTX0, r30
+ movw DST0, r24
+ movw MSG0, r22
+ movw LEN0, r18
+ movw LEN2, r20
+ movw r24, r30
+ rcall shabal384_init
+2:
+ tst LEN2
+ brne 3f
+ tst LEN3
+ breq 4f
+3:
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ sbc LEN2, r1
+ sbc LEN3, r1
+ ldi r18, 64
+ add MSG0, r18
+ adc MSG1, r1
+ rjmp 2b
+4:
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LEN0
+ rcall shabal_lastBlock
+ movw r24, DST0
+ movw r22, CTX0
+ rcall shabal384_ctx2hash
+ stack_free_large2 188
+ pop_range 8, 17
+ ret
+
--- /dev/null
+/* shabal384.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal384.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <avr/pgmspace.h>
+#include <string.h>
+
+uint32_t shabal384_iv[] PROGMEM = {
+ /* A */
+ 0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83,
+ 0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF,
+ 0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D,
+ /* B */
+ 0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F,
+ 0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641,
+ 0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8,
+ 0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36,
+ /* C */
+ 0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399,
+ 0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261,
+ 0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C,
+ 0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
+};
+
+void shabal384_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal384_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+16+i]));
+ }
+}
+
+void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+ shabal_ctx2hash(dest, ctx, 384);
+}
+
+void shabal384(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal384_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal384_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* shabal512-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal512-asm.S
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+
+shabal512_iv:
+ /* A */
+.long 0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632
+.long 0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B
+.long 0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F
+ /* B */
+.long 0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640
+.long 0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08
+.long 0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E
+.long 0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B
+ /* C */
+.long 0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359
+.long 0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780
+.long 0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A
+.long 0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969
+
+/******************************************************************************/
+/*
+ * param ctx: r24,r25
+ */
+.global shabal512_init
+shabal512_init:
+ movw r26, r24
+ ldi r24, 1
+ st X+, r24
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ st X+, r1
+ movw r24, r26
+ adiw r24, 12*4+4
+ st X+, r24
+ st X+, r25
+ adiw r24, 4*16-1
+ adiw r24, 1
+ st X+, r24
+ st X+, r25
+ ldi r24, (12+16+16)
+ ldi r30, lo8(shabal512_iv)
+ ldi r31, hi8(shabal512_iv)
+1: lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ lpm r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+
+.global shabal512_ctx2hash
+shabal512_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ ldd r24, Z+(8+2)
+ ldd r25, Z+(8+2+1)
+ movw r30, r24
+ ; adiw r30, (16-512/32)*4
+ ldi r24, 512/8
+1: ld r0, Z+
+ st X+, r0
+ dec r24
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+ * param dest: r24:r25
+ * param msg: r22:r23
+ * param length_b: r18:r21
+ */
+DST0 = 8
+DST1 = 9
+CTX0 = 10
+CTX1 = 11
+MSG0 = 12
+MSG1 = 13
+LEN2 = 14
+LEN3 = 15
+LEN0 = 16
+LEN1 = 17
+.global shabal512
+shabal512:
+ push_range 8, 17
+ stack_alloc_large 188
+ adiw r30, 1 /* Z points to stack space (ctx) */
+ movw CTX0, r30
+ movw DST0, r24
+ movw MSG0, r22
+ movw LEN0, r18
+ movw LEN2, r20
+ movw r24, r30
+ rcall shabal512_init
+2:
+ tst LEN2
+ brne 3f
+ tst LEN3
+ breq 4f
+3:
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall shabal_nextBlock
+ subi LEN1, 0x02
+ sbc LEN2, r1
+ sbc LEN3, r1
+ ldi r18, 64
+ add MSG0, r18
+ adc MSG1, r1
+ rjmp 2b
+4:
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LEN0
+ rcall shabal_lastBlock
+ movw r24, DST0
+ movw r22, CTX0
+ rcall shabal512_ctx2hash
+ stack_free_large2 188
+ pop_range 8, 17
+ ret
+
--- /dev/null
+/* shabal512.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file shabal512.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-04-27
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include "shabal.h"
+#include <avr/pgmspace.h>
+#include <string.h>
+
+uint32_t shabal512_iv[] PROGMEM = {
+ /* A */
+ 0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632,
+ 0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B,
+ 0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F,
+ /* B */
+ 0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640,
+ 0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08,
+ 0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E,
+ 0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B,
+ /* C */
+ 0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359,
+ 0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780,
+ 0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A,
+ 0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969,
+};
+
+void shabal512_init(shabal_ctx_t* ctx){
+ uint8_t i;
+ ctx->b = ctx->b_buffer;
+ ctx->c = ctx->c_buffer;
+ ctx->w.w64 = 1LL;
+ for(i=0;i<SHABAL_R;++i){
+ ctx->a[i] = pgm_read_dword(&(shabal512_iv[i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->b[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+i]));
+ }
+ for(i=0;i<16;++i){
+ ctx->c[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+16+i]));
+ }
+}
+
+void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx){
+ shabal_ctx2hash(dest, ctx, 512);
+}
+
+void shabal512(void* dest, void* msg, uint32_t length_b){
+ shabal_ctx_t ctx;
+ shabal512_init(&ctx);
+ while(length_b>=SHABAL_BLOCKSIZE){
+ shabal_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
+ length_b -= SHABAL_BLOCKSIZE;
+ }
+ shabal_lastBlock(&ctx, msg, length_b);
+ shabal512_ctx2hash(dest, &ctx);
+}
--- /dev/null
+test
+
+Test vectors for Shabal (192 bits):
+message:
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+hash:
+ 0F 70 6E CB 97 CF 4D CE 00 BF BB D2 FB 64 53 0C
+ 32 87 0C B4 48 39 73 0D
+
+Test vectors for Shabal (192 bits):
+message:
+ 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
+ 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34
+ 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A
+ 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
+ 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64
+ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74
+ 75 76 77 78 79 7A
+hash:
+ 69 0F AE 79 22 6D 95 76 0A E8 FD B4 F5 8C 05 37
+ 11 17 56 55 7D 30 7B 15
+
+Test vectors for Shabal (224 bits):
+message:
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+hash:
+ 99 DD A6 14 F9 07 D2 E8 81 76 18 F7 30 69 6F 32
+ 00 AE CA 8B 5F 85 F4 25 43 BA 20 31
+
+Test vectors for Shabal (224 bits):
+message:
+ 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
+ 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34
+ 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A
+ 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
+ 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64
+ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74
+ 75 76 77 78 79 7A
+hash:
+ C7 D6 2D 8D 2A 34 74 B4 F4 A9 D1 1A 52 DB 3D 43
+ 5B F1 58 CF 45 4C 5D 56 1D 71 25 F5
+
+Test vectors for Shabal (256 bits):
+message:
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+hash:
+ DA 8F 08 C0 2A 67 BA 9A 56 BD D0 79 8E 48 AE 07
+ 14 21 5E 09 3B 5B 85 06 49 A3 77 18 99 3F 54 A2
+
+Test vectors for Shabal (256 bits):
+message:
+ 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
+ 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34
+ 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A
+ 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
+ 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64
+ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74
+ 75 76 77 78 79 7A
+hash:
+ B4 9F 34 BF 51 86 4C 30 53 3C C4 6C C2 54 2B DE
+ C2 F9 6F D0 6F 5C 53 9A FF 6E AD 58 83 F7 32 7A
+
+Test vectors for Shabal (384 bits):
+message:
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+hash:
+ 9D DE 12 33 91 0D 85 DA 3A 5C 78 03 12 B1 11 C6
+ FC CA 1B 5D D2 55 37 03 5E E0 8E 3B 4E 1E 25 15
+ 4F 72 6A 63 84 E5 A8 F0 AF EA AB 4A C4 C0 2F 12
+
+Test vectors for Shabal (384 bits):
+message:
+ 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
+ 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34
+ 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A
+ 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
+ 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64
+ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74
+ 75 76 77 78 79 7A
+hash:
+ 30 01 2C 0E 3E DC 46 0B D7 86 27 C2 C3 09 44 D2
+ A1 89 66 9A FA 2D 7A 97 13 EF 2F 77 4C 44 74 A4
+ 3A F1 CB CE C5 FA B4 24 8C 08 73 F0 38 FB EB A0
+
+Test vectors for Shabal (512 bits):
+message:
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+hash:
+ 15 80 16 C6 C8 1F 3F 0A 52 D9 8D 68 ED 2F 9E 8E
+ 78 95 EF 23 CB A7 E2 BC 61 09 D8 A5 32 E6 C9 E6
+ A6 A5 01 97 9F B8 37 F0 4E C4 C6 20 E7 31 79 DC
+ 82 AB B5 2B 32 CD AD B3 56 50 E2 9C 98 5E 30 22
+
+Test vectors for Shabal (512 bits):
+message:
+ 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
+ 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34
+ 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A
+ 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
+ 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64
+ 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74
+ 75 76 77 78 79 7A
+hash:
+ 67 7E 6F 7F 12 D7 0A F0 B3 35 66 2F 59 B5 68 51
+ F3 65 3E 66 64 7D 33 86 DF DA 01 43 25 4C C8 A5
+ DB 3E 21 94 06 8C 6F 71 59 7D 7B 60 98 4D 22 B4
+ 7A 1F 60 D9 1C A8 DF CB 17 5D 65 B9 73 59 CE CF
+>
\ No newline at end of file
--- /dev/null
+%!PS-Adobe-3.0
+%%BoundingBox: 24 24 571 818
+%%Title: Enscript Output
+%%For:
+%%Creator: GNU enscript 1.6.4
+%%CreationDate: Mon Apr 27 00:59:17 2009
+%%Orientation: Portrait
+%%Pages: (atend)
+%%DocumentMedia: A4 595 842 0 () ()
+%%DocumentNeededResources: (atend)
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Enscript-Prolog 1.6 4
+%
+% Procedures.
+%
+
+/_S { % save current state
+ /_s save def
+} def
+/_R { % restore from saved state
+ _s restore
+} def
+
+/S { % showpage protecting gstate
+ gsave
+ showpage
+ grestore
+} bind def
+
+/MF { % fontname newfontname -> - make a new encoded font
+ /newfontname exch def
+ /fontname exch def
+
+ /fontdict fontname findfont def
+ /newfont fontdict maxlength dict def
+
+ fontdict {
+ exch
+ dup /FID eq {
+ % skip FID pair
+ pop pop
+ } {
+ % copy to the new font dictionary
+ exch newfont 3 1 roll put
+ } ifelse
+ } forall
+
+ newfont /FontName newfontname put
+
+ % insert only valid encoding vectors
+ encoding_vector length 256 eq {
+ newfont /Encoding encoding_vector put
+ } if
+
+ newfontname newfont definefont pop
+} def
+
+/MF_PS { % fontname newfontname -> - make a new font preserving its enc
+ /newfontname exch def
+ /fontname exch def
+
+ /fontdict fontname findfont def
+ /newfont fontdict maxlength dict def
+
+ fontdict {
+ exch
+ dup /FID eq {
+ % skip FID pair
+ pop pop
+ } {
+ % copy to the new font dictionary
+ exch newfont 3 1 roll put
+ } ifelse
+ } forall
+
+ newfont /FontName newfontname put
+
+ newfontname newfont definefont pop
+} def
+
+/SF { % fontname width height -> - set a new font
+ /height exch def
+ /width exch def
+
+ findfont
+ [width 0 0 height 0 0] makefont setfont
+} def
+
+/SUF { % fontname width height -> - set a new user font
+ /height exch def
+ /width exch def
+
+ /F-gs-user-font MF
+ /F-gs-user-font width height SF
+} def
+
+/SUF_PS { % fontname width height -> - set a new user font preserving its enc
+ /height exch def
+ /width exch def
+
+ /F-gs-user-font MF_PS
+ /F-gs-user-font width height SF
+} def
+
+/M {moveto} bind def
+/s {show} bind def
+
+/Box { % x y w h -> - define box path
+ /d_h exch def /d_w exch def /d_y exch def /d_x exch def
+ d_x d_y moveto
+ d_w 0 rlineto
+ 0 d_h rlineto
+ d_w neg 0 rlineto
+ closepath
+} def
+
+/bgs { % x y height blskip gray str -> - show string with bg color
+ /str exch def
+ /gray exch def
+ /blskip exch def
+ /height exch def
+ /y exch def
+ /x exch def
+
+ gsave
+ x y blskip sub str stringwidth pop height Box
+ gray setgray
+ fill
+ grestore
+ x y M str s
+} def
+
+/bgcs { % x y height blskip red green blue str -> - show string with bg color
+ /str exch def
+ /blue exch def
+ /green exch def
+ /red exch def
+ /blskip exch def
+ /height exch def
+ /y exch def
+ /x exch def
+
+ gsave
+ x y blskip sub str stringwidth pop height Box
+ red green blue setrgbcolor
+ fill
+ grestore
+ x y M str s
+} def
+
+% Highlight bars.
+/highlight_bars { % nlines lineheight output_y_margin gray -> -
+ gsave
+ setgray
+ /ymarg exch def
+ /lineheight exch def
+ /nlines exch def
+
+ % This 2 is just a magic number to sync highlight lines to text.
+ 0 d_header_y ymarg sub 2 sub translate
+
+ /cw d_output_w cols div def
+ /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
+
+ % for each column
+ 0 1 cols 1 sub {
+ cw mul /xp exch def
+
+ % for each rows
+ 0 1 nrows 1 sub {
+ /rn exch def
+ rn lineheight mul neg /yp exch def
+ rn nlines idiv 2 mod 0 eq {
+ % Draw highlight bar. 4 is just a magic indentation.
+ xp 4 add yp cw 8 sub lineheight neg Box fill
+ } if
+ } for
+ } for
+
+ grestore
+} def
+
+% Line highlight bar.
+/line_highlight { % x y width height gray -> -
+ gsave
+ /gray exch def
+ Box gray setgray fill
+ grestore
+} def
+
+% Column separator lines.
+/column_lines {
+ gsave
+ .1 setlinewidth
+ 0 d_footer_h translate
+ /cw d_output_w cols div def
+ 1 1 cols 1 sub {
+ cw mul 0 moveto
+ 0 d_output_h rlineto stroke
+ } for
+ grestore
+} def
+
+% Column borders.
+/column_borders {
+ gsave
+ .1 setlinewidth
+ 0 d_footer_h moveto
+ 0 d_output_h rlineto
+ d_output_w 0 rlineto
+ 0 d_output_h neg rlineto
+ closepath stroke
+ grestore
+} def
+
+% Do the actual underlay drawing
+/draw_underlay {
+ ul_style 0 eq {
+ ul_str true charpath stroke
+ } {
+ ul_str show
+ } ifelse
+} def
+
+% Underlay
+/underlay { % - -> -
+ gsave
+ 0 d_page_h translate
+ d_page_h neg d_page_w atan rotate
+
+ ul_gray setgray
+ ul_font setfont
+ /dw d_page_h dup mul d_page_w dup mul add sqrt def
+ ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
+ draw_underlay
+ grestore
+} def
+
+/user_underlay { % - -> -
+ gsave
+ ul_x ul_y translate
+ ul_angle rotate
+ ul_gray setgray
+ ul_font setfont
+ 0 0 ul_h_ptsize 2 div sub moveto
+ draw_underlay
+ grestore
+} def
+
+% Page prefeed
+/page_prefeed { % bool -> -
+ statusdict /prefeed known {
+ statusdict exch /prefeed exch put
+ } {
+ pop
+ } ifelse
+} def
+
+% Wrapped line markers
+/wrapped_line_mark { % x y charwith charheight type -> -
+ /type exch def
+ /h exch def
+ /w exch def
+ /y exch def
+ /x exch def
+
+ type 2 eq {
+ % Black boxes (like TeX does)
+ gsave
+ 0 setlinewidth
+ x w 4 div add y M
+ 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
+ closepath fill
+ grestore
+ } {
+ type 3 eq {
+ % Small arrows
+ gsave
+ .2 setlinewidth
+ x w 2 div add y h 2 div add M
+ w 4 div 0 rlineto
+ x w 4 div add y lineto stroke
+
+ x w 4 div add w 8 div add y h 4 div add M
+ x w 4 div add y lineto
+ w 4 div h 8 div rlineto stroke
+ grestore
+ } {
+ % do nothing
+ } ifelse
+ } ifelse
+} def
+
+% EPSF import.
+
+/BeginEPSF {
+ /b4_Inc_state save def % Save state for cleanup
+ /dict_count countdictstack def % Count objects on dict stack
+ /op_count count 1 sub def % Count objects on operand stack
+ userdict begin
+ /showpage { } def
+ 0 setgray 0 setlinecap
+ 1 setlinewidth 0 setlinejoin
+ 10 setmiterlimit [ ] 0 setdash newpath
+ /languagelevel where {
+ pop languagelevel
+ 1 ne {
+ false setstrokeadjust false setoverprint
+ } if
+ } if
+} bind def
+
+/EndEPSF {
+ count op_count sub { pos } repeat % Clean up stacks
+ countdictstack dict_count sub { end } repeat
+ b4_Inc_state restore
+} bind def
+
+% Check PostScript language level.
+/languagelevel where {
+ pop /gs_languagelevel languagelevel def
+} {
+ /gs_languagelevel 1 def
+} ifelse
+%%EndResource
+%%BeginResource: procset Enscript-Encoding-88591 1.6 4
+/encoding_vector [
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign
+/dollar /percent /ampersand /quoteright
+/parenleft /parenright /asterisk /plus
+/comma /hyphen /period /slash
+/zero /one /two /three
+/four /five /six /seven
+/eight /nine /colon /semicolon
+/less /equal /greater /question
+/at /A /B /C
+/D /E /F /G
+/H /I /J /K
+/L /M /N /O
+/P /Q /R /S
+/T /U /V /W
+/X /Y /Z /bracketleft
+/backslash /bracketright /asciicircum /underscore
+/quoteleft /a /b /c
+/d /e /f /g
+/h /i /j /k
+/l /m /n /o
+/p /q /r /s
+/t /u /v /w
+/x /y /z /braceleft
+/bar /braceright /tilde /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/space /exclamdown /cent /sterling
+/currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft
+/logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior
+/acute /mu /paragraph /bullet
+/cedilla /onesuperior /ordmasculine /guillemotright
+/onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde
+/Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis
+/Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute
+/Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex
+/Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde
+/adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis
+/igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute
+/ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex
+/udieresis /yacute /thorn /ydieresis
+] def
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeResource: font Courier-Bold
+%%IncludeResource: font Courier
+/HFpt_w 10 def
+/HFpt_h 10 def
+/Courier-Bold /HF-gs-font MF
+/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
+/Courier /F-gs-font MF
+/F-gs-font 10 10 SF
+/#copies 1 def
+% Pagedevice definitions:
+gs_languagelevel 1 gt {
+ <<
+ /PageSize [595 842]
+ >> setpagedevice
+} if
+%%BeginResource: procset Enscript-Header-simple 1.6 4
+
+/do_header { % print default simple header
+ gsave
+ d_header_x d_header_y HFpt_h 3 div add translate
+
+ HF setfont
+ user_header_p {
+ 5 0 moveto user_header_left_str show
+
+ d_header_w user_header_center_str stringwidth pop sub 2 div
+ 0 moveto user_header_center_str show
+
+ d_header_w user_header_right_str stringwidth pop sub 5 sub
+ 0 moveto user_header_right_str show
+ } {
+ 5 0 moveto fname show
+ 45 0 rmoveto fmodstr show
+ 45 0 rmoveto pagenumstr show
+ } ifelse
+
+ grestore
+} def
+%%EndResource
+/d_page_w 547 def
+/d_page_h 794 def
+/d_header_x 0 def
+/d_header_y 779 def
+/d_header_w 547 def
+/d_header_h 15 def
+/d_footer_x 0 def
+/d_footer_y 0 def
+/d_footer_w 547 def
+/d_footer_h 0 def
+/d_output_w 547 def
+/d_output_h 779 def
+/cols 1 def
+%%EndSetup
+%%Page: (1) 1
+%%BeginPageSetup
+_S
+24 24 translate
+/pagenum 1 def
+/fname (shabal_shorttest.log) def
+/fdir () def
+/ftail (shabal_shorttest.log) def
+% User defined strings:
+/fmodstr (Mon Apr 27 00:58:21 2009) def
+/pagenumstr (1) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+do_header
+5 766 M
+(test) s
+5 744 M
+(Test vectors for Shabal \(192 bits\):) s
+5 733 M
+(message:) s
+5 722 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 711 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 700 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 689 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 678 M
+(hash:) s
+5 667 M
+( 0F 70 6E CB 97 CF 4D CE 00 BF BB D2 FB 64 53 0C ) s
+5 656 M
+( 32 87 0C B4 48 39 73 0D ) s
+5 634 M
+(Test vectors for Shabal \(192 bits\):) s
+5 623 M
+(message:) s
+5 612 M
+( 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 601 M
+( 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 590 M
+( 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 579 M
+( 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 568 M
+( 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 557 M
+( 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 546 M
+( 75 76 77 78 79 7A ) s
+5 535 M
+(hash:) s
+5 524 M
+( 69 0F AE 79 22 6D 95 76 0A E8 FD B4 F5 8C 05 37 ) s
+5 513 M
+( 11 17 56 55 7D 30 7B 15 ) s
+5 491 M
+(Test vectors for Shabal \(224 bits\):) s
+5 480 M
+(message:) s
+5 469 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 458 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 447 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 436 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 425 M
+(hash:) s
+5 414 M
+( 99 DD A6 14 F9 07 D2 E8 81 76 18 F7 30 69 6F 32 ) s
+5 403 M
+( 00 AE CA 8B 5F 85 F4 25 43 BA 20 31 ) s
+5 381 M
+(Test vectors for Shabal \(224 bits\):) s
+5 370 M
+(message:) s
+5 359 M
+( 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 348 M
+( 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 337 M
+( 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 326 M
+( 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 315 M
+( 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 304 M
+( 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 293 M
+( 75 76 77 78 79 7A ) s
+5 282 M
+(hash:) s
+5 271 M
+( C7 D6 2D 8D 2A 34 74 B4 F4 A9 D1 1A 52 DB 3D 43 ) s
+5 260 M
+( 5B F1 58 CF 45 4C 5D 56 1D 71 25 F5 ) s
+5 238 M
+(Test vectors for Shabal \(256 bits\):) s
+5 227 M
+(message:) s
+5 216 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 205 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 194 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 183 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 172 M
+(hash:) s
+5 161 M
+( DA 8F 08 C0 2A 67 BA 9A 56 BD D0 79 8E 48 AE 07 ) s
+5 150 M
+( 14 21 5E 09 3B 5B 85 06 49 A3 77 18 99 3F 54 A2 ) s
+5 128 M
+(Test vectors for Shabal \(256 bits\):) s
+5 117 M
+(message:) s
+5 106 M
+( 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 95 M
+( 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 84 M
+( 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 73 M
+( 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 62 M
+( 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 51 M
+( 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 40 M
+( 75 76 77 78 79 7A ) s
+5 29 M
+(hash:) s
+5 18 M
+( B4 9F 34 BF 51 86 4C 30 53 3C C4 6C C2 54 2B DE ) s
+5 7 M
+( C2 F9 6F D0 6F 5C 53 9A FF 6E AD 58 83 F7 32 7A ) s
+_R
+S
+%%Page: (2) 2
+%%BeginPageSetup
+_S
+24 24 translate
+/pagenum 2 def
+/fname (shabal_shorttest.log) def
+/fdir () def
+/ftail (shabal_shorttest.log) def
+% User defined strings:
+/fmodstr (Mon Apr 27 00:58:21 2009) def
+/pagenumstr (2) def
+/user_header_p false def
+/user_footer_p false def
+%%EndPageSetup
+do_header
+5 755 M
+(Test vectors for Shabal \(384 bits\):) s
+5 744 M
+(message:) s
+5 733 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 722 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 711 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 700 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 689 M
+(hash:) s
+5 678 M
+( 9D DE 12 33 91 0D 85 DA 3A 5C 78 03 12 B1 11 C6 ) s
+5 667 M
+( FC CA 1B 5D D2 55 37 03 5E E0 8E 3B 4E 1E 25 15 ) s
+5 656 M
+( 4F 72 6A 63 84 E5 A8 F0 AF EA AB 4A C4 C0 2F 12 ) s
+5 634 M
+(Test vectors for Shabal \(384 bits\):) s
+5 623 M
+(message:) s
+5 612 M
+( 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 601 M
+( 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 590 M
+( 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 579 M
+( 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 568 M
+( 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 557 M
+( 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 546 M
+( 75 76 77 78 79 7A ) s
+5 535 M
+(hash:) s
+5 524 M
+( 30 01 2C 0E 3E DC 46 0B D7 86 27 C2 C3 09 44 D2 ) s
+5 513 M
+( A1 89 66 9A FA 2D 7A 97 13 EF 2F 77 4C 44 74 A4 ) s
+5 502 M
+( 3A F1 CB CE C5 FA B4 24 8C 08 73 F0 38 FB EB A0 ) s
+5 480 M
+(Test vectors for Shabal \(512 bits\):) s
+5 469 M
+(message:) s
+5 458 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 447 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 436 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 425 M
+( 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ) s
+5 414 M
+(hash:) s
+5 403 M
+( 15 80 16 C6 C8 1F 3F 0A 52 D9 8D 68 ED 2F 9E 8E ) s
+5 392 M
+( 78 95 EF 23 CB A7 E2 BC 61 09 D8 A5 32 E6 C9 E6 ) s
+5 381 M
+( A6 A5 01 97 9F B8 37 F0 4E C4 C6 20 E7 31 79 DC ) s
+5 370 M
+( 82 AB B5 2B 32 CD AD B3 56 50 E2 9C 98 5E 30 22 ) s
+5 348 M
+(Test vectors for Shabal \(512 bits\):) s
+5 337 M
+(message:) s
+5 326 M
+( 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 ) s
+5 315 M
+( 71 72 73 74 75 76 77 78 79 7A 2D 30 31 32 33 34 ) s
+5 304 M
+( 35 36 37 38 39 2D 41 42 43 44 45 46 47 48 49 4A ) s
+5 293 M
+( 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A ) s
+5 282 M
+( 2D 30 31 32 33 34 35 36 37 38 39 2D 61 62 63 64 ) s
+5 271 M
+( 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 ) s
+5 260 M
+( 75 76 77 78 79 7A ) s
+5 249 M
+(hash:) s
+5 238 M
+( 67 7E 6F 7F 12 D7 0A F0 B3 35 66 2F 59 B5 68 51 ) s
+5 227 M
+( F3 65 3E 66 64 7D 33 86 DF DA 01 43 25 4C C8 A5 ) s
+5 216 M
+( DB 3E 21 94 06 8C 6F 71 59 7D 7B 60 98 4D 22 B4 ) s
+5 205 M
+( 7A 1F 60 D9 1C A8 DF CB 17 5D 65 B9 73 59 CE CF ) s
+5 194 M
+(>) s
+_R
+S
+%%Trailer
+%%Pages: 2
+%%DocumentNeededResources: font Courier-Bold Courier
+%%EOF
+++ /dev/null
-/* shabal192-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal192-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-shabal192_iv:
- /* A */
-.long 0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E
-.long 0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465
-.long 0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9
- /* B */
-.long 0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824
-.long 0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7
-.long 0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319
-.long 0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C
- /* C */
-.long 0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B
-.long 0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640
-.long 0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3
-.long 0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
-
-
-/******************************************************************************/
-/*
-void shabal192_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal192_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+16+i]));
- }
-}
-*/
-/*
- * param ctx: r24,r25
- */
-.global shabal192_init
-shabal192_init:
- movw r26, r24
- ldi r24, 1
- st X+, r24
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- movw r24, r26
- adiw r24, 12*4+2+2
- st X+, r24
- st X+, r25
- adiw r24, 4*16-1
- adiw r24, 1
- st X+, r24
- st X+, r25
- ldi r24, (12+16+16)
- ldi r30, lo8(shabal192_iv)
- ldi r31, hi8(shabal192_iv)
-1: lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
- * param dest: r24:r25
- * param ctx: r22:r23
- */
-.global shabal192_ctx2hash
-shabal192_ctx2hash:
- movw r26, r24
- movw r30, r22
- ldd r24, Z+(8+2)
- ldd r25, Z+(8+2+1)
- movw r30, r24
- adiw r30, (16-192/32)*4
- ldi r24, 192/8
-1: ld r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
-void shabal192(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal192_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal192_ctx2hash(dest, &ctx);
-}
-*/
-/*
- * param dest: r24:r25
- * param msg: r22:r23
- * param length_b: r18:r21
- */
-DST0 = 8
-DST1 = 9
-CTX0 = 10
-CTX1 = 11
-MSG0 = 12
-MSG1 = 13
-LEN2 = 14
-LEN3 = 15
-LEN0 = 16
-LEN1 = 17
-.global shabal192
-shabal192:
- push_range 8, 17
- stack_alloc_large 188
- adiw r30, 1 /* Z points to stack space (ctx) */
- movw CTX0, r30
- movw DST0, r24
- movw MSG0, r22
- movw LEN0, r18
- movw LEN2, r20
- movw r24, r30
- rcall shabal192_init
-2:
- tst LEN2
- brne 3f
- tst LEN3
- breq 4f
-3:
- movw r24, CTX0
- movw r22, MSG0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- sbc LEN2, r1
- sbc LEN3, r1
- ldi r18, 64
- add MSG0, r18
- adc MSG1, r1
- rjmp 2b
-4:
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LEN0
- rcall shabal_lastBlock
- movw r24, DST0
- movw r22, CTX0
- rcall shabal192_ctx2hash
- stack_free_large2 188
- pop_range 8, 17
- ret
-
-
+++ /dev/null
-/* shabal192.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal192.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <avr/pgmspace.h>
-#include <string.h>
-
-uint32_t shabal192_iv[] PROGMEM = {
- /* A */
- 0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E,
- 0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465,
- 0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9,
- /* B */
- 0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824,
- 0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7,
- 0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319,
- 0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C,
- /* C */
- 0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B,
- 0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640,
- 0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3,
- 0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
-};
-
-void shabal192_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal192_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+16+i]));
- }
-}
-
-void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx){
- shabal_ctx2hash(dest, ctx, 192);
-}
-
-void shabal192(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal192_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal192_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* shabal224-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal224-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-
-shabal224_iv:
- /* A */
-.long 0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B
-.long 0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F
-.long 0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061
- /* B */
-.long 0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498
-.long 0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5
-.long 0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0
-.long 0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C
- /* C */
-.long 0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD
-.long 0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18
-.long 0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2
-.long 0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
-
-
-/******************************************************************************/
-/*
- * param ctx: r24,r25
- */
-.global shabal224_init
-shabal224_init:
- movw r26, r24
- ldi r24, 1
- st X+, r24
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- movw r24, r26
- adiw r24, 12*4+4
- st X+, r24
- st X+, r25
- adiw r24, 4*16-1
- adiw r24, 1
- st X+, r24
- st X+, r25
- ldi r24, (12+16+16)
- ldi r30, lo8(shabal224_iv)
- ldi r31, hi8(shabal224_iv)
-1: lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-
-.global shabal224_ctx2hash
-shabal224_ctx2hash:
- movw r26, r24
- movw r30, r22
- ldd r24, Z+(8+2)
- ldd r25, Z+(8+2+1)
- movw r30, r24
- adiw r30, (16-224/32)*4
- ldi r24, 224/8
-1: ld r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
- * param dest: r24:r25
- * param msg: r22:r23
- * param length_b: r18:r21
- */
-DST0 = 8
-DST1 = 9
-CTX0 = 10
-CTX1 = 11
-MSG0 = 12
-MSG1 = 13
-LEN2 = 14
-LEN3 = 15
-LEN0 = 16
-LEN1 = 17
-.global shabal224
-shabal224:
- push_range 8, 17
- stack_alloc_large 188
- adiw r30, 1 /* Z points to stack space (ctx) */
- movw CTX0, r30
- movw DST0, r24
- movw MSG0, r22
- movw LEN0, r18
- movw LEN2, r20
- movw r24, r30
- rcall shabal224_init
-2:
- tst LEN2
- brne 3f
- tst LEN3
- breq 4f
-3:
- movw r24, CTX0
- movw r22, MSG0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- sbc LEN2, r1
- sbc LEN3, r1
- ldi r18, 64
- add MSG0, r18
- adc MSG1, r1
- rjmp 2b
-4:
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LEN0
- rcall shabal_lastBlock
- movw r24, DST0
- movw r22, CTX0
- rcall shabal224_ctx2hash
- stack_free_large2 188
- pop_range 8, 17
- ret
-
-
+++ /dev/null
-/* shabal224.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal224.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <avr/pgmspace.h>
-#include <string.h>
-
-uint32_t shabal224_iv[] PROGMEM = {
- /* A */
- 0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B,
- 0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F,
- 0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061,
- /* B */
- 0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498,
- 0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5,
- 0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0,
- 0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C,
- /* C */
- 0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD,
- 0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18,
- 0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2,
- 0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
-};
-
-void shabal224_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal224_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+16+i]));
- }
-}
-
-void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx){
- shabal_ctx2hash(dest, ctx, 224);
-}
-
-void shabal224(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal224_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal224_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* shabal256-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal256-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-
-shabal256_iv:
- /* A */
-.long 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191
-.long 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C
-.long 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A
- /* B */
-.long 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F
-.long 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002
-.long 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890
-.long 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5
- /* C */
-.long 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55
-.long 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433
-.long 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F
-.long 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
-
-/******************************************************************************/
-/*
- * param ctx: r24,r25
- */
-.global shabal256_init
-shabal256_init:
- movw r26, r24
- ldi r24, 1
- st X+, r24
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- movw r24, r26
- adiw r24, 12*4+4
- st X+, r24
- st X+, r25
- adiw r24, 4*16-1
- adiw r24, 1
- st X+, r24
- st X+, r25
- ldi r24, (12+16+16)
- ldi r30, lo8(shabal256_iv)
- ldi r31, hi8(shabal256_iv)
-1: lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-
-.global shabal256_ctx2hash
-shabal256_ctx2hash:
- movw r26, r24
- movw r30, r22
- ldd r24, Z+(8+2)
- ldd r25, Z+(8+2+1)
- movw r30, r24
- adiw r30, (16-256/32)*4
- ldi r24, 256/8
-1: ld r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
- * param dest: r24:r25
- * param msg: r22:r23
- * param length_b: r18:r21
- */
-DST0 = 8
-DST1 = 9
-CTX0 = 10
-CTX1 = 11
-MSG0 = 12
-MSG1 = 13
-LEN2 = 14
-LEN3 = 15
-LEN0 = 16
-LEN1 = 17
-.global shabal256
-shabal256:
- push_range 8, 17
- stack_alloc_large 188
- adiw r30, 1 /* Z points to stack space (ctx) */
- movw CTX0, r30
- movw DST0, r24
- movw MSG0, r22
- movw LEN0, r18
- movw LEN2, r20
- movw r24, r30
- rcall shabal256_init
-2:
- tst LEN2
- brne 3f
- tst LEN3
- breq 4f
-3:
- movw r24, CTX0
- movw r22, MSG0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- sbc LEN2, r1
- sbc LEN3, r1
- ldi r18, 64
- add MSG0, r18
- adc MSG1, r1
- rjmp 2b
-4:
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LEN0
- rcall shabal_lastBlock
- movw r24, DST0
- movw r22, CTX0
- rcall shabal256_ctx2hash
- stack_free_large2 188
- pop_range 8, 17
- ret
-
-
+++ /dev/null
-/* shabal256.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal256.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <avr/pgmspace.h>
-#include <string.h>
-
-uint32_t shabal256_iv[] PROGMEM = {
- /* A */
- 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191,
- 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C,
- 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A,
- /* B */
- 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F,
- 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002,
- 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890,
- 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5,
- /* C */
- 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55,
- 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433,
- 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F,
- 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
-};
-
-void shabal256_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal256_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+16+i]));
- }
-}
-
-void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx){
- shabal_ctx2hash(dest, ctx, 256);
-}
-
-void shabal256(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal256_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal256_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* shabal384-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal384-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-
-shabal384_iv:
- /* A */
-.long 0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83
-.long 0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF
-.long 0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D
- /* B */
-.long 0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F
-.long 0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641
-.long 0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8
-.long 0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36
- /* C */
-.long 0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399
-.long 0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261
-.long 0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C
-.long 0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
-
-/******************************************************************************/
-/*
- * param ctx: r24,r25
- */
-.global shabal384_init
-shabal384_init:
- movw r26, r24
- ldi r24, 1
- st X+, r24
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- movw r24, r26
- adiw r24, 12*4+4
- st X+, r24
- st X+, r25
- adiw r24, 4*16-1
- adiw r24, 1
- st X+, r24
- st X+, r25
- ldi r24, (12+16+16)
- ldi r30, lo8(shabal384_iv)
- ldi r31, hi8(shabal384_iv)
-1: lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-
-.global shabal384_ctx2hash
-shabal384_ctx2hash:
- movw r26, r24
- movw r30, r22
- ldd r24, Z+(8+2)
- ldd r25, Z+(8+2+1)
- movw r30, r24
- adiw r30, (16-384/32)*4
- ldi r24, 384/8
-1: ld r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
- * param dest: r24:r25
- * param msg: r22:r23
- * param length_b: r18:r21
- */
-DST0 = 8
-DST1 = 9
-CTX0 = 10
-CTX1 = 11
-MSG0 = 12
-MSG1 = 13
-LEN2 = 14
-LEN3 = 15
-LEN0 = 16
-LEN1 = 17
-.global shabal384
-shabal384:
- push_range 8, 17
- stack_alloc_large 188
- adiw r30, 1 /* Z points to stack space (ctx) */
- movw CTX0, r30
- movw DST0, r24
- movw MSG0, r22
- movw LEN0, r18
- movw LEN2, r20
- movw r24, r30
- rcall shabal384_init
-2:
- tst LEN2
- brne 3f
- tst LEN3
- breq 4f
-3:
- movw r24, CTX0
- movw r22, MSG0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- sbc LEN2, r1
- sbc LEN3, r1
- ldi r18, 64
- add MSG0, r18
- adc MSG1, r1
- rjmp 2b
-4:
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LEN0
- rcall shabal_lastBlock
- movw r24, DST0
- movw r22, CTX0
- rcall shabal384_ctx2hash
- stack_free_large2 188
- pop_range 8, 17
- ret
-
+++ /dev/null
-/* shabal384.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal384.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <avr/pgmspace.h>
-#include <string.h>
-
-uint32_t shabal384_iv[] PROGMEM = {
- /* A */
- 0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83,
- 0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF,
- 0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D,
- /* B */
- 0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F,
- 0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641,
- 0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8,
- 0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36,
- /* C */
- 0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399,
- 0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261,
- 0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C,
- 0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
-};
-
-void shabal384_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal384_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+16+i]));
- }
-}
-
-void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx){
- shabal_ctx2hash(dest, ctx, 384);
-}
-
-void shabal384(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal384_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal384_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* shabal512-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal512-asm.S
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-
-shabal512_iv:
- /* A */
-.long 0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632
-.long 0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B
-.long 0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F
- /* B */
-.long 0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640
-.long 0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08
-.long 0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E
-.long 0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B
- /* C */
-.long 0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359
-.long 0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780
-.long 0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A
-.long 0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969
-
-/******************************************************************************/
-/*
- * param ctx: r24,r25
- */
-.global shabal512_init
-shabal512_init:
- movw r26, r24
- ldi r24, 1
- st X+, r24
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- st X+, r1
- movw r24, r26
- adiw r24, 12*4+4
- st X+, r24
- st X+, r25
- adiw r24, 4*16-1
- adiw r24, 1
- st X+, r24
- st X+, r25
- ldi r24, (12+16+16)
- ldi r30, lo8(shabal512_iv)
- ldi r31, hi8(shabal512_iv)
-1: lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- lpm r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-
-.global shabal512_ctx2hash
-shabal512_ctx2hash:
- movw r26, r24
- movw r30, r22
- ldd r24, Z+(8+2)
- ldd r25, Z+(8+2+1)
- movw r30, r24
- ; adiw r30, (16-512/32)*4
- ldi r24, 512/8
-1: ld r0, Z+
- st X+, r0
- dec r24
- brne 1b
- ret
-
-/******************************************************************************/
-/*
- * param dest: r24:r25
- * param msg: r22:r23
- * param length_b: r18:r21
- */
-DST0 = 8
-DST1 = 9
-CTX0 = 10
-CTX1 = 11
-MSG0 = 12
-MSG1 = 13
-LEN2 = 14
-LEN3 = 15
-LEN0 = 16
-LEN1 = 17
-.global shabal512
-shabal512:
- push_range 8, 17
- stack_alloc_large 188
- adiw r30, 1 /* Z points to stack space (ctx) */
- movw CTX0, r30
- movw DST0, r24
- movw MSG0, r22
- movw LEN0, r18
- movw LEN2, r20
- movw r24, r30
- rcall shabal512_init
-2:
- tst LEN2
- brne 3f
- tst LEN3
- breq 4f
-3:
- movw r24, CTX0
- movw r22, MSG0
- rcall shabal_nextBlock
- subi LEN1, 0x02
- sbc LEN2, r1
- sbc LEN3, r1
- ldi r18, 64
- add MSG0, r18
- adc MSG1, r1
- rjmp 2b
-4:
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LEN0
- rcall shabal_lastBlock
- movw r24, DST0
- movw r22, CTX0
- rcall shabal512_ctx2hash
- stack_free_large2 188
- pop_range 8, 17
- ret
-
+++ /dev/null
-/* shabal512.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file shabal512.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-04-27
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include "shabal.h"
-#include <avr/pgmspace.h>
-#include <string.h>
-
-uint32_t shabal512_iv[] PROGMEM = {
- /* A */
- 0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632,
- 0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B,
- 0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F,
- /* B */
- 0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640,
- 0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08,
- 0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E,
- 0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B,
- /* C */
- 0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359,
- 0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780,
- 0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A,
- 0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969,
-};
-
-void shabal512_init(shabal_ctx_t* ctx){
- uint8_t i;
- ctx->b = ctx->b_buffer;
- ctx->c = ctx->c_buffer;
- ctx->w.w64 = 1LL;
- for(i=0;i<SHABAL_R;++i){
- ctx->a[i] = pgm_read_dword(&(shabal512_iv[i]));
- }
- for(i=0;i<16;++i){
- ctx->b[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+i]));
- }
- for(i=0;i<16;++i){
- ctx->c[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+16+i]));
- }
-}
-
-void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx){
- shabal_ctx2hash(dest, ctx, 512);
-}
-
-void shabal512(void* dest, void* msg, uint32_t length_b){
- shabal_ctx_t ctx;
- shabal512_init(&ctx);
- while(length_b>=SHABAL_BLOCKSIZE){
- shabal_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
- length_b -= SHABAL_BLOCKSIZE;
- }
- shabal_lastBlock(&ctx, msg, length_b);
- shabal512_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* skein.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file skein.c
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#ifndef SKEIN_H_
-#define SKEIN_H_
-
-#include <stdint.h>
-#include "ubi.h"
-
-#define SKEIN256_BLOCKSIZE UBI256_BLOCKSIZE
-#define SKEIN256_BLOCKSIZE_B UBI256_BLOCKSIZE_B
-
-#define SKEIN512_BLOCKSIZE UBI512_BLOCKSIZE
-#define SKEIN512_BLOCKSIZE_B UBI512_BLOCKSIZE_B
-
-#define SKEIN1024_BLOCKSIZE UBI1024_BLOCKSIZE
-#define SKEIN1024_BLOCKSIZE_B UBI1024_BLOCKSIZE_B
-
-typedef struct{
- uint16_t outsize_b;
- ubi256_ctx_t ubictx;
-}skein256_ctx_t;
-
-void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b);
-void skein256_nextBlock(skein256_ctx_t* ctx, const void* block);
-void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b);
-void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx);
-void skein256(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
-
-typedef struct{
- uint16_t outsize_b;
- ubi512_ctx_t ubictx;
-}skein512_ctx_t;
-
-void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b);
-void skein512_nextBlock(skein512_ctx_t* ctx, const void* block);
-void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b);
-void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx);
-void skein512(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
-
-typedef struct{
- uint16_t outsize_b;
- ubi1024_ctx_t ubictx;
-}skein1024_ctx_t;
-
-void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b);
-void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block);
-void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b);
-void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx);
-void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
-
-#endif /* SKEIN_H_ */
--- /dev/null
+/* memxor.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: memxor.S
+ * Author: Daniel Otte
+ * Date: 2008-08-07
+ * License: GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+ * param dest is passed in r24:r25
+ * param src is passed in r22:r23
+ * param n is passed in r20:r21
+ */
+.global memxor
+memxor:
+ movw r30, r24
+ movw r26, r22
+ movw r24, r20
+ adiw r24, 0
+ breq 2f
+1:
+ ld r20, X+
+ ld r21, Z
+ eor r20, r21
+ st Z+, r20
+ sbiw r24, 1
+ brne 1b
+2:
+ ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
--- /dev/null
+performance
+
+ === Skein-256-128 performance ===
+ type: hashfunction
+ hashsize (bits): 128
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 42999
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41706
+ ctx2hash (cycles): 42912
+
+ === Skein-256-160 performance ===
+ type: hashfunction
+ hashsize (bits): 160
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 42999
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41713
+ ctx2hash (cycles): 42940
+
+ === Skein-256-224 performance ===
+ type: hashfunction
+ hashsize (bits): 224
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 43006
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41713
+ ctx2hash (cycles): 42996
+
+ === Skein-256-256 performance ===
+ type: hashfunction
+ hashsize (bits): 256
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 43006
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41706
+ ctx2hash (cycles): 43026
+
+ === Skein-256-384 performance ===
+ type: hashfunction
+ hashsize (bits): 384
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 42999
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41706
+ ctx2hash (cycles): 20054
+
+ === Skein-256-512 performance ===
+ type: hashfunction
+ hashsize (bits): 512
+ ctxsize (bytes): 50
+ blocksize (bits): 256
+ init (cycles): 42999
+ nextBlock (cycles): 42003
+ lastBlock (cycles): 41706
+ ctx2hash (cycles): 20165
+
+ === Skein-512-128 performance ===
+ type: hashfunction
+ hashsize (bits): 128
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30522
+ nextBlock (cycles): 29183
+ lastBlock (cycles): 28526
+ ctx2hash (cycles): 30515
+
+ === Skein-512-160 performance ===
+ type: hashfunction
+ hashsize (bits): 160
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30522
+ nextBlock (cycles): 29183
+ lastBlock (cycles): 28526
+ ctx2hash (cycles): 30536
+
+ === Skein-512-224 performance ===
+ type: hashfunction
+ hashsize (bits): 224
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30522
+ nextBlock (cycles): 29176
+ lastBlock (cycles): 28526
+ ctx2hash (cycles): 30592
+
+ === Skein-512-256 performance ===
+ type: hashfunction
+ hashsize (bits): 256
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30522
+ nextBlock (cycles): 29176
+ lastBlock (cycles): 28533
+ ctx2hash (cycles): 30620
+
+ === Skein-512-384 performance ===
+ type: hashfunction
+ hashsize (bits): 384
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30529
+ nextBlock (cycles): 29176
+ lastBlock (cycles): 28533
+ ctx2hash (cycles): 30732
+
+ === Skein-512-512 performance ===
+ type: hashfunction
+ hashsize (bits): 512
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30529
+ nextBlock (cycles): 29176
+ lastBlock (cycles): 28533
+ ctx2hash (cycles): 30846
+
+ === Skein-512-1024 performance ===
+ type: hashfunction
+ hashsize (bits): 1024
+ ctxsize (bytes): 82
+ blocksize (bits): 512
+ init (cycles): 30529
+ nextBlock (cycles): 29176
+ lastBlock (cycles): 28526
+ ctx2hash (cycles): 61119
+
+ === Skein-1024-128 performance ===
+ type: hashfunction
+ hashsize (bits): 128
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28976
+ nextBlock (cycles): 26263
+ lastBlock (cycles): 23978
+ ctx2hash (cycles): 27216
+
+ === Skein-1024-160 performance ===
+ type: hashfunction
+ hashsize (bits): 160
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26256
+ lastBlock (cycles): 23978
+ ctx2hash (cycles): 27244
+
+ === Skein-1024-224 performance ===
+ type: hashfunction
+ hashsize (bits): 224
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26256
+ lastBlock (cycles): 23978
+ ctx2hash (cycles): 27307
+
+ === Skein-1024-256 performance ===
+ type: hashfunction
+ hashsize (bits): 256
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26263
+ lastBlock (cycles): 23971
+ ctx2hash (cycles): 27335
+
+ === Skein-1024-384 performance ===
+ type: hashfunction
+ hashsize (bits): 384
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26263
+ lastBlock (cycles): 23971
+ ctx2hash (cycles): 27447
+
+ === Skein-1024-512 performance ===
+ type: hashfunction
+ hashsize (bits): 512
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26263
+ lastBlock (cycles): 23971
+ ctx2hash (cycles): 27559
+
+ === Skein-1024-1024 performance ===
+ type: hashfunction
+ hashsize (bits): 1024
+ ctxsize (bytes): 146
+ blocksize (bits): 1024
+ init (cycles): 28983
+ nextBlock (cycles): 26263
+ lastBlock (cycles): 23971
+ ctx2hash (cycles): 28002
+>
\ No newline at end of file
--- /dev/null
+/* skein.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file skein.c
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#ifndef SKEIN_H_
+#define SKEIN_H_
+
+#include <stdint.h>
+#include "ubi.h"
+
+#define SKEIN256_BLOCKSIZE UBI256_BLOCKSIZE
+#define SKEIN256_BLOCKSIZE_B UBI256_BLOCKSIZE_B
+
+#define SKEIN512_BLOCKSIZE UBI512_BLOCKSIZE
+#define SKEIN512_BLOCKSIZE_B UBI512_BLOCKSIZE_B
+
+#define SKEIN1024_BLOCKSIZE UBI1024_BLOCKSIZE
+#define SKEIN1024_BLOCKSIZE_B UBI1024_BLOCKSIZE_B
+
+typedef struct{
+ uint16_t outsize_b;
+ ubi256_ctx_t ubictx;
+}skein256_ctx_t;
+
+void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b);
+void skein256_nextBlock(skein256_ctx_t* ctx, const void* block);
+void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx);
+void skein256(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+typedef struct{
+ uint16_t outsize_b;
+ ubi512_ctx_t ubictx;
+}skein512_ctx_t;
+
+void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b);
+void skein512_nextBlock(skein512_ctx_t* ctx, const void* block);
+void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx);
+void skein512(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+typedef struct{
+ uint16_t outsize_b;
+ ubi1024_ctx_t ubictx;
+}skein1024_ctx_t;
+
+void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b);
+void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block);
+void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b);
+void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx);
+void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b);
+
+#endif /* SKEIN_H_ */
--- /dev/null
+/* skein1024.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+
+void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI1024_BLOCKSIZE_B];
+ memset(null, 0, UBI1024_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi1024_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi1024_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block){
+ ubi1024_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b){
+ ubi1024_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx){
+ ubi1024_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI1024_BLOCKSIZE_B];
+ ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi1024_ctx_t));
+ ubi1024_lastBlock(&uctx, &counter, 64);
+ ubi1024_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI1024_BLOCKSIZE){
+ memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI1024_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI1024_BLOCKSIZE_B;
+ outsize_b -= UBI1024_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+
+void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
+ skein1024_ctx_t ctx;
+ skein1024_init(&ctx, outlength_b);
+ while(length_b>SKEIN1024_BLOCKSIZE){
+ skein1024_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN1024_BLOCKSIZE_B;
+ length_b -= SKEIN1024_BLOCKSIZE;
+ }
+ skein1024_lastBlock(&ctx, msg, length_b);
+ skein1024_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* skein1024_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-25
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI1024_BLOCKSIZE_B];
+ memset(null, 0, UBI1024_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi1024_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi1024_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param outsize_b: r22:r23
+ */
+UBICTX0 = 2
+UBICTX1 = 3
+CONF0 = 4
+CONF1 = 5
+.global skein1024_init
+skein1024_init:
+ push_range 2, 5
+ stack_alloc_large 32+128-22 ; |<- 22 ->|
+ adiw r30, 1 ; | CONF (32) |
+ movw CONF0, r30 ; | null (128) |
+ movw r26, r24
+ st X+, r22
+ st X+, r23
+ movw UBICTX0, r26
+ ldi r24, 'S'
+ st Z+, r24
+ ldi r24, 'H'
+ st Z+, r24
+ ldi r24, 'A'
+ st Z+, r24
+ ldi r24, '3'
+ st Z+, r24
+ ldi r24, 1
+ st Z+, r24
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r22
+ st Z+, r23
+ ldi 24, 128
+1: st Z+, r1
+ dec r24
+ brne 1b
+ /* call ubi1024_init*/
+ subi r30, lo8(128)
+ sbci r31, hi8(128)
+ movw r24, UBICTX0
+ movw r22, r30
+ ldi r20, 4
+ rcall ubi1024_init
+ /* call ubi1024_lastBlock*/
+ movw r24, UBICTX0
+ movw r22, CONF0
+ ldi r21, 1
+ clr r20
+ rcall ubi1024_lastBlock
+ /* call ubi1024_init*/
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 48
+ rcall ubi1024_init
+ stack_free_large2 32+128-22
+ pop_range 2, 5
+ ret
+
+/******************************************************************************/
+.global skein1024_nextBlock
+skein1024_nextBlock:
+ adiw r24, 2
+ rjmp ubi1024_nextBlock
+
+/******************************************************************************/
+.global skein1024_lastBlock
+skein1024_lastBlock:
+ adiw r24, 2
+ rjmp ubi1024_lastBlock
+
+/******************************************************************************/
+/*
+void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx){
+ ubi1024_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI1024_BLOCKSIZE_B];
+ ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi1024_ctx_t));
+ ubi1024_lastBlock(&uctx, &counter, 64);
+ ubi1024_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI1024_BLOCKSIZE){
+ memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI1024_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI1024_BLOCKSIZE_B;
+ outsize_b -= UBI1024_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+*/
+/*
+ * param dest: r24:r25
+ * param ctx: r22:r23
+ */
+ OUTSIZE_B0 = 16
+ OUTSIZE_B1 = 17
+ UCTX0 = 14
+ UCTX1 = 15
+ UBICTX0 = 12
+ UBICTX1 = 13
+ DEST0 = 10
+ DEST1 = 11
+.global skein1024_ctx2hash
+skein1024_ctx2hash:
+ push_range 10, 17
+ /* 144 || 8 || 128 */
+ stack_alloc_large 144+8+128 /* uctx || counter || outbuffer */
+ movw DEST0, r24
+ adiw r30, 1
+ movw UCTX0, r30
+ ldi r16, 144
+ add r30, r16
+ adc r31, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ movw r26, 22
+ ld OUTSIZE_B0, X+
+ ld OUTSIZE_B1, X+
+ movw UBICTX0, r26
+ /* call ubi1024_init */
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 63
+ rcall ubi1024_init
+
+ /* main loop */
+ /* copy ubictx in uctx*/
+1: movw r30, UCTX0
+ movw r26, UBICTX0
+ ldi r24, 144
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* call ubi1024_lastBlock */
+ movw r24, UCTX0
+ adiw r24, 63
+ adiw r24, 63
+ adiw r24, 18
+ movw r22, r24
+ movw r24, UCTX0
+ clr r21
+ ldi r20, 64
+ rcall ubi1024_lastBlock
+ /* copy uctx->g to outbuffer */
+ movw r26, UCTX0
+ adiw r26, 16
+ movw r30, UCTX0
+ adiw r30, 63
+ adiw r30, 63
+ adiw r30, 18+8
+ ldi r24, 128
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* compare outsize_b with 1024*/
+ cpi OUTSIZE_B1, 5
+ brge 5f
+ cpi OUTSIZE_B1, 4
+ brlo 3f
+ tst OUTSIZE_B0
+ breq 3f
+5: /* copy outbuffer to dest */
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 63
+ adiw r26, 63
+ adiw r26, 18+8
+ ldi r24, 128
+6: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 6b
+ /* store new dest */
+ movw DEST0, r30
+ /* adjust counter and outsize_b*/
+ subi OUTSIZE_B1, 2
+ movw r30, UCTX0
+ adiw r30, 63
+ adiw r30, 63
+ adiw r30, 18
+ ldi r24, 1
+ ld r25, Z
+ add r25, r24
+ st Z+, r25
+ ldi r24, 7
+6: ld r25, Z
+ adc r25, r1
+ st Z+, r25
+ dec r24
+ brne 6b
+ rjmp 1b
+3: /* last iteraton */
+ movw r24, OUTSIZE_B0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 63
+ adiw r26, 63
+ adiw r26, 18+8
+ tst r24
+ breq 8f
+7: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 7b
+8:
+ stack_free_large3 144+8+128
+ pop_range 10, 17
+ ret
+
+/******************************************************************************/
+/*
+void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
+ skein1024_ctx_t ctx;
+ skein1024_init(&ctx, outlength_b);
+ while(length_b>SKEIN1024_BLOCKSIZE){
+ skein1024_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN1024_BLOCKSIZE_B;
+ length_b -= SKEIN1024_BLOCKSIZE;
+ }
+ skein1024_lastBlock(&ctx, msg, length_b);
+ skein1024_ctx2hash(dest, &ctx);
+}
+*/
+/*
+ * param dest: r24:r25
+ * param outlength_b: r22:r23
+ * param msg: r20:r21
+ * param length_b: r16:r19
+ */
+LENGTH_B0 = 2
+LENGTH_B1 = 3
+LENGTH_B2 = 4
+LENGTH_B3 = 5
+DEST0 = 6
+DEST1 = 7
+MSG0 = 8
+MSG1 = 9
+CTX0 = 10
+CTX1 = 11
+.global skein1024
+skein1024:
+ push_range 2, 11
+ stack_alloc_large 146
+ adiw r30, 1
+ movw CTX0, r30
+ movw DEST0, r24
+ movw MSG0, r20
+ movw LENGTH_B0, r16
+ movw LENGTH_B2, r18
+ /* call skein1024_init */
+ movw r24, r30
+ rcall skein1024_init
+1: tst LENGTH_B2
+ brne 4f
+ tst LENGTH_B3
+ brne 4f
+ /* call skein1024_lastBlock */
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LENGTH_B0
+ rcall skein1024_lastBlock
+ /* call skein1024_ctx2hash */
+ movw r24, DEST0
+ movw r22, CTX0
+ rcall skein1024_ctx2hash
+ /* return */
+ stack_free_large2 146
+ pop_range 2, 11
+ ret
+
+4: /* process preceeding blocks */
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall skein1024_nextBlock
+ ldi r24, 128
+ add MSG0, r24
+ adc MSG0, r1
+ mov r24, LENGTH_B1
+ mov r25, LENGTH_B2
+ sbiw r24, 4
+ sbc LENGTH_B3, r1
+ mov LENGTH_B1, r24
+ mov LENGTH_B2, r25
+ rjmp 1b
+
--- /dev/null
+/* skein256.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+#include "cli.h"
+
+void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI256_BLOCKSIZE_B];
+ memset(null, 0, UBI256_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein256_nextBlock(skein256_ctx_t* ctx, const void* block){
+ ubi256_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b){
+ ubi256_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx){
+ ubi256_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI256_BLOCKSIZE_B];
+ ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
+ ubi256_lastBlock(&uctx, &counter, 64);
+ ubi256_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI256_BLOCKSIZE){
+ memcpy(dest, outbuffer, (outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
+ outsize_b -= UBI256_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+
+void skein256(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
+ skein256_ctx_t ctx;
+ skein256_init(&ctx, outlength_b);
+ while(length_b>SKEIN256_BLOCKSIZE){
+ skein256_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
+ length_b -= SKEIN256_BLOCKSIZE;
+ }
+ skein256_lastBlock(&ctx, msg, length_b);
+ skein256_ctx2hash(dest, &ctx);
+}
--- /dev/null
+/* skein256_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI256_BLOCKSIZE_B];
+ memset(null, 0, UBI256_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param outsize_b: r22:r23
+ */
+UBICTX0 = 2
+UBICTX1 = 3
+CONF0 = 4
+CONF1 = 5
+.global skein256_init
+skein256_init:
+ push_range 2, 5
+ stack_alloc 64-22
+ adiw r30, 1
+ movw CONF0, r30
+ movw r26, r24
+ st X+, r22
+ st X+, r23
+ movw UBICTX0, r26
+ ldi r24, 'S'
+ st Z+, r24
+ ldi r24, 'H'
+ st Z+, r24
+ ldi r24, 'A'
+ st Z+, r24
+ ldi r24, '3'
+ st Z+, r24
+ ldi r24, 1
+ st Z+, r24
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r22
+ st Z+, r23
+ ldi 24, 22+10
+1: st Z+, r1
+ dec r24
+ brne 1b
+ /* call ubi256_init*/
+ sbiw r30, 32
+ movw r24, UBICTX0
+ movw r22, r30
+ ldi r20, 4
+ rcall ubi256_init
+ /* call ubi256_lastBlock*/
+ movw r24, UBICTX0
+ movw r22, CONF0
+ ldi r21, 1
+ clr r20
+ rcall ubi256_lastBlock
+ /* call ubi256_init*/
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 48
+ rcall ubi256_init
+ stack_free 64-22
+ pop_range 2, 5
+ ret
+
+/******************************************************************************/
+.global skein256_nextBlock
+skein256_nextBlock:
+ adiw r24, 2
+ rjmp ubi256_nextBlock
+
+/******************************************************************************/
+.global skein256_lastBlock
+skein256_lastBlock:
+ adiw r24, 2
+ rjmp ubi256_lastBlock
+
+/******************************************************************************/
+/*
+void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx){
+ ubi256_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI256_BLOCKSIZE_B];
+ ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
+ ubi256_lastBlock(&uctx, &counter, 64);
+ ubi256_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI256_BLOCKSIZE){
+ memcpy(dest, outbuffer, (outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
+ outsize_b -= UBI256_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+*/
+/*
+ * param dest: r24:r25
+ * param ctx: r22:r23
+ */
+ OUTSIZE_B0 = 16
+ OUTSIZE_B1 = 17
+ UCTX0 = 14
+ UCTX1 = 15
+ UBICTX0 = 12
+ UBICTX1 = 13
+ DEST0 = 10
+ DEST1 = 11
+.global skein256_ctx2hash
+skein256_ctx2hash:
+ push_range 10, 17
+ /* 48 || 8 || 32 */
+ stack_alloc_large 88 /* uctx || counter || outbuffer */
+ movw DEST0, r24
+ adiw r30, 1
+ movw UCTX0, r30
+ adiw r30, 48
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ movw r26, 22
+ ld OUTSIZE_B0, X+
+ ld OUTSIZE_B1, X+
+ movw UBICTX0, r26
+ /* call ubi256_init */
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 63
+ rcall ubi256_init
+
+ /* main loop */
+ /* copy ubictx in uctx*/
+1: movw r30, UCTX0
+ movw r26, UBICTX0
+ ldi r24, 48
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* call ubi256_lastBlock */
+ movw r24, UCTX0
+ adiw r24, 48
+ movw r22, r24
+ movw r24, UCTX0
+ clr r21
+ ldi r20, 64
+ rcall ubi256_lastBlock
+ /* copy uctx->g to outbuffer */
+ movw r26, UCTX0
+ adiw r26, 16
+ movw r30, UCTX0
+ adiw r30, 56
+ ldi r24, 32
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* compare outsize_b with 256*/
+ cpi OUTSIZE_B1, 2
+ brge 5f
+ cpi OUTSIZE_B1, 1
+ brlo 3f
+ tst OUTSIZE_B0
+ breq 3f
+5: /* copy outbuffer to dest */
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 56
+ ldi r24, 32
+6: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 6b
+ /* store new dest */
+ movw DEST0, r30 ;XXX r26
+ /* adjust counter and outsize_b*/
+ dec OUTSIZE_B1
+ movw r30, UCTX0
+ adiw r30, 48
+ ldi r24, 1
+ ld r25, Z
+ add r25, r24
+ st Z+, r25
+ ldi r24, 7
+6: ld r25, Z
+ adc r25, r1
+ st Z+, r25
+ dec r24
+ brne 6b
+ rjmp 1b
+3: /* last iteraton */
+ movw r24, OUTSIZE_B0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r24
+ lsr r24
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 56
+ tst r24
+ breq 8f
+7: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 7b
+8:
+ stack_free_large 88
+ pop_range 10, 17
+ ret
+
+/******************************************************************************/
+/*
+void skein256(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
+ skein256_ctx_t ctx;
+ skein256_init(&ctx, outlength_b);
+ while(length_b>SKEIN256_BLOCKSIZE){
+ skein256_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
+ length_b -= SKEIN256_BLOCKSIZE;
+ }
+ skein256_lastBlock(&ctx, msg, length_b);
+ skein256_ctx2hash(dest, &ctx);
+}
+*/
+/*
+ * param dest: r24:r25
+ * param outlength_b: r22:r23
+ * param msg: r20:r21
+ * param length_b: r16:r19
+ */
+LENGTH_B0 = 2
+LENGTH_B1 = 3
+LENGTH_B2 = 4
+LENGTH_B3 = 5
+DEST0 = 6
+DEST1 = 7
+MSG0 = 8
+MSG1 = 9
+CTX0 = 10
+CTX1 = 11
+.global skein256
+skein256:
+ push_range 2, 11
+ stack_alloc 50
+ adiw r30, 1
+ movw CTX0, r30
+ movw DEST0, r24
+ movw MSG0, r20
+ movw LENGTH_B0, r16
+ movw LENGTH_B2, r18
+ /* call skein256_init */
+ movw r24, r30
+ rcall skein256_init
+1: tst LENGTH_B2
+ brne 4f
+ tst LENGTH_B3
+ brne 4f
+ /* call skein256_lastBlock */
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LENGTH_B0
+ rcall skein256_lastBlock
+ /* call skein256_ctx2hash */
+ movw r24, DEST0
+ movw r22, CTX0
+ rcall skein256_ctx2hash
+ /* return */
+ stack_free 50
+ pop_range 2, 11
+ ret
+
+4: /* process preceeding blocks */
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall skein256_nextBlock
+ movw r24, MSG0
+ adiw r24, 32
+ movw MSG0, r24
+ mov r24, LENGTH_B1
+ mov r25, LENGTH_B2
+ sbiw r24, 1
+ sbc LENGTH_B3, r1
+ mov LENGTH_B1, r24
+ mov LENGTH_B2, r25
+ rjmp 1b
+
--- /dev/null
+/* skein512.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ubi.h"
+#include "skein.h"
+
+
+void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI512_BLOCKSIZE_B];
+ memset(null, 0, UBI512_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+
+void skein512_nextBlock(skein512_ctx_t* ctx, const void* block){
+ ubi512_nextBlock(&(ctx->ubictx), block);
+}
+
+void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b){
+ ubi512_lastBlock(&(ctx->ubictx), block, length_b);
+}
+
+void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
+ ubi512_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI512_BLOCKSIZE_B];
+ ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
+ ubi512_lastBlock(&uctx, &counter, 64);
+ ubi512_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI512_BLOCKSIZE){
+ memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
+ outsize_b -= UBI512_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+
+void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
+ skein512_ctx_t ctx;
+ skein512_init(&ctx, outlength_b);
+ while(length_b>SKEIN512_BLOCKSIZE){
+ skein512_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
+ length_b -= SKEIN512_BLOCKSIZE;
+ }
+ skein512_lastBlock(&ctx, msg, length_b);
+ skein512_ctx2hash(dest, &ctx);
+}
+
--- /dev/null
+/* skein512_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
+ skein_config_t conf;
+ uint8_t null[UBI512_BLOCKSIZE_B];
+ memset(null, 0, UBI512_BLOCKSIZE_B);
+ memset(&conf, 0, sizeof(skein_config_t));
+ conf.schema[0] = 'S';
+ conf.schema[1] = 'H';
+ conf.schema[2] = 'A';
+ conf.schema[3] = '3';
+ conf.version = 1;
+ conf.out_length = outsize_b;
+ ctx->outsize_b = outsize_b;
+ ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
+ ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
+ ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param outsize_b: r22:r23
+ */
+UBICTX0 = 2
+UBICTX1 = 3
+CONF0 = 4
+CONF1 = 5
+.global skein512_init
+skein512_init:
+ push_range 2, 5
+ stack_alloc_large 32+64-22 ; |<- 22 ->|
+ adiw r30, 1 ; | CONF (32) |
+ movw CONF0, r30 ; | null (64) |
+ movw r26, r24
+ st X+, r22
+ st X+, r23
+ movw UBICTX0, r26
+ ldi r24, 'S'
+ st Z+, r24
+ ldi r24, 'H'
+ st Z+, r24
+ ldi r24, 'A'
+ st Z+, r24
+ ldi r24, '3'
+ st Z+, r24
+ ldi r24, 1
+ st Z+, r24
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r22
+ st Z+, r23
+ ldi 24, 64
+1: st Z+, r1
+ dec r24
+ brne 1b
+ /* call ubi512_init*/
+ sbiw r30, 63
+ sbiw r30, 1
+ movw r24, UBICTX0
+ movw r22, r30
+ ldi r20, 4
+ rcall ubi512_init
+ /* call ubi512_lastBlock*/
+ movw r24, UBICTX0
+ movw r22, CONF0
+ ldi r21, 1
+ clr r20
+ rcall ubi512_lastBlock
+ /* call ubi512_init*/
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 48
+ rcall ubi512_init
+ stack_free_large 32+64-22
+ pop_range 2, 5
+ ret
+
+/******************************************************************************/
+.global skein512_nextBlock
+skein512_nextBlock:
+ adiw r24, 2
+ rjmp ubi512_nextBlock
+
+/******************************************************************************/
+.global skein512_lastBlock
+skein512_lastBlock:
+ adiw r24, 2
+ rjmp ubi512_lastBlock
+
+/******************************************************************************/
+/*
+void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
+ ubi512_ctx_t uctx;
+ uint16_t outsize_b;
+
+ uint64_t counter=0;
+ uint8_t outbuffer[UBI512_BLOCKSIZE_B];
+ ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
+
+ outsize_b = ctx->outsize_b;
+ while(1){
+ memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
+ ubi512_lastBlock(&uctx, &counter, 64);
+ ubi512_ctx2hash(outbuffer, &uctx);
+ if(outsize_b<=UBI512_BLOCKSIZE){
+ memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
+ break;
+ }else{
+ memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
+ dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
+ outsize_b -= UBI512_BLOCKSIZE;
+ counter++;
+ }
+ }
+}
+*/
+/*
+ * param dest: r24:r25
+ * param ctx: r22:r23
+ */
+ OUTSIZE_B0 = 16
+ OUTSIZE_B1 = 17
+ UCTX0 = 14
+ UCTX1 = 15
+ UBICTX0 = 12
+ UBICTX1 = 13
+ DEST0 = 10
+ DEST1 = 11
+.global skein512_ctx2hash
+skein512_ctx2hash:
+ push_range 10, 17
+ /* 80 || 8 || 64 */
+ stack_alloc_large 80+8+64 /* uctx || counter || outbuffer */
+ movw DEST0, r24
+ adiw r30, 1
+ movw UCTX0, r30
+ adiw r30, 63
+ adiw r30, 17
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ st Z+, r1
+ movw r26, 22
+ ld OUTSIZE_B0, X+
+ ld OUTSIZE_B1, X+
+ movw UBICTX0, r26
+ /* call ubi512_init */
+ movw r24, UBICTX0
+ adiw r24, 16
+ movw r22, r24
+ movw r24, UBICTX0
+ ldi r20, 63
+ rcall ubi512_init
+
+ /* main loop */
+ /* copy ubictx in uctx*/
+1: movw r30, UCTX0
+ movw r26, UBICTX0
+ ldi r24, 80
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* call ubi512_lastBlock */
+ movw r24, UCTX0
+ adiw r24, 63
+ adiw r24, 17
+ movw r22, r24
+ movw r24, UCTX0
+ clr r21
+ ldi r20, 64
+ rcall ubi512_lastBlock
+ /* copy uctx->g to outbuffer */
+ movw r26, UCTX0
+ adiw r26, 16
+ movw r30, UCTX0
+ adiw r30, 63
+ adiw r30, 17+8
+ ldi r24, 64
+2: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 2b
+ /* compare outsize_b with 512*/
+ cpi OUTSIZE_B1, 3
+ brge 5f
+ cpi OUTSIZE_B1, 2
+ brlo 3f
+ tst OUTSIZE_B0
+ breq 3f
+5: /* copy outbuffer to dest */
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 63
+ adiw r26, 17+8
+ ldi r24, 64
+6: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 6b
+ /* store new dest */
+ movw DEST0, r30
+ /* adjust counter and outsize_b*/
+ subi OUTSIZE_B1, 2
+ movw r30, UCTX0
+ adiw r30, 63
+ adiw r30, 17
+ ldi r24, 1
+ ld r25, Z
+ add r25, r24
+ st Z+, r25
+ ldi r24, 7
+6: ld r25, Z
+ adc r25, r1
+ st Z+, r25
+ dec r24
+ brne 6b
+ rjmp 1b
+3: /* last iteraton */
+ movw r24, OUTSIZE_B0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ lsr r24
+ movw r30, DEST0
+ movw r26, UCTX0
+ adiw r26, 63
+ adiw r26, 17+8
+ tst r24
+ breq 8f
+7: ld r25, X+
+ st Z+, r25
+ dec r24
+ brne 7b
+8:
+ stack_free_large2 80+8+64
+ pop_range 10, 17
+ ret
+
+/******************************************************************************/
+/*
+void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
+ skein512_ctx_t ctx;
+ skein512_init(&ctx, outlength_b);
+ while(length_b>SKEIN512_BLOCKSIZE){
+ skein512_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
+ length_b -= SKEIN512_BLOCKSIZE;
+ }
+ skein512_lastBlock(&ctx, msg, length_b);
+ skein512_ctx2hash(dest, &ctx);
+}
+*/
+/*
+ * param dest: r24:r25
+ * param outlength_b: r22:r23
+ * param msg: r20:r21
+ * param length_b: r16:r19
+ */
+LENGTH_B0 = 2
+LENGTH_B1 = 3
+LENGTH_B2 = 4
+LENGTH_B3 = 5
+DEST0 = 6
+DEST1 = 7
+MSG0 = 8
+MSG1 = 9
+CTX0 = 10
+CTX1 = 11
+.global skein512
+skein512:
+ push_range 2, 11
+ stack_alloc_large 82
+ adiw r30, 1
+ movw CTX0, r30
+ movw DEST0, r24
+ movw MSG0, r20
+ movw LENGTH_B0, r16
+ movw LENGTH_B2, r18
+ /* call skein512_init */
+ movw r24, r30
+ rcall skein512_init
+1: tst LENGTH_B2
+ brne 4f
+ tst LENGTH_B3
+ brne 4f
+ /* call skein512_lastBlock */
+ movw r24, CTX0
+ movw r22, MSG0
+ movw r20, LENGTH_B0
+ rcall skein512_lastBlock
+ /* call skein512_ctx2hash */
+ movw r24, DEST0
+ movw r22, CTX0
+ rcall skein512_ctx2hash
+ /* return */
+ stack_free_large 82
+ pop_range 2, 11
+ ret
+
+4: /* process preceeding blocks */
+ movw r24, CTX0
+ movw r22, MSG0
+ rcall skein512_nextBlock
+ ldi r24, 64
+ add MSG0, r24
+ adc MSG0, r1
+ mov r24, LENGTH_B1
+ mov r25, LENGTH_B2
+ sbiw r24, 2
+ sbc LENGTH_B3, r1
+ mov LENGTH_B1, r24
+ mov LENGTH_B2, r25
+ rjmp 1b
+
--- /dev/null
+ a: Skein-256-128
+ b: Skein-256-160
+ c: Skein-256-224
+ *d: Skein-256-256
+ e: Skein-256-384
+ f: Skein-256-512
+ g: Skein-512-128
+ h: Skein-512-160
+ i: Skein-512-224
+ j: Skein-512-256
+ k: Skein-512-384
+ l: Skein-512-512
+ m: Skein-512-1024
+ n: Skein-1024-128
+ o: Skein-1024-160
+ p: Skein-1024-224
+ q: Skein-1024-256
+ r: Skein-1024-384
+ s: Skein-1024-512
+ t: Skein-1024-1024
--- /dev/null
+/* threefish.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \file threefish.h
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ * \brief Implementation of the Threefish block cipher
+ * \ingroup Threefish
+ */
+
+#ifndef THREEFISH_H_
+#define THREEFISH_H_
+
+#include <stdint.h>
+
+#define THREEFISH256_BLOCKSIZE 256
+#define THREEFISH256_BLOCKSIZE_B ((THREEFISH256_BLOCKSIZE+7)/8)
+#define THREEFISH512_BLOCKSIZE 512
+#define THREEFISH512_BLOCKSIZE_B ((THREEFISH512_BLOCKSIZE+7)/8)
+#define THREEFISH1024_BLOCKSIZE 1024
+#define THREEFISH1024_BLOCKSIZE_B ((THREEFISH1024_BLOCKSIZE+7)/8)
+
+/** \typedef threefish256_ctx_t
+ * \brief holds key data for Threefish-256
+ *
+ * A variable of this type may hold the key data for Threefish-256 encryption
+ * or decryption..
+ */
+typedef struct{
+ uint64_t k[5];
+ uint64_t t[3];
+} threefish256_ctx_t;
+
+/** \typedef threefish512_ctx_t
+ * \brief holds key data for Threefish-512
+ *
+ * A variable of this type may hold the key data for Threefish-512 encryption
+ * or decryption..
+ */
+typedef struct{
+ uint64_t k[9];
+ uint64_t t[3];
+} threefish512_ctx_t;
+
+/** \typedef threefish1024_ctx_t
+ * \brief holds key data for Threefish-1024
+ *
+ * A variable of this type may hold the key data for Threefish-1024 encryption
+ * or decryption..
+ */
+typedef struct{
+ uint64_t k[17];
+ uint64_t t[3];
+} threefish1024_ctx_t;
+
+
+void threefish_mix(void* data, uint8_t rot);
+void threefish_invmix(void* data, uint8_t rot);
+
+void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx);
+void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx);
+void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx);
+
+void threefish256_enc(void* data, const threefish256_ctx_t* ctx);
+void threefish512_enc(void* data, const threefish512_ctx_t* ctx);
+void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx);
+
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx);
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx);
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx);
+
+#endif /* THREEFISH_H_ */
--- /dev/null
+/* threefish1024_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+static
+void permute_inv16(void* data){
+ uint64_t t;
+ t = X(15);
+ X(15) = X(7);
+ X(7) = X(9);
+ X(9) = X(1);
+ X(1) = t;
+ t = X(11);
+ X(11) = X(5);
+ X(5) = X(13);
+ X(13) = X(3);
+ X(3) = t;
+ t = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(14);
+ X(14) = X(12);
+ X(12) = X(10);
+ X(10) = X(8);
+ X(8) = t;
+}
+
+static
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<13; ++i){
+ X(i) -= ctx->k[(s+i)%17];
+ }
+ X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
+ X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+ X(15) -= ctx->k[(s+15)%17] + s;
+}
+
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
+ uint8_t i=0,s=20;
+ uint8_t r0[8] = {47, 58, 17, 28, 34, 33, 25, 55};
+ uint8_t r1[8] = {49, 7, 6, 7, 43, 8, 25, 43};
+ uint8_t r2[8] = {27, 32, 18, 47, 25, 18, 46, 37};
+ uint8_t r3[8] = {58, 45, 25, 48, 60, 57, 13, 40};
+ uint8_t r4[8] = {37, 19, 43, 51, 44, 21, 14, 16};
+ uint8_t r5[8] = {48, 18, 42, 9, 9, 12, 13, 22};
+ uint8_t r6[8] = {53, 2, 40, 35, 59, 32, 52, 38};
+ uint8_t r7[8] = {56, 56, 15, 41, 34, 54, 57, 12};
+ do{
+ if(i%4==0){
+ add_key_16(data, ctx, s);
+ --s;
+ }
+ permute_inv16(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ threefish_invmix((uint8_t*)data + 64, r4[i%8]);
+ threefish_invmix((uint8_t*)data + 80, r5[i%8]);
+ threefish_invmix((uint8_t*)data + 96, r6[i%8]);
+ threefish_invmix((uint8_t*)data +112, r7[i%8]);
+ ++i;
+ }while(i!=80);
+ add_key_16(data, ctx, s);
+}
--- /dev/null
+/* threefish1024_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-24
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void permute_inv16(void* data){
+ uint64_t t;
+ t = X(15);
+ X(15) = X(7);
+ X(7) = X(9);
+ X(9) = X(1);
+ X(1) = t;
+ t = X(11);
+ X(11) = X(5);
+ X(5) = X(13);
+ X(13) = X(3);
+ X(3) = t;
+ t = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(14);
+ X(14) = X(12);
+ X(12) = X(10);
+ X(10) = X(8);
+ X(8) = t;
+}
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<13; ++i){
+ X(i) -= ctx->k[(s+i)%17];
+ }
+ X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
+ X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+ X(15) -= ctx->k[(s+15)%17] + s;
+}
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
+ uint8_t i=0,s=20;
+ uint8_t r0[8] = {0x69, 0x72, 0x21, 0x34, 0x42, 0x41, 0x31, 0x79};
+ uint8_t r1[8] = {0x61, 0x19, 0x1a, 0x19, 0x53, 0x10, 0x31, 0x53};
+ uint8_t r2[8] = {0x33, 0x40, 0x22, 0x69, 0x31, 0x22, 0x6a, 0x5b};
+ uint8_t r3[8] = {0x72, 0x6b, 0x31, 0x60, 0x74, 0x71, 0x2b, 0x50};
+ uint8_t r4[8] = {0x5b, 0x23, 0x53, 0x63, 0x54, 0x3b, 0x2a, 0x20};
+ uint8_t r5[8] = {0x60, 0x22, 0x52, 0x11, 0x11, 0x14, 0x2b, 0x3a};
+ uint8_t r6[8] = {0x7b, 0x02, 0x50, 0x43, 0x73, 0x40, 0x64, 0x5a};
+ uint8_t r7[8] = {0x70, 0x70, 0x29, 0x51, 0x42, 0x7a, 0x71, 0x14};
+
+ do{
+ if(i%4==0){
+ add_key_16(data, ctx, s);
+ --s;
+ }
+ permute_inv16(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ threefish_invmix((uint8_t*)data + 64, r4[i%8]);
+ threefish_invmix((uint8_t*)data + 80, r5[i%8]);
+ threefish_invmix((uint8_t*)data + 96, r6[i%8]);
+ threefish_invmix((uint8_t*)data +112, r7[i%8]);
+ ++i;
+ }while(i!=80);
+ add_key_16(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+IDX4 = 12
+IDX5 = 13
+IDX6 = 14
+IDX7 = 15
+
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish1024_dec
+threefish1024_dec:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ ldi r26, 20
+ mov S, r26
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish1024_slut17)
+ ldi r31, hi8(threefish1024_slut17)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall sub_z_from_x8
+ /* second half */
+ ldi r30, lo8(threefish1024_slut17)
+ ldi r31, hi8(threefish1024_slut17)
+ add r30, S
+ adc r31, r1
+ adiw r30, 8
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall sub_z_from_x8
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish1024_slut3)
+ ldi r31, hi8(threefish1024_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 7*8 /* make Z pointing to (extended tweak) */
+ adiw r30, 7*8
+ adiw r30, 3*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ ld r0, X
+ sub r0, S
+ 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
+ ld r0, X
+ sbc r0, r1
+ st X+, r0
+ tst S
+ brne 3f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+3:
+ dec S
+4:
+ /* now the permutation */
+ movw r26, DATA0 /* X1 <-> X15 */
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8+4
+ adiw r30, 7*8+4
+ rcall xchg_zx8
+ movw r26, DATA0 /* X15 <-> X7 */
+ adiw r26, 7*8+4
+ adiw r26, 7*8+4
+ movw r30, DATA0
+ adiw r30, 7*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X9 <-> X7 */
+ adiw r26, 7*8
+ adiw r26, 2*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X3 <-> X11 */
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 4*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X11 <-> X5 */
+ adiw r26, 7*8
+ adiw r26, 4*8
+ movw r30, DATA0
+ adiw r30, 5*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X13 <-> X5 */
+ adiw r26, 7*8
+ adiw r26, 6*8
+ movw r30, DATA0
+ adiw r30, 5*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X8 <-> X14 */
+ adiw r26, 7*8
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 7*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X14 <-> X12 */
+ adiw r26, 7*8
+ adiw r26, 7*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 5*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X10 <-> X12 */
+ adiw r26, 7*8
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 5*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X4 <-> X6 */
+ adiw r26, 4*8
+ movw r30, DATA0
+ adiw r30, 6*8
+ rcall xchg_zx8
+
+ /* call mix */
+ ldi r30, lo8(threefish1024_rc0)
+ ldi r31, hi8(threefish1024_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ adiw r30, 8
+ lpm IDX1, Z
+ adiw r30, 8
+ lpm IDX2, Z
+ adiw r30, 8
+ lpm IDX3, Z
+ adiw r30, 8
+ lpm IDX4, Z
+ adiw r30, 8
+ lpm IDX5, Z
+ adiw r30, 8
+ lpm IDX6, Z
+ push IDX6
+ push IDX5
+ push IDX4
+ push IDX3
+ push IDX2
+
+ movw r24, DATA0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 32
+ mov r22, IDX1
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 48
+ pop r22
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 1
+ pop r22
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 17
+ pop r22
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 33
+ pop r22
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 49
+ pop r22
+ call threefish_invmix_asm /* no rcall? */
+ inc I
+9:
+ rjmp 1b
+
+threefish1024_slut17:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
+ .byte 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78
+ .byte 0x80, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
+ .byte 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70
+ .byte 0x78, 0x80, 0x00, 0x08, 0x10
+threefish1024_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10
+ .byte 0x00
+
+threefish1024_rc0: .byte 0x69, 0x72, 0x21, 0x34, 0x42, 0x41, 0x31, 0x79
+threefish1024_rc1: .byte 0x61, 0x19, 0x1a, 0x19, 0x53, 0x10, 0x31, 0x53
+threefish1024_rc2: .byte 0x33, 0x40, 0x22, 0x69, 0x31, 0x22, 0x6a, 0x5b
+threefish1024_rc3: .byte 0x72, 0x6b, 0x31, 0x60, 0x74, 0x71, 0x2b, 0x50
+threefish1024_rc4: .byte 0x5b, 0x23, 0x53, 0x63, 0x54, 0x3b, 0x2a, 0x20
+threefish1024_rc5: .byte 0x60, 0x22, 0x52, 0x11, 0x11, 0x14, 0x2b, 0x3a
+threefish1024_rc6: .byte 0x7b, 0x02, 0x50, 0x43, 0x73, 0x40, 0x64, 0x5a
+threefish1024_rc7: .byte 0x70, 0x70, 0x29, 0x51, 0x42, 0x7a, 0x71, 0x14
+
+sub_z_from_x8:
+ ld r0, Z+
+ ld r1, X
+ sub r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+T0 = IDX0
+T1 = 0
+CNT = 24
+xchg_zx8:
+ ldi CNT, 8
+1: ld T0, X
+ ld T1, Z
+ st X+, T1
+ st Z+, T0
+ dec CNT
+ brne 1b
+ ret
+
+
+
--- /dev/null
+/* threefish1024_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+static
+void permute_inv16(void* data){
+ uint64_t t;
+ t = X(15);
+ X(15) = X(7);
+ X(7) = X(9);
+ X(9) = X(1);
+ X(1) = t;
+ t = X(11);
+ X(11) = X(5);
+ X(5) = X(13);
+ X(13) = X(3);
+ X(3) = t;
+ t = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(14);
+ X(14) = X(12);
+ X(12) = X(10);
+ X(10) = X(8);
+ X(8) = t;
+}
+
+static
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<13; ++i){
+ X(i) -= ctx->k[(s+i)%17];
+ }
+ X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
+ X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+ X(15) -= ctx->k[(s+15)%17] + s;
+}
+
+void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
+ uint8_t i=0,s=20;
+ uint8_t r0[8] = {0x69, 0x72, 0x21, 0x34, 0x42, 0x41, 0x31, 0x79};
+ uint8_t r1[8] = {0x61, 0x19, 0x1a, 0x19, 0x53, 0x10, 0x31, 0x53};
+ uint8_t r2[8] = {0x33, 0x40, 0x22, 0x69, 0x31, 0x22, 0x6a, 0x5b};
+ uint8_t r3[8] = {0x72, 0x6b, 0x31, 0x60, 0x74, 0x71, 0x2b, 0x50};
+ uint8_t r4[8] = {0x5b, 0x23, 0x53, 0x63, 0x54, 0x3b, 0x2a, 0x20};
+ uint8_t r5[8] = {0x60, 0x22, 0x52, 0x11, 0x11, 0x14, 0x2b, 0x3a};
+ uint8_t r6[8] = {0x7b, 0x02, 0x50, 0x43, 0x73, 0x40, 0x64, 0x5a};
+ uint8_t r7[8] = {0x70, 0x70, 0x29, 0x51, 0x42, 0x7a, 0x71, 0x14};
+
+ do{
+ if(i%4==0){
+ add_key_16(data, ctx, s);
+ --s;
+ }
+ permute_inv16(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ threefish_invmix((uint8_t*)data + 64, r4[i%8]);
+ threefish_invmix((uint8_t*)data + 80, r5[i%8]);
+ threefish_invmix((uint8_t*)data + 96, r6[i%8]);
+ threefish_invmix((uint8_t*)data +112, r7[i%8]);
+ ++i;
+ }while(i!=80);
+ add_key_16(data, ctx, s);
+}
--- /dev/null
+/* threefish1024_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+static
+void permute_16(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(9);
+ X(9) = X(7);
+ X(7) = X(15);
+ X(15) = t;
+ t = X(3);
+ X(3) = X(13);
+ X(13) = X(5);
+ X(5) = X(11);
+ X(11) = t;
+ t = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(8);
+ X(8) = X(10);
+ X(10) = X(12);
+ X(12) = X(14);
+ X(14) = t;
+}
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx){
+ memcpy(ctx->k, key, 16*8);
+ if(tweak){
+ memcpy(ctx->t, tweak, 2*8);
+ ctx->t[2] = T(0) ^ T(1);
+ }else{
+ memset(ctx, 0, 3*8);
+ }
+ uint8_t i;
+ ctx->k[16] = THREEFISH_KEY_CONST;
+ for(i=0; i<16; ++i){
+ ctx->k[16] ^= K(i);
+ }
+}
+
+static
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<13; ++i){
+ X(i) += ctx->k[(s+i)%17];
+ }
+ X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
+ X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+ X(15) += ctx->k[(s+15)%17] + s;
+}
+
+void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
+ uint8_t r1[8] = {43, 25, 8, 43, 7, 6, 7, 49};
+ uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
+ uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
+ uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
+ uint8_t r5[8] = {22, 13, 12, 9, 9, 42, 18, 48};
+ uint8_t r6[8] = {38, 52, 32, 59, 35, 40, 2, 53};
+ uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
+
+ do{
+ if(i%4==0){
+ add_key_16(data, ctx, s);
+ ++s;
+ }
+ threefish_mix((uint8_t*)data + 0, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ threefish_mix((uint8_t*)data + 32, r2[i%8]);
+ threefish_mix((uint8_t*)data + 48, r3[i%8]);
+ threefish_mix((uint8_t*)data + 64, r4[i%8]);
+ threefish_mix((uint8_t*)data + 80, r5[i%8]);
+ threefish_mix((uint8_t*)data + 96, r6[i%8]);
+ threefish_mix((uint8_t*)data +112, r7[i%8]);
+ permute_16(data);
+ ++i;
+ }while(i!=80);
+ add_key_16(data, ctx, s);
+}
--- /dev/null
+/* threefish1024_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-24
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+A0 = 14
+A1 = 15
+A2 = 16
+A3 = 17
+A4 = 18
+A5 = 19
+A6 = 20
+A7 = 21
+/*
+#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+void threefish1024_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
+ memcpy(ctx->k, key, 16*8);
+ memcpy(ctx->t, tweak, 2*8);
+ uint8_t i;
+ ctx->k[16] = THREEFISH_KEY_CONST;
+ for(i=0; i<8; ++i){
+ ctx->k[16] ^= K(i);
+ }
+ ctx->t[2] = T(0) ^ T(1);
+}
+*/
+/*
+ * param key: r24:r25
+ * param tweak: r22:r23
+ * param ctx: r20:r21
+ */
+.global threefish1024_init
+threefish1024_init:
+ push_range 14, 17
+ movw r30, r20
+ movw r26, r24
+ ldi r24, 16
+ ldi A7, 0x55
+ mov A6, A7
+ movw A4, A6
+ movw A2, A6
+ movw A0, A6
+1:
+ ld r0, X+
+ st Z+, r0
+ eor A0, r0
+ ld r0, X+
+ st Z+, r0
+ eor A1, r0
+ ld r0, X+
+ st Z+, r0
+ eor A2, r0
+ ld r0, X+
+ st Z+, r0
+ eor A3, r0
+ ld r0, X+
+ st Z+, r0
+ eor A4, r0
+ ld r0, X+
+ st Z+, r0
+ eor A5, r0
+ ld r0, X+
+ st Z+, r0
+ eor A6, r0
+ ld r0, X+
+ st Z+, r0
+ eor A7, r0
+ dec r24
+ brne 1b
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ /* now the tweak */
+ movw r26, r22
+ tst r27
+ brne 3f
+ tst r26
+ brne 3f
+ ldi r26, 3*8
+1:
+ st Z+, r1
+ dec r26
+ brne 1b
+ rjmp 9f
+3:
+ ld A0, X+
+ ld A1, X+
+ ld A2, X+
+ ld A3, X+
+ ld A4, X+
+ ld A5, X+
+ ld A6, X+
+ ld A7, X+
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ ld r0, X+
+ eor A0, r0
+ st Z+, r0
+ ld r0, X+
+ eor A1, r0
+ st Z+, r0
+ ld r0, X+
+ eor A2, r0
+ st Z+, r0
+ ld r0, X+
+ eor A3, r0
+ st Z+, r0
+ ld r0, X+
+ eor A4, r0
+ st Z+, r0
+ ld r0, X+
+ eor A5, r0
+ st Z+, r0
+ ld r0, X+
+ eor A6, r0
+ st Z+, r0
+ ld r0, X+
+ eor A7, r0
+ st Z+, r0
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+9:
+ pop_range 14, 17
+ ret
+
+/******************************************************************************/
+/*
+#define X(a) (((uint64_t*)data)[(a)])
+void permute_16(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(9);
+ X(9) = X(7);
+ X(7) = X(15);
+ X(15) = t;
+ t = X(3);
+ X(3) = X(13);
+ X(13) = X(5);
+ X(5) = X(11);
+ X(11) = t;
+ t = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(8);
+ X(8) = X(10);
+ X(10) = X(12);
+ X(12) = X(14);
+ X(14) = t;
+}
+void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<13; ++i){
+ X(i) += ctx->k[(s+i)%17];
+ }
+ X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
+ X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
+ X(15) += ctx->k[(s+15)%17] + s;
+}
+void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
+ uint8_t r1[8] = {43, 25, 8, 43, 7, 6, 7, 49};
+ uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
+ uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
+ uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
+ uint8_t r5[8] = {22, 13, 12, 9, 9, 42, 18, 48};
+ uint8_t r6[8] = {38, 52, 32, 59, 35, 40, 2, 53};
+ uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
+ do{
+ if(i%4==0){
+ add_key_16(data, ctx, s);
+ ++s;
+ }
+ threefish_mix((uint8_t*)data + 0, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ threefish_mix((uint8_t*)data + 32, r2[i%8]);
+ threefish_mix((uint8_t*)data + 48, r3[i%8]);
+ threefish_mix((uint8_t*)data + 64, r4[i%8]);
+ threefish_mix((uint8_t*)data + 80, r5[i%8]);
+ threefish_mix((uint8_t*)data + 96, r6[i%8]);
+ threefish_mix((uint8_t*)data +112, r7[i%8]);
+ permute_16(data);
+ ++i;
+ }while(i!=80);
+ add_key_16(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+IDX4 = 12
+IDX5 = 13
+IDX6 = 14
+IDX7 = 15
+
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish1024_enc
+threefish1024_enc:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ clr S
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish1024_slut17)
+ ldi r31, hi8(threefish1024_slut17)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall add_z_to_x8
+ /* second half */
+ ldi r30, lo8(threefish1024_slut17)
+ ldi r31, hi8(threefish1024_slut17)
+ add r30, S
+ adc r31, r1
+ adiw r30, 8
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall add_z_to_x8
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish1024_slut3)
+ ldi r31, hi8(threefish1024_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 7*8 /* make Z pointing to (extended tweak) */
+ adiw r30, 7*8
+ adiw r30, 3*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ ld r0, X
+ add r0, S
+ 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
+ inc S
+ mov r26, S
+ cpi r26, 21
+ brmi 4f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+4:
+ /* call mix */
+ ldi r30, lo8(threefish1024_rc0)
+ ldi r31, hi8(threefish1024_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ adiw r30, 8
+ lpm IDX1, Z
+ adiw r30, 8
+ lpm IDX2, Z
+ adiw r30, 8
+ lpm IDX3, Z
+ adiw r30, 8
+ lpm IDX4, Z
+ adiw r30, 8
+ lpm IDX5, Z
+ adiw r30, 8
+ lpm IDX6, Z
+ push IDX6
+ push IDX5
+ push IDX4
+ push IDX3
+ push IDX2
+
+ movw r24, DATA0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 32
+ mov r22, IDX1
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 48
+ pop r22
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 1
+ pop r22
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 17
+ pop r22
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 33
+ pop r22
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 63
+ adiw r24, 49
+ pop r22
+ call threefish_mix_asm /* no rcall? */
+ /* now the permutation */
+ movw r26, DATA0 /* X1 <-> X15 */
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8+4
+ adiw r30, 7*8+4
+ rcall xchg_zx8
+ movw r26, DATA0 /* X1 <-> X9 */
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 2*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X9 <-> X7 */
+ adiw r26, 7*8
+ adiw r26, 2*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X3 <-> X11 */
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 4*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X3 <-> X13 */
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 6*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X13 <-> X5 */
+ adiw r26, 7*8
+ adiw r26, 6*8
+ movw r30, DATA0
+ adiw r30, 5*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X8 <-> X14 */
+ adiw r26, 7*8
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 7*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X8 <-> X10 */
+ adiw r26, 7*8
+ adiw r26, 1*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 3*8
+ rcall xchg_zx8
+ movw r26, DATA0 /* X10 <-> X12 */
+ adiw r26, 7*8
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ adiw r30, 5*8
+ rcall xchg_zx8
+ /* --- */
+ movw r26, DATA0 /* X4 <-> X6 */
+ adiw r26, 4*8
+ movw r30, DATA0
+ adiw r30, 6*8
+ rcall xchg_zx8
+
+ inc I
+; mov r26, I
+; cpi r26, 5
+; brne 9f
+; rjmp exit
+9:
+ rjmp 1b
+
+threefish1024_slut17:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
+ .byte 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78
+ .byte 0x80, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
+ .byte 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70
+ .byte 0x78, 0x80, 0x00, 0x08, 0x10
+threefish1024_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10
+ .byte 0x00
+threefish1024_rc0: .byte 0x79, 0x31, 0x41, 0x42, 0x34, 0x21, 0x72, 0x69
+threefish1024_rc1: .byte 0x53, 0x31, 0x10, 0x53, 0x19, 0x1a, 0x19, 0x61
+threefish1024_rc2: .byte 0x5b, 0x6a, 0x22, 0x31, 0x69, 0x22, 0x40, 0x33
+threefish1024_rc3: .byte 0x50, 0x2b, 0x71, 0x74, 0x60, 0x31, 0x6b, 0x72
+threefish1024_rc4: .byte 0x20, 0x2a, 0x3b, 0x54, 0x63, 0x53, 0x23, 0x5b
+threefish1024_rc5: .byte 0x3a, 0x2b, 0x14, 0x11, 0x11, 0x52, 0x22, 0x60
+threefish1024_rc6: .byte 0x5a, 0x64, 0x40, 0x73, 0x43, 0x50, 0x02, 0x7b
+threefish1024_rc7: .byte 0x14, 0x71, 0x7a, 0x42, 0x51, 0x29, 0x70, 0x70
+
+add_z_to_x8:
+ ld r0, Z+
+ ld r1, X
+ add r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+T0 = IDX0
+T1 = 0
+CNT = 24
+xchg_zx8:
+ ldi CNT, 8
+1: ld T0, X
+ ld T1, Z
+ st X+, T1
+ st Z+, T0
+ dec CNT
+ brne 1b
+ ret
+
+
+
--- /dev/null
+/* threefish256_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+static
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+static
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+ X(0) -= ctx->k[(s+0)%5];
+ X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) -= ctx->k[(s+3)%5] + s;
+}
+
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {59, 11, 53, 26, 58, 13, 36, 5};
+ uint8_t r1[8] = {50, 42, 35, 20, 44, 46, 28, 56};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ --s;
+ }
+ permute_4(data);
+ threefish_invmix(data, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+
--- /dev/null
+/* threefish256_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+ X(0) -= ctx->k[(s+0)%5];
+ X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) -= ctx->k[(s+3)%5] + s;
+}
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {0x73, 0x13, 0x7b, 0x32, 0x72, 0x2b, 0x44, 0x1b};
+ uint8_t r1[8] = {0x62, 0x52, 0x43, 0x24, 0x54, 0x6a, 0x34, 0x70};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ --s;
+ }
+ permute_4(data);
+ threefish_invmix(data, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish256_dec
+threefish256_dec:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ ldi r26, 18
+ mov S, r26
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish256_slut5)
+ ldi r31, hi8(threefish256_slut5)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall sub_z_from_x8
+
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish256_slut3)
+ ldi r31, hi8(threefish256_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 5*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ ld r0, X
+ sub r0, S
+ 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
+ ld r0, X
+ sbc r0, r1
+ st X+, r0
+ tst S
+ brne 3f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+3:
+ dec S
+4:
+ /* now the permutation */
+ movw r26, DATA0
+ adiw r26, 8
+ movw r30, r26
+ adiw r30, 16
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ /* call mix */
+ ldi r30, lo8(threefish256_rc0)
+ ldi r31, hi8(threefish256_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ movw r24, DATA0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_invmix_asm /* no rcall? */
+ inc I
+ rjmp 1b
+
+threefish256_slut5:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+ .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
+ .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+threefish256_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+
+threefish256_rc0: .byte 0x73, 0x13, 0x7b, 0x32, 0x72, 0x2b, 0x44, 0x1b
+threefish256_rc1: .byte 0x62, 0x52, 0x43, 0x24, 0x54, 0x6a, 0x34, 0x70
+
+sub_z_from_x8:
+ ld r0, Z+
+ ld r1, X
+ sub r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* threefish256_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+static
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+
+static
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+ X(0) -= ctx->k[(s+0)%5];
+ X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) -= ctx->k[(s+3)%5] + s;
+}
+
+void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {0x73, 0x13, 0x7b, 0x32, 0x72, 0x2b, 0x44, 0x1b};
+ uint8_t r1[8] = {0x62, 0x52, 0x43, 0x24, 0x54, 0x6a, 0x34, 0x70};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ --s;
+ }
+ permute_4(data);
+ threefish_invmix(data, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+
--- /dev/null
+/* threefish256_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+#define X(a) (((uint64_t*)data)[(a)])
+static
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx){
+ memcpy(ctx->k, key, 4*8);
+ if(tweak){
+ memcpy(ctx->t, tweak, 2*8);
+ ctx->t[2] = T(0) ^ T(1);
+ }else{
+ memset(ctx->t, 0, 3*8);
+ }
+ uint8_t i;
+ ctx->k[4] = THREEFISH_KEY_CONST;
+ for(i=0; i<4; ++i){
+ ctx->k[4] ^= K(i);
+ }
+}
+
+static
+void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
+ X(0) += ctx->k[(s+0)%5];
+ X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) += ctx->k[(s+3)%5] + s;
+}
+
+void threefish256_enc(void* data, const threefish256_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
+ uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ ++s;
+ }
+ threefish_mix(data, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ permute_4(data);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+
--- /dev/null
+/* threefish256_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+A0 = 14
+A1 = 15
+A2 = 16
+A3 = 17
+A4 = 18
+A5 = 19
+A6 = 20
+A7 = 21
+/*
+#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish256_init(void* key, void* tweak, threefish256_ctx_t* ctx){
+ memcpy(ctx->k, key, 4*8);
+ memcpy(ctx->t, tweak, 2*8);
+ uint8_t i;
+ ctx->k[4] = THREEFISH_KEY_CONST;
+ for(i=0; i<4; ++i){
+ ctx->k[4] ^= K(i);
+ }
+ ctx->t[2] = T(0) ^ T(1);
+}
+*/
+/*
+ * param key: r24:r25
+ * param tweak: r22:r23
+ * param ctx: r20:r21
+ */
+.global threefish256_init
+threefish256_init:
+ push_range 14, 17
+ movw r30, r20
+ movw r26, r24
+ ldi r24, 4
+ ldi A7, 0x55
+ mov A6, A7
+ movw A4, A6
+ movw A2, A6
+ movw A0, A6
+1:
+ ld r0, X+
+ st Z+, r0
+ eor A0, r0
+ ld r0, X+
+ st Z+, r0
+ eor A1, r0
+ ld r0, X+
+ st Z+, r0
+ eor A2, r0
+ ld r0, X+
+ st Z+, r0
+ eor A3, r0
+ ld r0, X+
+ st Z+, r0
+ eor A4, r0
+ ld r0, X+
+ st Z+, r0
+ eor A5, r0
+ ld r0, X+
+ st Z+, r0
+ eor A6, r0
+ ld r0, X+
+ st Z+, r0
+ eor A7, r0
+ dec r24
+ brne 1b
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ /* now the tweak */
+ tst r23
+ brne 3f
+ tst r22
+ brne 3f
+ ldi r26, 3*8
+2:
+ st Z+, r1
+ dec r26
+ brne 2b
+ rjmp 9f
+3:
+ movw r26, r22
+ ld A0, X+
+ ld A1, X+
+ ld A2, X+
+ ld A3, X+
+ ld A4, X+
+ ld A5, X+
+ ld A6, X+
+ ld A7, X+
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ ld r0, X+
+ eor A0, r0
+ st Z+, r0
+ ld r0, X+
+ eor A1, r0
+ st Z+, r0
+ ld r0, X+
+ eor A2, r0
+ st Z+, r0
+ ld r0, X+
+ eor A3, r0
+ st Z+, r0
+ ld r0, X+
+ eor A4, r0
+ st Z+, r0
+ ld r0, X+
+ eor A5, r0
+ st Z+, r0
+ ld r0, X+
+ eor A6, r0
+ st Z+, r0
+ ld r0, X+
+ eor A7, r0
+ st Z+, r0
+
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+9:
+ pop_range 14, 17
+ ret
+
+/******************************************************************************/
+/*
+#define X(a) (((uint64_t*)data)[(a)])
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+void add_key_4(void* data, threefish256_ctx_t* ctx, uint8_t s){ / * s: 0..19 * /
+ X(0) += ctx->k[(s+0)%5];
+ X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) += ctx->k[(s+3)%5] + s;
+}
+void threefish256_enc(void* data, threefish256_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
+ uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ ++s;
+ }
+ threefish_mix(data, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ permute_4(data);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish256_enc
+threefish256_enc:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ clr S
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish256_slut5)
+ ldi r31, hi8(threefish256_slut5)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall add_z_to_x8
+
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish256_slut3)
+ ldi r31, hi8(threefish256_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 5*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ ld r0, X
+ add r0, S
+ 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
+ inc S
+ mov r26, S
+ cpi r26, 19
+ brmi 4f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+4:
+ /* call mix */
+ ldi r30, lo8(threefish256_rc0)
+ ldi r31, hi8(threefish256_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ movw r24, DATA0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_mix_asm /* no rcall? */
+ /* now the permutation */
+ movw r26, DATA0
+ adiw r26, 8
+ movw r30, r26
+ adiw r30, 16
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ inc I
+ rjmp 1b
+
+threefish256_slut5:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+ .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
+ .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+threefish256_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+;threefish256_rc0: .byte 5, 36, 13, 58, 26, 53, 11, 59
+;threefish256_rc1: .byte 56, 28, 46, 44, 20, 35, 42, 50
+threefish256_rc0: .byte 0x1b, 0x44, 0x2b, 0x72, 0x32, 0x7b, 0x13, 0x73
+threefish256_rc1: .byte 0x70, 0x34, 0x6a, 0x54, 0x24, 0x43, 0x52, 0x62
+
+add_z_to_x8:
+ ld r0, Z+
+ ld r1, X
+ add r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* threefish_mix.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+A0 = 14
+A1 = 15
+A2 = 16
+A3 = 17
+A4 = 18
+A5 = 19
+A6 = 20
+A7 = 21
+/*
+#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish256_init(void* key, void* tweak, threefish256_ctx_t* ctx){
+ memcpy(ctx->k, key, 4*8);
+ memcpy(ctx->t, tweak, 2*8);
+ uint8_t i;
+ ctx->k[4] = THREEFISH_KEY_CONST;
+ for(i=0; i<4; ++i){
+ ctx->k[4] ^= K(i);
+ }
+ ctx->t[2] = T(0) ^ T(1);
+}
+*/
+/*
+ * param key: r24:r25
+ * param tweak: r22:r23
+ * param ctx: r20:r21
+ */
+.global threefish256_init
+threefish256_init:
+ push_range 14, 17
+ movw r30, r20
+ movw r26, r24
+ ldi r24, 4
+ ldi A7, 0x55
+ mov A6, A7
+ movw A4, A6
+ movw A2, A6
+ movw A0, A6
+1:
+ ld r0, X+
+ st Z+, r0
+ eor A0, r0
+ ld r0, X+
+ st Z+, r0
+ eor A1, r0
+ ld r0, X+
+ st Z+, r0
+ eor A2, r0
+ ld r0, X+
+ st Z+, r0
+ eor A3, r0
+ ld r0, X+
+ st Z+, r0
+ eor A4, r0
+ ld r0, X+
+ st Z+, r0
+ eor A5, r0
+ ld r0, X+
+ st Z+, r0
+ eor A6, r0
+ ld r0, X+
+ st Z+, r0
+ eor A7, r0
+ dec r24
+ brne 1b
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ /* now the tweak */
+ movw r26, r22
+ tst r27
+ brne 3f
+ tst r26
+ brne 3f
+ ldi r26, 3*8
+1:
+ st Z+, r1
+ dec r26
+ brne 1b
+ rjmp 9f
+3:
+ ld A0, X+
+ ld A1, X+
+ ld A2, X+
+ ld A3, X+
+ ld A4, X+
+ ld A5, X+
+ ld A6, X+
+ ld A7, X+
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ ld r0, X+
+ eor A0, r0
+ st Z+, r0
+ ld r0, X+
+ eor A1, r0
+ st Z+, r0
+ ld r0, X+
+ eor A2, r0
+ st Z+, r0
+ ld r0, X+
+ eor A3, r0
+ st Z+, r0
+ ld r0, X+
+ eor A4, r0
+ st Z+, r0
+ ld r0, X+
+ eor A5, r0
+ st Z+, r0
+ ld r0, X+
+ eor A6, r0
+ st Z+, r0
+ ld r0, X+
+ eor A7, r0
+ st Z+, r0
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+9:
+ pop_range 14, 17
+ ret
+
+/******************************************************************************/
+/*
+#define X(a) (((uint64_t*)data)[(a)])
+void permute_4(void* data){
+ uint64_t t;
+ t = X(1);
+ X(1) = X(3);
+ X(3) = t;
+}
+void add_key_4(void* data, threefish256_ctx_t* ctx, uint8_t s){ / * s: 0..19 * /
+ X(0) += ctx->k[(s+0)%5];
+ X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
+ X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
+ X(3) += ctx->k[(s+3)%5] + s;
+}
+void threefish256_enc(void* data, threefish256_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
+ uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
+ do{
+ if(i%4==0){
+ add_key_4(data, ctx, s);
+ ++s;
+ }
+ threefish_mix(data, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ permute_4(data);
+ ++i;
+ }while(i!=72);
+ add_key_4(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish256_enc
+threefish256_enc:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ clr S
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish256_slut5)
+ ldi r31, hi8(threefish256_slut5)
+ mov r26, S
+ add r30, r26
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall add_z_to_x8
+
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish256_slut3)
+ ldi r31, hi8(threefish256_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 5*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ ld r0, X
+ add r0, S
+ st X+, r0
+ ldi r16, 7
+3:
+ ld r0, X
+ adc r0, r1
+ st X+, r0
+ dec r16
+ brne 3b
+ inc S
+ mov r26, S
+ cpi r26, 19
+ brmi 4f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+4:
+ /* call mix */
+ ldi r30, lo8(threefish256_rc0)
+ ldi r31, hi8(threefish256_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ movw r24, DATA0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_mix_asm /* no rcall? */
+ /* now the permutation */
+ movw r26, DATA0
+ adiw r26, 8
+ movw r30, r26
+ adiw r30, 16
+ ldi r16, 8
+3: ld IDX0, X
+ ld IDX1, Z
+ st X+, IDX1
+ st Z+, IDX0
+ dec r16
+ brne 3b
+ inc I
+ rjmp 1b
+
+threefish256_slut5:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+ .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
+ .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
+threefish256_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+threefish256_rc0: .byte 0x1b, 0x44, 0x2b, 0x72, 0x32, 0x7b, 0x13, 0x73
+threefish256_rc1: .byte 0x70, 0x34, 0x6a, 0x54, 0x24, 0x43, 0x52, 0x62
+
+add_z_to_x8:
+ ld r0, Z+
+ ld r1, X
+ add r1, r0
+ st X+, r1
+ ldi r16, 7
+1:
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ dec r16
+ brne 1b
+ clr r1
+ ret
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* threefish512_dec.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-22
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_inv8(void* data){
+ uint64_t t;
+ t = X(6);
+ X(6) = X(4);
+ X(4) = X(2);
+ X(2) = X(0);
+ X(0) = t;
+ t = X(7);
+ X(7) = X(3);
+ X(3) = t;
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<5; ++i){
+ X(i) -= ctx->k[(s+i)%9];
+ }
+ X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
+ X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+ X(7) -= ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {33, 29, 39, 33, 26, 34, 48, 38};
+ uint8_t r1[8] = {51, 26, 27, 49, 12, 14, 20, 30};
+ uint8_t r2[8] = {39, 11, 41, 8, 58, 15, 43, 50};
+ uint8_t r3[8] = {35, 9, 14, 42, 7, 27, 31, 53};
+ do{
+ if(i%4==0){
+ add_key_8(data, ctx, s);
+ --s;
+ }
+ permute_inv8(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_8(data, ctx, s);
+}
+
--- /dev/null
+/* threefish512_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-24
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_inv8(void* data){
+ uint64_t t;
+ t = X(6);
+ X(6) = X(4);
+ X(4) = X(2);
+ X(2) = X(0);
+ X(0) = t;
+ t = X(7);
+ X(7) = X(3);
+ X(3) = t;
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<5; ++i){
+ X(i) -= ctx->k[(s+i)%9];
+ }
+ X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
+ X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+ X(7) -= ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {0x41, 0x4b, 0x59, 0x41, 0x32, 0x42, 0x60, 0x5a};
+ uint8_t r1[8] = {0x63, 0x32, 0x33, 0x61, 0x14, 0x2a, 0x24, 0x4a};
+ uint8_t r2[8] = {0x59, 0x13, 0x51, 0x10, 0x72, 0x29, 0x53, 0x62};
+ uint8_t r3[8] = {0x43, 0x11, 0x2a, 0x52, 0x19, 0x33, 0x49, 0x7b};
+ do{
+ if(i%4==0){
+ add_key_8(data, ctx, s);
+ --s;
+ }
+ permute_inv8(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_8(data, ctx, s);
+}
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+IDX4 = 12
+IDX5 = 13
+IDX6 = 14
+IDX7 = 15
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish512_dec
+threefish512_dec:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ ldi r26, 18
+ mov S, r26
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish512_slut9)
+ ldi r31, hi8(threefish512_slut9)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall sub_z_from_x8
+
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish512_slut3)
+ ldi r31, hi8(threefish512_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 7*8 /* make Z pointing to (extended tweak) */
+ adiw r30, 2*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall sub_z_from_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall sub_z_from_x8
+ ld r0, X
+ sub r0, S
+ 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
+ ld r0, X
+ sbc r0, r1
+ st X+, r0
+ tst S
+ brne 3f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+3:
+ dec S
+4:
+ /* now the permutation */
+ movw r26, DATA0
+ movw r30, DATA0
+ adiw r30, 6*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ adiw r26, 6*8
+ movw r30, DATA0
+ adiw r30, 4*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ adiw r26, 2*8
+ movw r30, DATA0
+ adiw r30, 4*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ rcall xchg_zx8
+ /* call mix */
+ ldi r30, lo8(threefish512_rc0)
+ ldi r31, hi8(threefish512_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ adiw r30, 8
+ lpm IDX1, Z
+ push IDX1
+ adiw r30, 8
+ lpm IDX1, Z
+
+ movw r24, DATA0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 32
+ pop r22
+ ;mov r22, IDX0
+ call threefish_invmix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 48
+ mov r22, IDX1
+ call threefish_invmix_asm /* no rcall? */
+ inc I
+ rjmp 1b
+
+threefish512_slut9:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
+ .byte 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
+ .byte 0x38, 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28
+ .byte 0x30, 0x38, 0x40
+threefish512_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+
+threefish512_rc0: .byte 0x41, 0x4b, 0x59, 0x41, 0x32, 0x42, 0x60, 0x5a
+threefish512_rc1: .byte 0x63, 0x32, 0x33, 0x61, 0x14, 0x2a, 0x24, 0x4a
+threefish512_rc2: .byte 0x59, 0x13, 0x51, 0x10, 0x72, 0x29, 0x53, 0x62
+threefish512_rc3: .byte 0x43, 0x11, 0x2a, 0x52, 0x19, 0x33, 0x49, 0x7b
+
+sub_z_from_x8:
+ ld r0, Z+
+ ld r1, X
+ sub r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ sbc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+T0 = IDX0
+T1 = 0
+CNT = 24
+xchg_zx8:
+ ldi CNT, 8
+1: ld T0, X
+ ld T1, Z
+ st X+, T1
+ st Z+, T0
+ dec CNT
+ brne 1b
+ ret
+
+
+
--- /dev/null
+/* threefish512_dec.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-22
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_inv8(void* data){
+ uint64_t t;
+ t = X(6);
+ X(6) = X(4);
+ X(4) = X(2);
+ X(2) = X(0);
+ X(0) = t;
+ t = X(7);
+ X(7) = X(3);
+ X(3) = t;
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<5; ++i){
+ X(i) -= ctx->k[(s+i)%9];
+ }
+ X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
+ X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+ X(7) -= ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
+ uint8_t i=0,s=18;
+ uint8_t r0[8] = {0x41, 0x4b, 0x59, 0x41, 0x32, 0x42, 0x60, 0x5a};
+ uint8_t r1[8] = {0x63, 0x32, 0x33, 0x61, 0x14, 0x2a, 0x24, 0x4a};
+ uint8_t r2[8] = {0x59, 0x13, 0x51, 0x10, 0x72, 0x29, 0x53, 0x62};
+ uint8_t r3[8] = {0x43, 0x11, 0x2a, 0x52, 0x19, 0x33, 0x49, 0x7b};
+ do{
+ if(i%4==0){
+ add_key_8(data, ctx, s);
+ --s;
+ }
+ permute_inv8(data);
+ threefish_invmix((uint8_t*)data + 0, r0[i%8]);
+ threefish_invmix((uint8_t*)data + 16, r1[i%8]);
+ threefish_invmix((uint8_t*)data + 32, r2[i%8]);
+ threefish_invmix((uint8_t*)data + 48, r3[i%8]);
+ ++i;
+ }while(i!=72);
+ add_key_8(data, ctx, s);
+}
+
--- /dev/null
+/* threefish512_enc.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+
+
+#define X(a) (((uint64_t*)data)[(a)])
+
+
+static
+void permute_8(void* data){
+ uint64_t t;
+ t = X(0);
+ X(0) = X(2);
+ X(2) = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(3);
+ X(3) = X(7);
+ X(7) = t;
+}
+/*
+static
+void permute_inv8(void* data){
+ uint64_t t;
+ t = X(6);
+ X(6) = X(4);
+ X(4) = X(2);
+ X(2) = X(0);
+ X(0) = t;
+ t = X(7);
+ X(7) = X(3);
+ X(3) = t;
+}
+*/
+
+#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+
+void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
+ memcpy(ctx->k, key, 8*8);
+ if(tweak){
+ memcpy(ctx->t, tweak, 2*8);
+ ctx->t[2] = T(0) ^ T(1);
+ }else{
+ memset(ctx->t, 0, 3*8);
+ }
+ uint8_t i;
+ ctx->k[8] = THREEFISH_KEY_CONST;
+ for(i=0; i<8; ++i){
+ ctx->k[8] ^= K(i);
+ }
+}
+
+static
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<5; ++i){
+ X(i) += ctx->k[(s+i)%9];
+ }
+ X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
+ X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+ X(7) += ctx->k[(s+7)%9] + s;
+}
+
+void threefish512_enc(void* data, const threefish512_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
+ uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
+ uint8_t r2[8] = {50, 43, 15, 58, 8, 41, 11, 39};
+ uint8_t r3[8] = {53, 31, 27, 7, 42, 14, 9, 35};
+ do{
+ if(i%4==0){
+ add_key_8(data, ctx, s);
+ ++s;
+ }
+ threefish_mix((uint8_t*)data + 0, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ threefish_mix((uint8_t*)data + 32, r2[i%8]);
+ threefish_mix((uint8_t*)data + 48, r3[i%8]);
+ permute_8(data);
+ ++i;
+ }while(i!=72);
+ add_key_8(data, ctx, s);
+}
+
--- /dev/null
+/* threefish512_enc_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-24
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+A0 = 14
+A1 = 15
+A2 = 16
+A3 = 17
+A4 = 18
+A5 = 19
+A6 = 20
+A7 = 21
+/*
+#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
+
+#define K(s) (((uint64_t*)key)[(s)])
+#define T(s) (((uint64_t*)tweak)[(s)])
+void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
+ memcpy(ctx->k, key, 8*8);
+ memcpy(ctx->t, tweak, 2*8);
+ uint8_t i;
+ ctx->k[8] = THREEFISH_KEY_CONST;
+ for(i=0; i<8; ++i){
+ ctx->k[8] ^= K(i);
+ }
+ ctx->t[2] = T(0) ^ T(1);
+}
+*/
+/*
+ * param key: r24:r25
+ * param tweak: r22:r23
+ * param ctx: r20:r21
+ */
+.global threefish512_init
+threefish512_init:
+ push_range 14, 17
+ movw r30, r20
+ movw r26, r24
+ ldi r24, 8
+ ldi A7, 0x55
+ mov A6, A7
+ movw A4, A6
+ movw A2, A6
+ movw A0, A6
+1:
+ ld r0, X+
+ st Z+, r0
+ eor A0, r0
+ ld r0, X+
+ st Z+, r0
+ eor A1, r0
+ ld r0, X+
+ st Z+, r0
+ eor A2, r0
+ ld r0, X+
+ st Z+, r0
+ eor A3, r0
+ ld r0, X+
+ st Z+, r0
+ eor A4, r0
+ ld r0, X+
+ st Z+, r0
+ eor A5, r0
+ ld r0, X+
+ st Z+, r0
+ eor A6, r0
+ ld r0, X+
+ st Z+, r0
+ eor A7, r0
+ dec r24
+ brne 1b
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ /* now the tweak */
+ movw r26, r22
+ tst r27
+ brne 3f
+ tst r26
+ brne 3f
+ ldi r26, 3*8
+1:
+ st Z+, r1
+ dec r26
+ brne 1b
+ rjmp 9f
+3:
+ ld A0, X+
+ ld A1, X+
+ ld A2, X+
+ ld A3, X+
+ ld A4, X+
+ ld A5, X+
+ ld A6, X+
+ ld A7, X+
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+ ld r0, X+
+ eor A0, r0
+ st Z+, r0
+ ld r0, X+
+ eor A1, r0
+ st Z+, r0
+ ld r0, X+
+ eor A2, r0
+ st Z+, r0
+ ld r0, X+
+ eor A3, r0
+ st Z+, r0
+ ld r0, X+
+ eor A4, r0
+ st Z+, r0
+ ld r0, X+
+ eor A5, r0
+ st Z+, r0
+ ld r0, X+
+ eor A6, r0
+ st Z+, r0
+ ld r0, X+
+ eor A7, r0
+ st Z+, r0
+ st Z+, A0
+ st Z+, A1
+ st Z+, A2
+ st Z+, A3
+ st Z+, A4
+ st Z+, A5
+ st Z+, A6
+ st Z+, A7
+9:
+ pop_range 14, 17
+ ret
+
+/******************************************************************************/
+/*
+#define X(a) (((uint64_t*)data)[(a)])
+void permute_8(void* data){
+ uint64_t t;
+ t = X(0);
+ X(0) = X(2);
+ X(2) = X(4);
+ X(4) = X(6);
+ X(6) = t;
+ t = X(3);
+ X(3) = X(7);
+ X(7) = t;
+}
+void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
+ uint8_t i;
+ for(i=0; i<5; ++i){
+ X(i) += ctx->k[(s+i)%9];
+ }
+ X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
+ X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
+ X(7) += ctx->k[(s+7)%9] + s;
+}
+void threefish512_enc(void* data, const threefish512_ctx_t* ctx){
+ uint8_t i=0,s=0;
+ uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
+ uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
+ uint8_t r2[8] = {50, 43, 15, 58, 8, 41, 11, 39};
+ uint8_t r3[8] = {53, 31, 27, 7, 42, 14, 9, 35};
+ do{
+ if(i%4==0){
+ add_key_8(data, ctx, s);
+ ++s;
+ }
+ threefish_mix((uint8_t*)data + 0, r0[i%8]);
+ threefish_mix((uint8_t*)data + 16, r1[i%8]);
+ threefish_mix((uint8_t*)data + 32, r2[i%8]);
+ threefish_mix((uint8_t*)data + 48, r3[i%8]);
+ permute_8(data);
+ ++i;
+ }while(i!=72);
+ add_key_8(data, ctx, s);
+}
+
+*/
+I = 2
+S = 3
+DATA0 = 4
+DATA1 = 5
+CTX0 = 6
+CTX1 = 7
+IDX0 = 8
+IDX1 = 9
+IDX2 = 10
+IDX3 = 11
+IDX4 = 12
+IDX5 = 13
+IDX6 = 14
+IDX7 = 15
+/*
+ * param data: r24:r25
+ * param ctx: r22:r23
+ */
+.global threefish512_enc
+threefish512_enc:
+ push r28
+ push r29
+ push_range 2, 17
+ movw DATA0, r24
+ movw CTX0, r22
+ clr I
+ clr S
+1:
+ mov r30, I
+ andi r30, 0x03
+ breq 2f
+ rjmp 4f
+2:
+ ldi r30, lo8(threefish512_slut9)
+ ldi r31, hi8(threefish512_slut9)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z+
+ lpm IDX2, Z+
+ lpm IDX3, Z+
+ lpm IDX4, Z+
+ lpm IDX5, Z+
+ lpm IDX6, Z+
+ lpm IDX7, Z
+ movw r30, CTX0
+ movw r26, DATA0
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX2
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX3
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX4
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX5
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX6
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, CTX0
+ add r30, IDX7
+ adc r31, r1
+ rcall add_z_to_x8
+
+ /* now the remaining key */
+ sbiw r26, 3*8
+ ldi r30, lo8(threefish512_slut3)
+ ldi r31, hi8(threefish512_slut3)
+ add r30, S
+ adc r31, r1
+ lpm IDX0, Z+
+ lpm IDX1, Z
+ movw r30, CTX0
+ adiw r30, 7*8 /* make Z pointing to (extended tweak) */
+ adiw r30, 2*8
+ movw IDX2, r30
+ add r30, IDX0
+ adc r31, r1
+ rcall add_z_to_x8
+ movw r30, IDX2
+ add r30, IDX1
+ adc r31, r1
+ rcall add_z_to_x8
+ ld r0, X
+ add r0, S
+ 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
+ inc S
+ mov r26, S
+ cpi r26, 19
+ brmi 4f
+exit:
+ pop_range 2, 17
+ pop r29
+ pop r28
+ ret
+4:
+ /* call mix */
+ ldi r30, lo8(threefish512_rc0)
+ ldi r31, hi8(threefish512_rc0)
+ mov r26, I
+ andi r26, 0x07
+ add r30, r26
+ adc r31, r1
+ lpm r22, Z
+ adiw r30, 8
+ lpm IDX0, Z
+ adiw r30, 8
+ lpm IDX1, Z
+ push IDX1
+ adiw r30, 8
+ lpm IDX1, Z
+
+ movw r24, DATA0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 16
+ mov r22, IDX0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 32
+ pop r22
+ ;mov r22, IDX0
+ call threefish_mix_asm /* no rcall? */
+ movw r24, DATA0
+ adiw r24, 48
+ mov r22, IDX1
+ call threefish_mix_asm /* no rcall? */
+ /* now the permutation */
+ movw r26, DATA0
+ movw r30, DATA0
+ adiw r30, 6*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ movw r30, DATA0
+ adiw r30, 2*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ adiw r26, 2*8
+ movw r30, DATA0
+ adiw r30, 4*8
+ rcall xchg_zx8
+ movw r26, DATA0
+ adiw r26, 3*8
+ movw r30, DATA0
+ adiw r30, 7*8
+ rcall xchg_zx8
+ inc I
+ rjmp 1b
+
+threefish512_slut9:
+ .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
+ .byte 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
+ .byte 0x38, 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28
+ .byte 0x30, 0x38, 0x40
+threefish512_slut3:
+ .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+ .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
+ .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
+
+threefish512_rc0: .byte 0x5a, 0x60, 0x42, 0x32, 0x41, 0x59, 0x4b, 0x41
+threefish512_rc1: .byte 0x4a, 0x24, 0x2a, 0x14, 0x61, 0x33, 0x32, 0x63
+threefish512_rc2: .byte 0x62, 0x53, 0x29, 0x72, 0x10, 0x51, 0x13, 0x59
+threefish512_rc3: .byte 0x7b, 0x49, 0x33, 0x19, 0x52, 0x2a, 0x11, 0x43
+
+add_z_to_x8:
+ ld r0, Z+
+ ld r1, X
+ add r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ ld r0, Z+
+ ld r1, X
+ adc r1, r0
+ st X+, r1
+ clr r1
+ ret
+
+T0 = IDX0
+T1 = 0
+CNT = 24
+xchg_zx8:
+ ldi CNT, 8
+1: ld T0, X
+ ld T1, Z
+ st X+, T1
+ st Z+, T0
+ dec CNT
+ brne 1b
+ ret
+
+
+
--- /dev/null
+/* threefish_invmix.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-21
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/*
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_invmix(void* data, uint8_t rot){
+ uint64_t x;
+ x = X1;
+ x ^= X0;
+ X1 = ((x>>rot)|(x<<(64-rot)));
+ X0 -= X1;
+}
+*/
+A0 = 10
+A1 = 11
+A2 = 12
+A3 = 13
+A4 = 14
+A5 = 15
+A6 = 16
+A7 = 17
+
+B0 = 18
+B1 = 19
+B2 = 20
+B3 = 21
+B4 = 22
+B5 = 23
+B6 = 24
+B7 = 25
+vROT = 27
+/*
+ * param data: r24:r25
+ * param rot: r22
+ */
+
+.global threefish_invmix_asm
+threefish_invmix_asm:
+ movw r28, r24
+ mov vROT,r22
+ ldd A0, Y+ 0
+ ldd A1, Y+ 1
+ ldd A2, Y+ 2
+ ldd A3, Y+ 3
+ ldd A4, Y+ 4
+ ldd A5, Y+ 5
+ ldd A6, Y+ 6
+ ldd A7, Y+ 7
+ ldd B0, Y+ 8
+ ldd B1, Y+ 9
+ ldd B2, Y+10
+ ldd B3, Y+11
+ ldd B4, Y+12
+ ldd B5, Y+13
+ ldd B6, Y+14
+ ldd B7, Y+15
+ eor B0, A0
+ eor B1, A1
+ eor B2, A2
+ eor B3, A3
+ eor B4, A4
+ eor B5, A5
+ eor B6, A6
+ eor B7, A7
+
+ mov r26, vROT
+ swap r26
+ andi r26, 0x07
+ ldi r30, pm_lo8(byte_rot_jmptable)
+ ldi r31, pm_hi8(byte_rot_jmptable)
+ add r30, r26
+ adc r31, r1
+ ijmp
+post_byterot:
+ bst vROT, 3
+ andi vROT, 0x07
+ brts 1f
+ rjmp bit_rotr
+1: rjmp bit_rotl
+post_bitrot:
+ sub A0, B0
+ sbc A1, B1
+ sbc A2, B2
+ sbc A3, B3
+ sbc A4, B4
+ sbc A5, B5
+ sbc A6, B6
+ sbc A7, B7
+
+ std Y+ 0, A0
+ std Y+ 1, A1
+ std Y+ 2, A2
+ std Y+ 3, A3
+ std Y+ 4, A4
+ std Y+ 5, A5
+ std Y+ 6, A6
+ std Y+ 7, A7
+ std Y+ 8, B0
+ std Y+ 9, B1
+ std Y+10, B2
+ std Y+11, B3
+ std Y+12, B4
+ std Y+13, B5
+ std Y+14, B6
+ std Y+15, B7
+exit:
+ ret
+
+byte_rot_jmptable:
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+ rjmp byte_rotr_1
+ rjmp byte_rotr_2
+ rjmp byte_rotr_3
+ rjmp byte_rotr_4
+ rjmp byte_rotr_5
+ rjmp byte_rotr_6
+ rjmp byte_rotr_7
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+
+
+
+; 0 1 2 3 4 5 6 7
+; 1 2 3 4 5 6 7 0
+;.global byte_rotr_1
+;.global byte_rotr_0
+byte_rotr_1: /* 10 words */
+ mov r0, B0
+ mov B0, B1
+ mov B1, B2
+ mov B2, B3
+ mov B3, B4
+ mov B4, B5
+ mov B5, B6
+ mov B6, B7
+ mov B7, r0
+byte_rotr_0:
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 2 3 4 5 6 7 0 1
+;.global byte_rotr_2
+byte_rotr_2: /* 11 words */
+ mov r0, B0
+ mov B0, B2
+ mov B2, B4
+ mov B4, B6
+ mov B6, r0
+ mov r0, B1
+ mov B1, B3
+ mov B3, B5
+ mov B5, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 3 4 5 6 7 0 1 2
+;.global byte_rotr_3
+byte_rotr_3: /* 10 words */
+ mov r0, B0
+ mov B0, B3
+ mov B3, B6
+ mov B6, B1
+ mov B1, B4
+ mov B4, B7
+ mov B7, B2
+ mov B2, B5
+ mov B5, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 4 5 6 7 0 1 2 3
+;.global byte_rotr_4
+byte_rotr_4: /* 13 words */
+ mov r0, B0
+ mov B0, B4
+ mov B4, r0
+
+ mov r0, B1
+ mov B1, B5
+ mov B5, r0
+
+ mov r0, B2
+ mov B2, B6
+ mov B6, r0
+
+ mov r0, B3
+ mov B3, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 5 6 7 0 1 2 3 4
+;.global byte_rotr_5
+byte_rotr_5: /* 10 words */
+ mov r0, B0
+ mov B0, B5
+ mov B5, B2
+ mov B2, B7
+ mov B7, B4
+ mov B4, B1
+ mov B1, B6
+ mov B6, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 6 7 0 1 2 3 4 5
+;.global byte_rotr_6
+byte_rotr_6: /* 11 words */
+ mov r0, B0
+ mov B0, B6
+ mov B6, B4
+ mov B4, B2
+ mov B2, r0
+
+ mov r0, B1
+ mov B1, B7
+ mov B7, B5
+ mov B5, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 7 0 1 2 3 4 5 6
+;.global byte_rotr_7
+byte_rotr_7: /* 10 words */
+ mov r0, B7
+ mov B7, B6
+ mov B6, B5
+ mov B5, B4
+ mov B4, B3
+ mov B3, B2
+ mov B2, B1
+ mov B1, B0
+ mov B0, r0
+ rjmp post_byterot
+
+;.global bit_rotl
+bit_rotl:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B7
+ rol r0
+ rol B0
+ rol B1
+ rol B2
+ rol B3
+ rol B4
+ rol B5
+ rol B6
+ rol B7
+ dec vROT
+ rjmp bit_rotl
+
+;.global bit_rotr
+bit_rotr:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B0
+ ror r0
+ ror B7
+ ror B6
+ ror B5
+ ror B4
+ ror B3
+ ror B2
+ ror B1
+ ror B0
+ dec vROT
+ rjmp bit_rotr
+
+
--- /dev/null
+/* threefish_invmix.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-21
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/*
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_invmix(void* data, uint8_t rot){
+ uint64_t x;
+ x = X1;
+ x ^= X0;
+ X1 = ((x>>rot)|(x<<(64-rot)));
+ X0 -= X1;
+}
+*/
+A0 = 10
+A1 = 11
+A2 = 12
+A3 = 13
+A4 = 14
+A5 = 15
+A6 = 16
+A7 = 17
+
+B0 = 18
+B1 = 19
+B2 = 20
+B3 = 21
+B4 = 22
+B5 = 23
+B6 = 24
+B7 = 25
+vROT = 27
+/*
+ * param data: r24:r25
+ * param rot: r22
+ */
+
+.global threefish_invmix
+threefish_invmix:
+ push_range 10, 17
+ push r28
+ push r29
+ movw r28, r24
+ mov vROT,r22
+ ldd A0, Y+ 0
+ ldd A1, Y+ 1
+ ldd A2, Y+ 2
+ ldd A3, Y+ 3
+ ldd A4, Y+ 4
+ ldd A5, Y+ 5
+ ldd A6, Y+ 6
+ ldd A7, Y+ 7
+ ldd B0, Y+ 8
+ ldd B1, Y+ 9
+ ldd B2, Y+10
+ ldd B3, Y+11
+ ldd B4, Y+12
+ ldd B5, Y+13
+ ldd B6, Y+14
+ ldd B7, Y+15
+ eor B0, A0
+ eor B1, A1
+ eor B2, A2
+ eor B3, A3
+ eor B4, A4
+ eor B5, A5
+ eor B6, A6
+ eor B7, A7
+
+ mov r26, vROT
+ swap r26
+ andi r26, 0x07
+ ldi r30, pm_lo8(byte_rot_jmptable)
+ ldi r31, pm_hi8(byte_rot_jmptable)
+ add r30, r26
+ adc r31, r1
+ ijmp
+post_byterot:
+ bst vROT, 3
+ andi vROT, 0x07
+ brts 1f
+ rjmp bit_rotr
+1: rjmp bit_rotl
+post_bitrot:
+ sub A0, B0
+ sbc A1, B1
+ sbc A2, B2
+ sbc A3, B3
+ sbc A4, B4
+ sbc A5, B5
+ sbc A6, B6
+ sbc A7, B7
+
+ std Y+ 0, A0
+ std Y+ 1, A1
+ std Y+ 2, A2
+ std Y+ 3, A3
+ std Y+ 4, A4
+ std Y+ 5, A5
+ std Y+ 6, A6
+ std Y+ 7, A7
+ std Y+ 8, B0
+ std Y+ 9, B1
+ std Y+10, B2
+ std Y+11, B3
+ std Y+12, B4
+ std Y+13, B5
+ std Y+14, B6
+ std Y+15, B7
+exit:
+ pop r29
+ pop r28
+ pop_range 10, 17
+ ret
+
+byte_rot_jmptable:
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+ rjmp byte_rotr_1
+ rjmp byte_rotr_2
+ rjmp byte_rotr_3
+ rjmp byte_rotr_4
+ rjmp byte_rotr_5
+ rjmp byte_rotr_6
+ rjmp byte_rotr_7
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+
+
+
+; 0 1 2 3 4 5 6 7
+; 1 2 3 4 5 6 7 0
+;.global byte_rotr_1
+;.global byte_rotr_0
+byte_rotr_1: /* 10 words */
+ mov r0, B0
+ mov B0, B1
+ mov B1, B2
+ mov B2, B3
+ mov B3, B4
+ mov B4, B5
+ mov B5, B6
+ mov B6, B7
+ mov B7, r0
+byte_rotr_0:
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 2 3 4 5 6 7 0 1
+;.global byte_rotr_2
+byte_rotr_2: /* 11 words */
+ mov r0, B0
+ mov B0, B2
+ mov B2, B4
+ mov B4, B6
+ mov B6, r0
+ mov r0, B1
+ mov B1, B3
+ mov B3, B5
+ mov B5, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 3 4 5 6 7 0 1 2
+;.global byte_rotr_3
+byte_rotr_3: /* 10 words */
+ mov r0, B0
+ mov B0, B3
+ mov B3, B6
+ mov B6, B1
+ mov B1, B4
+ mov B4, B7
+ mov B7, B2
+ mov B2, B5
+ mov B5, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 4 5 6 7 0 1 2 3
+;.global byte_rotr_4
+byte_rotr_4: /* 13 words */
+ mov r0, B0
+ mov B0, B4
+ mov B4, r0
+
+ mov r0, B1
+ mov B1, B5
+ mov B5, r0
+
+ mov r0, B2
+ mov B2, B6
+ mov B6, r0
+
+ mov r0, B3
+ mov B3, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 5 6 7 0 1 2 3 4
+;.global byte_rotr_5
+byte_rotr_5: /* 10 words */
+ mov r0, B0
+ mov B0, B5
+ mov B5, B2
+ mov B2, B7
+ mov B7, B4
+ mov B4, B1
+ mov B1, B6
+ mov B6, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 6 7 0 1 2 3 4 5
+;.global byte_rotr_6
+byte_rotr_6: /* 11 words */
+ mov r0, B0
+ mov B0, B6
+ mov B6, B4
+ mov B4, B2
+ mov B2, r0
+
+ mov r0, B1
+ mov B1, B7
+ mov B7, B5
+ mov B5, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 7 0 1 2 3 4 5 6
+;.global byte_rotr_7
+byte_rotr_7: /* 10 words */
+ mov r0, B7
+ mov B7, B6
+ mov B6, B5
+ mov B5, B4
+ mov B4, B3
+ mov B3, B2
+ mov B2, B1
+ mov B1, B0
+ mov B0, r0
+ rjmp post_byterot
+
+;.global bit_rotl
+bit_rotl:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B7
+ rol r0
+ rol B0
+ rol B1
+ rol B2
+ rol B3
+ rol B4
+ rol B5
+ rol B6
+ rol B7
+ dec vROT
+ rjmp bit_rotl
+
+;.global bit_rotr
+bit_rotr:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B0
+ ror r0
+ ror B7
+ ror B6
+ ror B5
+ ror B4
+ ror B3
+ ror B2
+ ror B1
+ ror B0
+ dec vROT
+ rjmp bit_rotr
+
+
--- /dev/null
+/* threefish_invmix_c.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-21
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_invmix(void* data, uint8_t rot){
+ uint64_t x;
+ x = X1;
+ x ^= X0;
+ X1 = ((x>>rot)|(x<<(64-rot)));
+ X0 -= X1;
+}
--- /dev/null
+/* threefish_mix.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/*
+#define B0 (((uint64_t*)data)[0])
+#define B1 (((uint64_t*)data)[1])
+static
+void mix(void* data, uint8_t rot){
+ uint64_t x;
+ x = B1;
+ B0 += x;
+ B1 = ((x<<rot)|(x>>(64-rot))) ^ B0;
+}
+*/
+A0 = 10
+A1 = 11
+A2 = 12
+A3 = 13
+A4 = 14
+A5 = 15
+A6 = 16
+A7 = 17
+
+B0 = 18
+B1 = 19
+B2 = 20
+B3 = 21
+B4 = 22
+B5 = 23
+B6 = 24
+B7 = 25
+vROT = 27
+/*
+ * param data: r24:r25
+ * param rot: r22
+ */
+
+.global threefish_mix_asm
+threefish_mix_asm:
+ movw r28, r24
+ mov vROT,r22
+ ldd A0, Y+ 0
+ ldd A1, Y+ 1
+ ldd A2, Y+ 2
+ ldd A3, Y+ 3
+ ldd A4, Y+ 4
+ ldd A5, Y+ 5
+ ldd A6, Y+ 6
+ ldd A7, Y+ 7
+ ldd B0, Y+ 8
+ ldd B1, Y+ 9
+ ldd B2, Y+10
+ ldd B3, Y+11
+ ldd B4, Y+12
+ ldd B5, Y+13
+ ldd B6, Y+14
+ ldd B7, Y+15
+ add A0, B0
+ adc A1, B1
+ adc A2, B2
+ adc A3, B3
+ adc A4, B4
+ adc A5, B5
+ adc A6, B6
+ adc A7, B7
+
+ mov r26, vROT
+ swap r26
+ andi r26, 0x07
+ ldi r30, pm_lo8(byte_rot_jmptable)
+ ldi r31, pm_hi8(byte_rot_jmptable)
+ add r30, r26
+ adc r31, r1
+ ijmp
+post_byterot:
+ bst vROT, 3
+ andi vROT, 0x07
+ brts 1f
+ rjmp bit_rotl
+1: rjmp bit_rotr
+post_bitrot:
+ eor B0, A0
+ eor B1, A1
+ eor B2, A2
+ eor B3, A3
+ eor B4, A4
+ eor B5, A5
+ eor B6, A6
+ eor B7, A7
+
+ std Y+ 0, A0
+ std Y+ 1, A1
+ std Y+ 2, A2
+ std Y+ 3, A3
+ std Y+ 4, A4
+ std Y+ 5, A5
+ std Y+ 6, A6
+ std Y+ 7, A7
+ std Y+ 8, B0
+ std Y+ 9, B1
+ std Y+10, B2
+ std Y+11, B3
+ std Y+12, B4
+ std Y+13, B5
+ std Y+14, B6
+ std Y+15, B7
+exit:
+ ret
+
+
+byte_rot_jmptable:
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+ rjmp byte_rotr_7
+ rjmp byte_rotr_6
+ rjmp byte_rotr_5
+ rjmp byte_rotr_4
+ rjmp byte_rotr_3
+ rjmp byte_rotr_2
+ rjmp byte_rotr_1
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+
+; 0 1 2 3 4 5 6 7
+; 1 2 3 4 5 6 7 0
+;.global byte_rotr_1
+;.global byte_rotr_0
+byte_rotr_1: /* 10 words */
+ mov r0, B0
+ mov B0, B1
+ mov B1, B2
+ mov B2, B3
+ mov B3, B4
+ mov B4, B5
+ mov B5, B6
+ mov B6, B7
+ mov B7, r0
+byte_rotr_0:
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 2 3 4 5 6 7 0 1
+;.global byte_rotr_2
+byte_rotr_2: /* 11 words */
+ mov r0, B0
+ mov B0, B2
+ mov B2, B4
+ mov B4, B6
+ mov B6, r0
+ mov r0, B1
+ mov B1, B3
+ mov B3, B5
+ mov B5, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 3 4 5 6 7 0 1 2
+;.global byte_rotr_3
+byte_rotr_3: /* 10 words */
+ mov r0, B0
+ mov B0, B3
+ mov B3, B6
+ mov B6, B1
+ mov B1, B4
+ mov B4, B7
+ mov B7, B2
+ mov B2, B5
+ mov B5, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 4 5 6 7 0 1 2 3
+;.global byte_rotr_4
+byte_rotr_4: /* 13 words */
+ mov r0, B0
+ mov B0, B4
+ mov B4, r0
+
+ mov r0, B1
+ mov B1, B5
+ mov B5, r0
+
+ mov r0, B2
+ mov B2, B6
+ mov B6, r0
+
+ mov r0, B3
+ mov B3, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 5 6 7 0 1 2 3 4
+;.global byte_rotr_5
+byte_rotr_5: /* 10 words */
+ mov r0, B0
+ mov B0, B5
+ mov B5, B2
+ mov B2, B7
+ mov B7, B4
+ mov B4, B1
+ mov B1, B6
+ mov B6, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 6 7 0 1 2 3 4 5
+;.global byte_rotr_6
+byte_rotr_6: /* 11 words */
+ mov r0, B0
+ mov B0, B6
+ mov B6, B4
+ mov B4, B2
+ mov B2, r0
+
+ mov r0, B1
+ mov B1, B7
+ mov B7, B5
+ mov B5, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 7 0 1 2 3 4 5 6
+;.global byte_rotr_7
+byte_rotr_7: /* 10 words */
+ mov r0, B7
+ mov B7, B6
+ mov B6, B5
+ mov B5, B4
+ mov B4, B3
+ mov B3, B2
+ mov B2, B1
+ mov B1, B0
+ mov B0, r0
+ rjmp post_byterot
+
+;.global bit_rotl
+bit_rotl:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B7
+ rol r0
+ rol B0
+ rol B1
+ rol B2
+ rol B3
+ rol B4
+ rol B5
+ rol B6
+ rol B7
+ dec vROT
+ rjmp bit_rotl
+
+;.global bit_rotr
+bit_rotr:
+ tst vROT
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B0
+ ror r0
+ ror B7
+ ror B6
+ ror B5
+ ror B4
+ ror B3
+ ror B2
+ ror B1
+ ror B0
+ dec vROT
+ rjmp bit_rotr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* threefish_mix.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/*
+#define B0 (((uint64_t*)data)[0])
+#define B1 (((uint64_t*)data)[1])
+static
+void mix(void* data, uint8_t rot){
+ uint64_t x;
+ x = B1;
+ B0 += x;
+ B1 = ((x<<rot)|(x>>(64-rot))) ^ B0;
+}
+*/
+A0 = 10
+A1 = 11
+A2 = 12
+A3 = 13
+A4 = 14
+A5 = 15
+A6 = 16
+A7 = 17
+
+B0 = 18
+B1 = 19
+B2 = 20
+B3 = 21
+B4 = 22
+B5 = 23
+B6 = 24
+B7 = 25
+vROT = 27
+/*
+ * param data: r24:r25
+ * param rot: r22
+ */
+
+.global threefish_mix
+threefish_mix:
+ push r28
+ push r29
+ push_range 10, 17
+ movw r28, r24
+ mov vROT,r22
+ ldd A0, Y+ 0
+ ldd A1, Y+ 1
+ ldd A2, Y+ 2
+ ldd A3, Y+ 3
+ ldd A4, Y+ 4
+ ldd A5, Y+ 5
+ ldd A6, Y+ 6
+ ldd A7, Y+ 7
+ ldd B0, Y+ 8
+ ldd B1, Y+ 9
+ ldd B2, Y+10
+ ldd B3, Y+11
+ ldd B4, Y+12
+ ldd B5, Y+13
+ ldd B6, Y+14
+ ldd B7, Y+15
+ add A0, B0
+ adc A1, B1
+ adc A2, B2
+ adc A3, B3
+ adc A4, B4
+ adc A5, B5
+ adc A6, B6
+ adc A7, B7
+
+ mov r26, vROT
+ adiw r26, 3
+ lsr r26
+ lsr r26
+ lsr r26
+; andi r26, 0x07
+ ldi r30, pm_lo8(byte_rot_jmptable)
+ ldi r31, pm_hi8(byte_rot_jmptable)
+ add r30, r26
+ adc r31, r1
+ ijmp
+post_byterot:
+ ldi r30, lo8(bit_rot_lut)
+ ldi r31, hi8(bit_rot_lut)
+ andi vROT, 0x07
+ add r30, vROT
+ adc r31, r1
+ lpm r27, Z
+ bst r27, 7
+ andi r27, 0x07
+ brts 1f
+ rjmp bit_rotl
+1: rjmp bit_rotr
+post_bitrot:
+ eor B0, A0
+ eor B1, A1
+ eor B2, A2
+ eor B3, A3
+ eor B4, A4
+ eor B5, A5
+ eor B6, A6
+ eor B7, A7
+
+ std Y+ 0, A0
+ std Y+ 1, A1
+ std Y+ 2, A2
+ std Y+ 3, A3
+ std Y+ 4, A4
+ std Y+ 5, A5
+ std Y+ 6, A6
+ std Y+ 7, A7
+ std Y+ 8, B0
+ std Y+ 9, B1
+ std Y+10, B2
+ std Y+11, B3
+ std Y+12, B4
+ std Y+13, B5
+ std Y+14, B6
+ std Y+15, B7
+exit:
+ pop_range 10, 17
+ pop r29
+ pop r28
+ ret
+
+bit_rot_lut:
+ .byte 0x00
+ .byte 0x01
+ .byte 0x02
+ .byte 0x03
+ .byte 0x04
+ .byte 0x83
+ .byte 0x82
+ .byte 0x81
+
+byte_rot_jmptable:
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+ rjmp byte_rotr_7
+ rjmp byte_rotr_6
+ rjmp byte_rotr_5
+ rjmp byte_rotr_4
+ rjmp byte_rotr_3
+ rjmp byte_rotr_2
+ rjmp byte_rotr_1
+ rjmp post_byterot;ret; rjmp byte_rotr_0
+
+; 0 1 2 3 4 5 6 7
+; 1 2 3 4 5 6 7 0
+
+byte_rotr_1: /* 10 words */
+ mov r0, B0
+ mov B0, B1
+ mov B1, B2
+ mov B2, B3
+ mov B3, B4
+ mov B4, B5
+ mov B5, B6
+ mov B6, B7
+ mov B7, r0
+byte_rotr_0:
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 2 3 4 5 6 7 0 1
+
+byte_rotr_2: /* 11 words */
+ mov r0, B0
+ mov B0, B2
+ mov B2, B4
+ mov B4, B6
+ mov B6, r0
+ mov r0, B1
+ mov B1, B3
+ mov B3, B5
+ mov B5, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 3 4 5 6 7 0 1 2
+
+byte_rotr_3: /* 10 words */
+ mov r0, B0
+ mov B0, B3
+ mov B3, B6
+ mov B6, B1
+ mov B1, B4
+ mov B4, B7
+ mov B7, B2
+ mov B2, B5
+ mov B5, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 4 5 6 7 0 1 2 3
+byte_rotr_4: /* 13 words */
+ mov r0, B0
+ mov B0, B4
+ mov B4, r0
+
+ mov r0, B1
+ mov B1, B5
+ mov B5, r0
+
+ mov r0, B2
+ mov B2, B6
+ mov B6, r0
+
+ mov r0, B3
+ mov B3, B7
+ mov B7, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 5 6 7 0 1 2 3 4
+byte_rotr_5: /* 10 words */
+ mov r0, B0
+ mov B0, B5
+ mov B5, B2
+ mov B2, B7
+ mov B7, B4
+ mov B4, B1
+ mov B1, B6
+ mov B6, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 6 7 0 1 2 3 4 5
+byte_rotr_6: /* 11 words */
+ mov r0, B0
+ mov B0, B6
+ mov B6, B4
+ mov B4, B2
+ mov B2, r0
+
+ mov r0, B1
+ mov B1, B7
+ mov B7, B5
+ mov B5, B3
+ mov B3, r0
+ rjmp post_byterot
+
+; 0 1 2 3 4 5 6 7
+; 7 0 1 2 3 4 5 6
+byte_rotr_7: /* 10 words */
+ mov r0, B7
+ mov B7, B6
+ mov B6, B5
+ mov B5, B4
+ mov B4, B3
+ mov B3, B2
+ mov B2, B1
+ mov B1, B0
+ mov B0, r0
+ rjmp post_byterot
+
+bit_rotl:
+ tst r27
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B7
+ rol r0
+ rol B0
+ rol B1
+ rol B2
+ rol B3
+ rol B4
+ rol B5
+ rol B6
+ rol B7
+ dec r27
+ rjmp bit_rotl
+
+bit_rotr:
+ tst r27
+ brne 1f
+ rjmp post_bitrot
+1: mov r0, B0
+ ror r0
+ ror B7
+ ror B6
+ ror B5
+ ror B4
+ ror B3
+ ror B2
+ ror B1
+ ror B0
+ dec r27
+ rjmp bit_rotr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* threefish_mix_c.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ *
+ *
+ *
+ */
+
+#include <stdint.h>
+
+#define X0 (((uint64_t*)data)[0])
+#define X1 (((uint64_t*)data)[1])
+void threefish_mix(void* data, uint8_t rot){
+ uint64_t x;
+ x = X1;
+ X0 += x;
+ X1 = ((x<<rot)|(x>>(64-rot))) ^ X0;
+}
--- /dev/null
+/* ubi.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#ifndef UBI_H_
+#define UBI_H_
+
+#include <stdint.h>
+
+#define UBI_TYPE_KEY 0
+#define UBI_TYPE_CFG 4
+#define UBI_TYPE_PRS 8
+#define UBI_TYPE_PK 12
+#define UBI_TYPE_KDF 16
+#define UBI_TYPE_NON 20
+#define UBI_TYPE_MSG 48
+#define UBI_TYPE_OUT 63
+
+#define UBI256_BLOCKSIZE 256
+#define UBI256_BLOCKSIZE_B ((UBI256_BLOCKSIZE+7)/8)
+
+#define UBI512_BLOCKSIZE 512
+#define UBI512_BLOCKSIZE_B ((UBI512_BLOCKSIZE+7)/8)
+
+#define UBI1024_BLOCKSIZE 1024
+#define UBI1024_BLOCKSIZE_B ((UBI1024_BLOCKSIZE+7)/8)
+
+
+typedef struct{
+ uint8_t tweak[16];
+ uint8_t g[32];
+}ubi256_ctx_t;
+
+typedef struct{
+ uint8_t tweak[16];
+ uint8_t g[64];
+}ubi512_ctx_t;
+
+typedef struct{
+ uint8_t tweak[16];
+ uint8_t g[128];
+}ubi1024_ctx_t;
+
+void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type);
+void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block);
+void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx);
+
+void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type);
+void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block);
+void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx);
+
+void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type);
+void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block);
+void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b);
+void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx);
+
+typedef struct{
+ char schema[4];
+ uint16_t version;
+ uint16_t reserved1;
+ uint64_t out_length;
+ uint8_t tree_leaf_size;
+ uint8_t tree_fan_out;
+ uint8_t tree_max_height;
+ uint8_t reserved2[13];
+}skein_config_t;
+
+
+#endif /* UBI_H_ */
--- /dev/null
+/* ubi1024.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, UBI1024_BLOCKSIZE_B);
+}
+
+void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block){
+ threefish1024_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI1024_BLOCKSIZE_B;
+ threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI1024_BLOCKSIZE_B);
+ threefish1024_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI1024_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+
+
+void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish1024_ctx_t tfctx;
+ while(length_b>UBI1024_BLOCKSIZE){
+ ubi1024_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI1024_BLOCKSIZE_B;
+ length_b -= UBI1024_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07)
+ ctx->tweak[14] |= 0x80;
+ threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI1024_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07)
+ ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+ threefish1024_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+}
+
+void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI1024_BLOCKSIZE_B);
+}
+
--- /dev/null
+/* ubi1024_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, UBI1024_BLOCKSIZE_B);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param g: r22:r23
+ * param type: r20
+ */
+.global ubi1024_init
+ubi1024_init:
+ movw r26, r24
+ ldi r21, 15
+1: st X+, r1
+ dec r21
+ brne 1b
+ ori r20, 0x40
+ st X+, r20
+ ldi r21, 128
+ movw r30, r22
+2: ld r20, Z+
+ st X+, r20
+ dec r21
+ brne 2b
+ ret
+
+/******************************************************************************/
+/*
+void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI1024_BLOCKSIZE_B);
+}
+*/
+/*
+ * param dest: r24:r24
+ * param ctx: r22:r23
+ */
+.global ubi1024_ctx2hash
+ubi1024_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ adiw r30, 16
+ ldi r22, 128
+1: ld r23, Z+
+ st X+, r23
+ dec r22
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block){
+ threefish1024_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI1024_BLOCKSIZE_B;
+ threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI1024_BLOCKSIZE_B);
+ threefish1024_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI1024_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ */
+CTX0 = 2
+CTX1 = 3
+BLOCK0 = 4
+BLOCK1 = 5
+TFCTX0 = 6
+TFCTX1 = 7
+.global ubi1024_nextBlock
+ubi1024_nextBlock:
+ stack_alloc_large 20*8
+ push_range 2, 7
+ adiw r30, 1 /* Z points to tfctx */
+ movw TFCTX0, r30
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw r26, r24
+/* add BLOCKSIZE_B (128) to tweak */
+ ldi r25, 128
+ ld r24, X
+ add r24, r25
+ st X+, r24
+ ldi r25, 11
+1: ld r24, X
+ adc r24, r1
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish1024_init */
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points to ctx->g */
+ movw r20, TFCTX0
+ rcall threefish1024_init
+ /* copy block to ctx->g */
+ movw r26, CTX0
+ movw r30, BLOCK0
+ ldi r25, 128
+1: ld r24, Z+
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish1024_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish1024_enc
+/* xor block into ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ ldi r25, 128
+1: ld r24, X+
+ ld r23, Z
+ eor r23, r24
+ st Z+, r23
+ dec r25
+ brne 1b
+/* clear 'first' bit in tweak */
+ sbiw r30, 1+2
+ sbiw r30, 63
+ sbiw r30, 63
+ ld r24, Z
+ andi r24, ~0x40
+ st Z, r24
+exit:
+ pop_range 2, 7
+ stack_free_large2 20*8
+ ret
+
+/******************************************************************************/
+/*
+void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish1024_ctx_t tfctx;
+ while(length_b>UBI1024_BLOCKSIZE){
+ ubi1024_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI1024_BLOCKSIZE_B;
+ length_b -= UBI1024_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07)
+ ctx->tweak[14] |= 0x80;
+ threefish1024_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI1024_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07)
+ ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+ threefish1024_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ * param ength_b: r20:r21
+ */
+MASK_B = 8
+LEN_B = 9
+TFCTX0 = 10
+TFCTX1 = 11
+CTX0 = 12
+CTX1 = 13
+BLOCK0 = 14
+BLOCK1 = 15
+LENGTH0 = 16
+LENGTH1 = 17
+.global ubi1024_lastBlock
+ubi1024_lastBlock:
+/* run nextBlock for preceding blocks*/
+ push_range 8, 17
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw LENGTH0, r20
+1: cpi LENGTH1, 5
+ brlo 2f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi1024_nextBlock
+ ldi r25, 128
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ subi LENGTH1, 4
+ rjmp 1b
+2: cpi LENGTH1, 4
+ brlo 3f
+ tst LENGTH0
+ breq 3f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi1024_nextBlock
+ ldi r25, 128
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ subi LENGTH1, 4
+3: /* now the real fun */
+ stack_alloc_large 20*8
+ adiw r30, 1
+ movw TFCTX0, r30
+ /* calculate LEN_B */
+ movw r24, LENGTH0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ mov LEN_B, r24
+ /* add length to tweak */
+ movw r30, CTX0
+ ld r24, Z
+ add r24, LEN_B
+ st Z+, r24
+ ldi r25, 11
+1: ld r24, Z
+ adc r24, r1
+ st Z+, r24
+ dec r25
+ brne 1b
+ /* set 'final' bit*/
+ movw r30, CTX0
+ ldd r24, Z+15
+ ori r24, 0x80
+ std Z+15, r24
+ /* store in MASK_B if we do bit processing and set 'BitPad' bit*/
+ clr MASK_B
+ mov r24, LENGTH0
+ andi r24, 0x07
+ tst r24
+ breq 4f
+ ldd r25, Z+14
+ ori r25, 0x80
+ std Z+14, r25
+ ldi r25, 0x80
+ mov MASK_B, r25
+1: lsr MASK_B
+ dec r24
+ brne 1b
+4: /* call threefish1024_init*/
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points at ctx->g */
+ movw r20, TFCTX0
+ rcall threefish1024_init
+ /* copy block to ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ mov r24, LEN_B
+ ldi r25, 128
+ sub r25, LEN_B
+ tst r24
+1: breq 2f
+ ld r22, X+
+ st Z+, r22
+ dec r24
+ rjmp 1b
+2: tst MASK_B
+ breq 29f
+ or r22, MASK_B
+ st -Z, r22
+ adiw r30, 1
+29: tst r25
+3: breq 4f
+ st Z+, r1
+ dec r25
+ rjmp 3b
+4: /* call threefish1024_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish1024_enc
+ /* xor block into ctx->g */
+ movw r30, CTX0
+ movw r26, BLOCK0
+ tst LEN_B
+5: breq 6f
+ ld r22, X+
+ ld r23, Z
+ eor r23, r22
+ st Z+, r23
+ dec LEN_B
+ rjmp 5b
+6: tst MASK_B
+ breq 7f
+ eor r23, MASK_B
+ st -Z, r23
+
+7: stack_free_large2 20*8
+ pop_range 8, 17
+ ret
+
+
--- /dev/null
+/* ubi256.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, 32);
+}
+
+void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block){
+ threefish256_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
+ threefish256_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
+ threefish256_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI256_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+
+
+void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish256_ctx_t tfctx;
+ while(length_b>UBI256_BLOCKSIZE){
+ ubi256_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
+ length_b -= UBI256_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07){
+ ctx->tweak[14] |= 0x80;
+ }
+ threefish256_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI256_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] |= 0x80>>(length_b&7);
+ ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
+ }
+ threefish256_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+
+}
+
+void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
+}
+
--- /dev/null
+/* ubi256_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-16
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, 32);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param g: r22:r23
+ * param type: r20
+ */
+.global ubi256_init
+ubi256_init:
+ movw r26, r24
+ ldi r21, 15
+1: st X+, r1
+ dec r21
+ brne 1b
+ ori r20, 0x40
+ st X+, r20
+ ldi r21, 32
+ movw r30, r22
+2: ld r20, Z+
+ st X+, r20
+ dec r21
+ brne 2b
+ ret
+
+/******************************************************************************/
+/*
+void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
+}
+*/
+/*
+ * param dest: r24:r24
+ * param ctx: r22:r23
+ */
+.global ubi256_ctx2hash
+ubi256_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ adiw r30, 16
+ ldi r22, 32
+1: ld r23, Z+
+ st X+, r23
+ dec r22
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block){
+ threefish256_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
+ threefish256_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
+ threefish256_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI256_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ */
+CTX0 = 2
+CTX1 = 3
+BLOCK0 = 4
+BLOCK1 = 5
+TFCTX0 = 6
+TFCTX1 = 7
+.global ubi256_nextBlock
+ubi256_nextBlock:
+ stack_alloc_large 64
+ push_range 2, 7
+ adiw r30, 1 /* Z points to tfctx */
+ movw TFCTX0, r30
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw r26, r24
+/* add BLOCKSIZE_B (32) to tweak */
+ ldi r25, 32
+ ld r24, X
+ add r24, r25
+ st X+, r24
+ ldi r25, 11
+1: ld r24, X
+ adc r24, r1
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish256_init */
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points to ctx->g */
+ movw r20, TFCTX0
+ rcall threefish256_init
+ /* copy block to ctx->g */
+ movw r26, CTX0
+ movw r30, BLOCK0
+ ldi r25, 32
+1: ld r24, Z+
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish256_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish256_enc
+/* xor block into ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ ldi r25, 32
+1: ld r24, X+
+ ld r23, Z
+ eor r23, r24
+ st Z+, r23
+ dec r25
+ brne 1b
+/* clear 'first' bit in tweak */
+ sbiw r30, 33
+ ld r24, Z
+ andi r24, ~0x40
+ st Z, r24
+exit:
+ pop_range 2, 7
+ stack_free_large 64
+ ret
+
+/******************************************************************************/
+/*
+void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish256_ctx_t tfctx;
+ while(length_b>UBI256_BLOCKSIZE){
+ ubi256_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
+ length_b -= UBI256_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07){
+ ctx->tweak[14] |= 0x80;
+ }
+ threefish256_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI256_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] |= 0x80>>(length_b&7);
+ ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
+ }
+ threefish256_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ * param ength_b: r20:r21
+ */
+MASK_B = 8
+LEN_B = 9
+TFCTX0 = 10
+TFCTX1 = 11
+CTX0 = 12
+CTX1 = 13
+BLOCK0 = 14
+BLOCK1 = 15
+LENGTH0 = 16
+LENGTH1 = 17
+.global ubi256_lastBlock
+ubi256_lastBlock:
+/* run nextBlock for preceding blocks*/
+ push_range 8, 17
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw LENGTH0, r20
+1: cpi LENGTH1, 2
+ brlo 2f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi256_nextBlock
+ ldi r25, 32
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ dec LENGTH1
+ rjmp 1b
+2: tst LENGTH1
+ breq 3f
+ tst LENGTH0
+ breq 3f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi256_nextBlock
+ ldi r25, 32
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ dec LENGTH1
+3: /* now the real fun */
+ stack_alloc_large 64
+ adiw r30, 1
+ movw TFCTX0, r30
+ /* calculate LEN_B */
+ movw r24, LENGTH0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r24
+ lsr r24
+ mov LEN_B, r24
+ /* add length to tweak */
+ movw r30, CTX0
+ ld r24, Z
+ add r24, LEN_B
+ st Z+, r24
+ ldi r25, 11
+1: ld r24, Z
+ adc r24, r1
+ st Z+, r24
+ dec r25
+ brne 1b
+ /* set 'final' bit*/
+ movw r30, CTX0
+ ldd r24, Z+15
+ ori r24, 0x80
+ std Z+15, r24
+ /* store in T if we do bit processing and set 'BitPad' bit*/
+ clr MASK_B
+ mov r24, LENGTH0
+ andi r24, 0x07
+ tst r24
+ breq 4f
+ ldd r25, Z+14
+ ori r25, 0x80
+ std Z+14, r25
+ ldi r25, 0x80
+ mov MASK_B, r25
+1: lsr MASK_B
+ dec r24
+ brne 1b
+4: /* call threefish256_init*/
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points at ctx->g */
+ movw r20, TFCTX0
+ rcall threefish256_init
+ /* copy block to ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ mov r24, LEN_B
+ ldi r25, 32
+ sub r25, LEN_B
+ tst r24
+1: breq 2f
+ ld r22, X+
+ st Z+, r22
+ dec r24
+ rjmp 1b
+2: tst MASK_B
+ breq 29f
+ or r22, MASK_B
+ st -Z, r22
+ adiw r30, 1
+29: tst r25
+3: breq 4f
+ st Z+, r1
+ dec r25
+ rjmp 3b
+4: /* call threefish256_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish256_enc
+ /* xor block into ctx->g */
+ movw r30, CTX0
+ movw r26, BLOCK0
+ tst LEN_B
+5: breq 6f
+ ld r22, X+
+ ld r23, Z
+ eor r23, r22
+ st Z+, r23
+ dec LEN_B
+ rjmp 5b
+6: tst MASK_B
+ breq 7f
+ eor r23, MASK_B
+ st -Z, r23
+
+7: stack_free_large 64
+ pop_range 8, 17
+ ret
+
+
--- /dev/null
+/* ubi512.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-12
+ * \license GPLv3 or later
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "threefish.h"
+#include "memxor.h"
+#include "ubi.h"
+
+void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
+}
+
+void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
+ threefish512_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
+ threefish512_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
+ threefish512_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+
+
+void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish512_ctx_t tfctx;
+ while(length_b>UBI512_BLOCKSIZE){
+ ubi512_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
+ length_b -= UBI512_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07)
+ ctx->tweak[14] |= 0x80;
+ threefish512_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07)
+ ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+ threefish512_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+}
+
+void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
+}
+
--- /dev/null
+/* ubi512_asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2009-03-25
+ * \license GPLv3 or later
+ */
+
+#include "avr-asm-macros.S"
+
+/******************************************************************************/
+/*
+void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
+ memset(ctx->tweak, 0, 15);
+ ctx->tweak[15] = 0x40+type;
+ memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param g: r22:r23
+ * param type: r20
+ */
+.global ubi512_init
+ubi512_init:
+ movw r26, r24
+ ldi r21, 15
+1: st X+, r1
+ dec r21
+ brne 1b
+ ori r20, 0x40
+ st X+, r20
+ ldi r21, 64
+ movw r30, r22
+2: ld r20, Z+
+ st X+, r20
+ dec r21
+ brne 2b
+ ret
+
+/******************************************************************************/
+/*
+void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
+ memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
+}
+*/
+/*
+ * param dest: r24:r24
+ * param ctx: r22:r23
+ */
+.global ubi512_ctx2hash
+ubi512_ctx2hash:
+ movw r26, r24
+ movw r30, r22
+ adiw r30, 16
+ ldi r22, 64
+1: ld r23, Z+
+ st X+, r23
+ dec r22
+ brne 1b
+ ret
+
+/******************************************************************************/
+/*
+void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
+ threefish512_ctx_t tfctx;
+ ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
+ threefish512_init(ctx->g, ctx->tweak, &tfctx);
+ memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
+ threefish512_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
+ ctx->tweak[15] &= (uint8_t)~0x40;
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ */
+CTX0 = 2
+CTX1 = 3
+BLOCK0 = 4
+BLOCK1 = 5
+TFCTX0 = 6
+TFCTX1 = 7
+.global ubi512_nextBlock
+ubi512_nextBlock:
+ stack_alloc_large 12*8
+ push_range 2, 7
+ adiw r30, 1 /* Z points to tfctx */
+ movw TFCTX0, r30
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw r26, r24
+/* add BLOCKSIZE_B (64) to tweak */
+ ldi r25, 64
+ ld r24, X
+ add r24, r25
+ st X+, r24
+ ldi r25, 11
+1: ld r24, X
+ adc r24, r1
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish512_init */
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points to ctx->g */
+ movw r20, TFCTX0
+ rcall threefish512_init
+ /* copy block to ctx->g */
+ movw r26, CTX0
+ movw r30, BLOCK0
+ ldi r25, 64
+1: ld r24, Z+
+ st X+, r24
+ dec r25
+ brne 1b
+/* call threefish512_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish512_enc
+/* xor block into ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ ldi r25, 64
+1: ld r24, X+
+ ld r23, Z
+ eor r23, r24
+ st Z+, r23
+ dec r25
+ brne 1b
+/* clear 'first' bit in tweak */
+ sbiw r30, 33
+ sbiw r30, 32
+ ld r24, Z
+ andi r24, ~0x40
+ st Z, r24
+exit:
+ pop_range 2, 7
+ stack_free_large 12*8
+ ret
+
+/******************************************************************************/
+/*
+void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
+ threefish512_ctx_t tfctx;
+ while(length_b>UBI512_BLOCKSIZE){
+ ubi512_nextBlock(ctx, block);
+ block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
+ length_b -= UBI512_BLOCKSIZE;
+ }
+ ctx->tweak[15] |= 0x80;
+ ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
+ if(length_b & 0x07)
+ ctx->tweak[14] |= 0x80;
+ threefish512_init(ctx->g, ctx->tweak, &tfctx);
+ memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
+ memcpy(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07)
+ ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
+ threefish512_enc(ctx->g, &tfctx);
+ memxor(ctx->g, block, (length_b+7)/8);
+ if(length_b & 0x07){
+ ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
+ }
+}
+*/
+/*
+ * param ctx: r24:r25
+ * param block: r22:r23
+ * param ength_b: r20:r21
+ */
+MASK_B = 8
+LEN_B = 9
+TFCTX0 = 10
+TFCTX1 = 11
+CTX0 = 12
+CTX1 = 13
+BLOCK0 = 14
+BLOCK1 = 15
+LENGTH0 = 16
+LENGTH1 = 17
+.global ubi512_lastBlock
+ubi512_lastBlock:
+/* run nextBlock for preceding blocks*/
+ push_range 8, 17
+ movw CTX0, r24
+ movw BLOCK0, r22
+ movw LENGTH0, r20
+1: cpi LENGTH1, 3
+ brlo 2f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi512_nextBlock
+ ldi r25, 64
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ subi LENGTH1, 2
+ rjmp 1b
+2: cpi LENGTH1, 2
+ brlo 3f
+ tst LENGTH0
+ breq 3f
+ movw r24, CTX0
+ movw r22, BLOCK0
+ rcall ubi512_nextBlock
+ ldi r25, 64
+ add BLOCK0, r25
+ adc BLOCK1, r1
+ subi LENGTH1, 2
+3: /* now the real fun */
+ stack_alloc_large 8*12
+ adiw r30, 1
+ movw TFCTX0, r30
+ /* calculate LEN_B */
+ movw r24, LENGTH0
+ adiw r24, 7
+ lsr r25
+ ror r24
+ lsr r25
+ ror r24
+ lsr r24
+ mov LEN_B, r24
+ /* add length to tweak */
+ movw r30, CTX0
+ ld r24, Z
+ add r24, LEN_B
+ st Z+, r24
+ ldi r25, 11
+1: ld r24, Z
+ adc r24, r1
+ st Z+, r24
+ dec r25
+ brne 1b
+ /* set 'final' bit*/
+ movw r30, CTX0
+ ldd r24, Z+15
+ ori r24, 0x80
+ std Z+15, r24
+ /* store in MASk_B if we do bit processing and set 'BitPad' bit*/
+ clr MASK_B
+ mov r24, LENGTH0
+ andi r24, 0x07
+ tst r24
+ breq 4f
+ ldd r25, Z+14
+ ori r25, 0x80
+ std Z+14, r25
+ ldi r25, 0x80
+ mov MASK_B, r25
+1: lsr MASK_B
+ dec r24
+ brne 1b
+4: /* call threefish512_init*/
+ movw r24, CTX0
+ adiw r24, 16
+ movw r22, CTX0
+ movw CTX0, r24 /* CTX points at ctx->g */
+ movw r20, TFCTX0
+ rcall threefish512_init
+ /* copy block to ctx->g */
+ movw r26, BLOCK0
+ movw r30, CTX0
+ mov r24, LEN_B
+ ldi r25, 64
+ sub r25, LEN_B
+ tst r24
+1: breq 2f
+ ld r22, X+
+ st Z+, r22
+ dec r24
+ rjmp 1b
+2: tst MASK_B
+ breq 29f
+ or r22, MASK_B
+ st -Z, r22
+ adiw r30, 1
+29: tst r25
+3: breq 4f
+ st Z+, r1
+ dec r25
+ rjmp 3b
+4: /* call threefish512_enc */
+ movw r24, CTX0
+ movw r22, TFCTX0
+ rcall threefish512_enc
+ /* xor block into ctx->g */
+ movw r30, CTX0
+ movw r26, BLOCK0
+ tst LEN_B
+5: breq 6f
+ ld r22, X+
+ ld r23, Z
+ eor r23, r22
+ st Z+, r23
+ dec LEN_B
+ rjmp 5b
+6: tst MASK_B
+ breq 7f
+ eor r23, MASK_B
+ st -Z, r23
+
+7: stack_free_large 8*12
+ pop_range 8, 17
+ ret
+
+
+++ /dev/null
-/* skein1024.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "ubi.h"
-#include "skein.h"
-
-
-void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI1024_BLOCKSIZE_B];
- memset(null, 0, UBI1024_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi1024_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi1024_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-
-void skein1024_nextBlock(skein1024_ctx_t* ctx, const void* block){
- ubi1024_nextBlock(&(ctx->ubictx), block);
-}
-
-void skein1024_lastBlock(skein1024_ctx_t* ctx, const void* block, uint16_t length_b){
- ubi1024_lastBlock(&(ctx->ubictx), block, length_b);
-}
-
-void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx){
- ubi1024_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI1024_BLOCKSIZE_B];
- ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi1024_ctx_t));
- ubi1024_lastBlock(&uctx, &counter, 64);
- ubi1024_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI1024_BLOCKSIZE){
- memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI1024_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI1024_BLOCKSIZE_B;
- outsize_b -= UBI1024_BLOCKSIZE;
- counter++;
- }
- }
-}
-
-void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
- skein1024_ctx_t ctx;
- skein1024_init(&ctx, outlength_b);
- while(length_b>SKEIN1024_BLOCKSIZE){
- skein1024_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN1024_BLOCKSIZE_B;
- length_b -= SKEIN1024_BLOCKSIZE;
- }
- skein1024_lastBlock(&ctx, msg, length_b);
- skein1024_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* skein1024_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-25
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void skein1024_init(skein1024_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI1024_BLOCKSIZE_B];
- memset(null, 0, UBI1024_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi1024_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi1024_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-*/
-/*
- * param ctx: r24:r25
- * param outsize_b: r22:r23
- */
-UBICTX0 = 2
-UBICTX1 = 3
-CONF0 = 4
-CONF1 = 5
-.global skein1024_init
-skein1024_init:
- push_range 2, 5
- stack_alloc_large 32+128-22 ; |<- 22 ->|
- adiw r30, 1 ; | CONF (32) |
- movw CONF0, r30 ; | null (128) |
- movw r26, r24
- st X+, r22
- st X+, r23
- movw UBICTX0, r26
- ldi r24, 'S'
- st Z+, r24
- ldi r24, 'H'
- st Z+, r24
- ldi r24, 'A'
- st Z+, r24
- ldi r24, '3'
- st Z+, r24
- ldi r24, 1
- st Z+, r24
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r22
- st Z+, r23
- ldi 24, 128
-1: st Z+, r1
- dec r24
- brne 1b
- /* call ubi1024_init*/
- subi r30, lo8(128)
- sbci r31, hi8(128)
- movw r24, UBICTX0
- movw r22, r30
- ldi r20, 4
- rcall ubi1024_init
- /* call ubi1024_lastBlock*/
- movw r24, UBICTX0
- movw r22, CONF0
- ldi r21, 1
- clr r20
- rcall ubi1024_lastBlock
- /* call ubi1024_init*/
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 48
- rcall ubi1024_init
- stack_free_large2 32+128-22
- pop_range 2, 5
- ret
-
-/******************************************************************************/
-.global skein1024_nextBlock
-skein1024_nextBlock:
- adiw r24, 2
- rjmp ubi1024_nextBlock
-
-/******************************************************************************/
-.global skein1024_lastBlock
-skein1024_lastBlock:
- adiw r24, 2
- rjmp ubi1024_lastBlock
-
-/******************************************************************************/
-/*
-void skein1024_ctx2hash(void* dest, skein1024_ctx_t* ctx){
- ubi1024_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI1024_BLOCKSIZE_B];
- ubi1024_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi1024_ctx_t));
- ubi1024_lastBlock(&uctx, &counter, 64);
- ubi1024_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI1024_BLOCKSIZE){
- memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI1024_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI1024_BLOCKSIZE_B;
- outsize_b -= UBI1024_BLOCKSIZE;
- counter++;
- }
- }
-}
-*/
-/*
- * param dest: r24:r25
- * param ctx: r22:r23
- */
- OUTSIZE_B0 = 16
- OUTSIZE_B1 = 17
- UCTX0 = 14
- UCTX1 = 15
- UBICTX0 = 12
- UBICTX1 = 13
- DEST0 = 10
- DEST1 = 11
-.global skein1024_ctx2hash
-skein1024_ctx2hash:
- push_range 10, 17
- /* 144 || 8 || 128 */
- stack_alloc_large 144+8+128 /* uctx || counter || outbuffer */
- movw DEST0, r24
- adiw r30, 1
- movw UCTX0, r30
- ldi r16, 144
- add r30, r16
- adc r31, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- movw r26, 22
- ld OUTSIZE_B0, X+
- ld OUTSIZE_B1, X+
- movw UBICTX0, r26
- /* call ubi1024_init */
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 63
- rcall ubi1024_init
-
- /* main loop */
- /* copy ubictx in uctx*/
-1: movw r30, UCTX0
- movw r26, UBICTX0
- ldi r24, 144
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* call ubi1024_lastBlock */
- movw r24, UCTX0
- adiw r24, 63
- adiw r24, 63
- adiw r24, 18
- movw r22, r24
- movw r24, UCTX0
- clr r21
- ldi r20, 64
- rcall ubi1024_lastBlock
- /* copy uctx->g to outbuffer */
- movw r26, UCTX0
- adiw r26, 16
- movw r30, UCTX0
- adiw r30, 63
- adiw r30, 63
- adiw r30, 18+8
- ldi r24, 128
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* compare outsize_b with 1024*/
- cpi OUTSIZE_B1, 5
- brge 5f
- cpi OUTSIZE_B1, 4
- brlo 3f
- tst OUTSIZE_B0
- breq 3f
-5: /* copy outbuffer to dest */
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 63
- adiw r26, 63
- adiw r26, 18+8
- ldi r24, 128
-6: ld r25, X+
- st Z+, r25
- dec r24
- brne 6b
- /* store new dest */
- movw DEST0, r30
- /* adjust counter and outsize_b*/
- subi OUTSIZE_B1, 2
- movw r30, UCTX0
- adiw r30, 63
- adiw r30, 63
- adiw r30, 18
- ldi r24, 1
- ld r25, Z
- add r25, r24
- st Z+, r25
- ldi r24, 7
-6: ld r25, Z
- adc r25, r1
- st Z+, r25
- dec r24
- brne 6b
- rjmp 1b
-3: /* last iteraton */
- movw r24, OUTSIZE_B0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r25
- ror r24
- lsr r25
- ror r24
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 63
- adiw r26, 63
- adiw r26, 18+8
- tst r24
- breq 8f
-7: ld r25, X+
- st Z+, r25
- dec r24
- brne 7b
-8:
- stack_free_large3 144+8+128
- pop_range 10, 17
- ret
-
-/******************************************************************************/
-/*
-void skein1024(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
- skein1024_ctx_t ctx;
- skein1024_init(&ctx, outlength_b);
- while(length_b>SKEIN1024_BLOCKSIZE){
- skein1024_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN1024_BLOCKSIZE_B;
- length_b -= SKEIN1024_BLOCKSIZE;
- }
- skein1024_lastBlock(&ctx, msg, length_b);
- skein1024_ctx2hash(dest, &ctx);
-}
-*/
-/*
- * param dest: r24:r25
- * param outlength_b: r22:r23
- * param msg: r20:r21
- * param length_b: r16:r19
- */
-LENGTH_B0 = 2
-LENGTH_B1 = 3
-LENGTH_B2 = 4
-LENGTH_B3 = 5
-DEST0 = 6
-DEST1 = 7
-MSG0 = 8
-MSG1 = 9
-CTX0 = 10
-CTX1 = 11
-.global skein1024
-skein1024:
- push_range 2, 11
- stack_alloc_large 146
- adiw r30, 1
- movw CTX0, r30
- movw DEST0, r24
- movw MSG0, r20
- movw LENGTH_B0, r16
- movw LENGTH_B2, r18
- /* call skein1024_init */
- movw r24, r30
- rcall skein1024_init
-1: tst LENGTH_B2
- brne 4f
- tst LENGTH_B3
- brne 4f
- /* call skein1024_lastBlock */
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LENGTH_B0
- rcall skein1024_lastBlock
- /* call skein1024_ctx2hash */
- movw r24, DEST0
- movw r22, CTX0
- rcall skein1024_ctx2hash
- /* return */
- stack_free_large2 146
- pop_range 2, 11
- ret
-
-4: /* process preceeding blocks */
- movw r24, CTX0
- movw r22, MSG0
- rcall skein1024_nextBlock
- ldi r24, 128
- add MSG0, r24
- adc MSG0, r1
- mov r24, LENGTH_B1
- mov r25, LENGTH_B2
- sbiw r24, 4
- sbc LENGTH_B3, r1
- mov LENGTH_B1, r24
- mov LENGTH_B2, r25
- rjmp 1b
-
+++ /dev/null
-/* skein256.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "ubi.h"
-#include "skein.h"
-
-#include "cli.h"
-
-void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI256_BLOCKSIZE_B];
- memset(null, 0, UBI256_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-
-void skein256_nextBlock(skein256_ctx_t* ctx, const void* block){
- ubi256_nextBlock(&(ctx->ubictx), block);
-}
-
-void skein256_lastBlock(skein256_ctx_t* ctx, const void* block, uint16_t length_b){
- ubi256_lastBlock(&(ctx->ubictx), block, length_b);
-}
-
-void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx){
- ubi256_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI256_BLOCKSIZE_B];
- ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
- ubi256_lastBlock(&uctx, &counter, 64);
- ubi256_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI256_BLOCKSIZE){
- memcpy(dest, outbuffer, (outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
- outsize_b -= UBI256_BLOCKSIZE;
- counter++;
- }
- }
-}
-
-void skein256(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
- skein256_ctx_t ctx;
- skein256_init(&ctx, outlength_b);
- while(length_b>SKEIN256_BLOCKSIZE){
- skein256_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
- length_b -= SKEIN256_BLOCKSIZE;
- }
- skein256_lastBlock(&ctx, msg, length_b);
- skein256_ctx2hash(dest, &ctx);
-}
+++ /dev/null
-/* skein256_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void skein256_init(skein256_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI256_BLOCKSIZE_B];
- memset(null, 0, UBI256_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-*/
-/*
- * param ctx: r24:r25
- * param outsize_b: r22:r23
- */
-UBICTX0 = 2
-UBICTX1 = 3
-CONF0 = 4
-CONF1 = 5
-.global skein256_init
-skein256_init:
- push_range 2, 5
- stack_alloc 64-22
- adiw r30, 1
- movw CONF0, r30
- movw r26, r24
- st X+, r22
- st X+, r23
- movw UBICTX0, r26
- ldi r24, 'S'
- st Z+, r24
- ldi r24, 'H'
- st Z+, r24
- ldi r24, 'A'
- st Z+, r24
- ldi r24, '3'
- st Z+, r24
- ldi r24, 1
- st Z+, r24
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r22
- st Z+, r23
- ldi 24, 22+10
-1: st Z+, r1
- dec r24
- brne 1b
- /* call ubi256_init*/
- sbiw r30, 32
- movw r24, UBICTX0
- movw r22, r30
- ldi r20, 4
- rcall ubi256_init
- /* call ubi256_lastBlock*/
- movw r24, UBICTX0
- movw r22, CONF0
- ldi r21, 1
- clr r20
- rcall ubi256_lastBlock
- /* call ubi256_init*/
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 48
- rcall ubi256_init
- stack_free 64-22
- pop_range 2, 5
- ret
-
-/******************************************************************************/
-.global skein256_nextBlock
-skein256_nextBlock:
- adiw r24, 2
- rjmp ubi256_nextBlock
-
-/******************************************************************************/
-.global skein256_lastBlock
-skein256_lastBlock:
- adiw r24, 2
- rjmp ubi256_lastBlock
-
-/******************************************************************************/
-/*
-void skein256_ctx2hash(void* dest, skein256_ctx_t* ctx){
- ubi256_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI256_BLOCKSIZE_B];
- ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
- ubi256_lastBlock(&uctx, &counter, 64);
- ubi256_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI256_BLOCKSIZE){
- memcpy(dest, outbuffer, (outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
- outsize_b -= UBI256_BLOCKSIZE;
- counter++;
- }
- }
-}
-*/
-/*
- * param dest: r24:r25
- * param ctx: r22:r23
- */
- OUTSIZE_B0 = 16
- OUTSIZE_B1 = 17
- UCTX0 = 14
- UCTX1 = 15
- UBICTX0 = 12
- UBICTX1 = 13
- DEST0 = 10
- DEST1 = 11
-.global skein256_ctx2hash
-skein256_ctx2hash:
- push_range 10, 17
- /* 48 || 8 || 32 */
- stack_alloc_large 88 /* uctx || counter || outbuffer */
- movw DEST0, r24
- adiw r30, 1
- movw UCTX0, r30
- adiw r30, 48
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- movw r26, 22
- ld OUTSIZE_B0, X+
- ld OUTSIZE_B1, X+
- movw UBICTX0, r26
- /* call ubi256_init */
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 63
- rcall ubi256_init
-
- /* main loop */
- /* copy ubictx in uctx*/
-1: movw r30, UCTX0
- movw r26, UBICTX0
- ldi r24, 48
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* call ubi256_lastBlock */
- movw r24, UCTX0
- adiw r24, 48
- movw r22, r24
- movw r24, UCTX0
- clr r21
- ldi r20, 64
- rcall ubi256_lastBlock
- /* copy uctx->g to outbuffer */
- movw r26, UCTX0
- adiw r26, 16
- movw r30, UCTX0
- adiw r30, 56
- ldi r24, 32
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* compare outsize_b with 256*/
- cpi OUTSIZE_B1, 2
- brge 5f
- cpi OUTSIZE_B1, 1
- brlo 3f
- tst OUTSIZE_B0
- breq 3f
-5: /* copy outbuffer to dest */
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 56
- ldi r24, 32
-6: ld r25, X+
- st Z+, r25
- dec r24
- brne 6b
- /* store new dest */
- movw DEST0, r30 ;XXX r26
- /* adjust counter and outsize_b*/
- dec OUTSIZE_B1
- movw r30, UCTX0
- adiw r30, 48
- ldi r24, 1
- ld r25, Z
- add r25, r24
- st Z+, r25
- ldi r24, 7
-6: ld r25, Z
- adc r25, r1
- st Z+, r25
- dec r24
- brne 6b
- rjmp 1b
-3: /* last iteraton */
- movw r24, OUTSIZE_B0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r24
- lsr r24
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 56
- tst r24
- breq 8f
-7: ld r25, X+
- st Z+, r25
- dec r24
- brne 7b
-8:
- stack_free_large 88
- pop_range 10, 17
- ret
-
-/******************************************************************************/
-/*
-void skein256(void* dest, uint16_t outlength_b, const void* msg, uint32_t length_b){
- skein256_ctx_t ctx;
- skein256_init(&ctx, outlength_b);
- while(length_b>SKEIN256_BLOCKSIZE){
- skein256_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
- length_b -= SKEIN256_BLOCKSIZE;
- }
- skein256_lastBlock(&ctx, msg, length_b);
- skein256_ctx2hash(dest, &ctx);
-}
-*/
-/*
- * param dest: r24:r25
- * param outlength_b: r22:r23
- * param msg: r20:r21
- * param length_b: r16:r19
- */
-LENGTH_B0 = 2
-LENGTH_B1 = 3
-LENGTH_B2 = 4
-LENGTH_B3 = 5
-DEST0 = 6
-DEST1 = 7
-MSG0 = 8
-MSG1 = 9
-CTX0 = 10
-CTX1 = 11
-.global skein256
-skein256:
- push_range 2, 11
- stack_alloc 50
- adiw r30, 1
- movw CTX0, r30
- movw DEST0, r24
- movw MSG0, r20
- movw LENGTH_B0, r16
- movw LENGTH_B2, r18
- /* call skein256_init */
- movw r24, r30
- rcall skein256_init
-1: tst LENGTH_B2
- brne 4f
- tst LENGTH_B3
- brne 4f
- /* call skein256_lastBlock */
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LENGTH_B0
- rcall skein256_lastBlock
- /* call skein256_ctx2hash */
- movw r24, DEST0
- movw r22, CTX0
- rcall skein256_ctx2hash
- /* return */
- stack_free 50
- pop_range 2, 11
- ret
-
-4: /* process preceeding blocks */
- movw r24, CTX0
- movw r22, MSG0
- rcall skein256_nextBlock
- movw r24, MSG0
- adiw r24, 32
- movw MSG0, r24
- mov r24, LENGTH_B1
- mov r25, LENGTH_B2
- sbiw r24, 1
- sbc LENGTH_B3, r1
- mov LENGTH_B1, r24
- mov LENGTH_B2, r25
- rjmp 1b
-
+++ /dev/null
-/* skein512.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "ubi.h"
-#include "skein.h"
-
-
-void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI512_BLOCKSIZE_B];
- memset(null, 0, UBI512_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-
-void skein512_nextBlock(skein512_ctx_t* ctx, const void* block){
- ubi512_nextBlock(&(ctx->ubictx), block);
-}
-
-void skein512_lastBlock(skein512_ctx_t* ctx, const void* block, uint16_t length_b){
- ubi512_lastBlock(&(ctx->ubictx), block, length_b);
-}
-
-void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
- ubi512_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI512_BLOCKSIZE_B];
- ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
- ubi512_lastBlock(&uctx, &counter, 64);
- ubi512_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI512_BLOCKSIZE){
- memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
- outsize_b -= UBI512_BLOCKSIZE;
- counter++;
- }
- }
-}
-
-void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
- skein512_ctx_t ctx;
- skein512_init(&ctx, outlength_b);
- while(length_b>SKEIN512_BLOCKSIZE){
- skein512_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
- length_b -= SKEIN512_BLOCKSIZE;
- }
- skein512_lastBlock(&ctx, msg, length_b);
- skein512_ctx2hash(dest, &ctx);
-}
-
+++ /dev/null
-/* skein512_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
- skein_config_t conf;
- uint8_t null[UBI512_BLOCKSIZE_B];
- memset(null, 0, UBI512_BLOCKSIZE_B);
- memset(&conf, 0, sizeof(skein_config_t));
- conf.schema[0] = 'S';
- conf.schema[1] = 'H';
- conf.schema[2] = 'A';
- conf.schema[3] = '3';
- conf.version = 1;
- conf.out_length = outsize_b;
- ctx->outsize_b = outsize_b;
- ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
- ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
- ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
-}
-*/
-/*
- * param ctx: r24:r25
- * param outsize_b: r22:r23
- */
-UBICTX0 = 2
-UBICTX1 = 3
-CONF0 = 4
-CONF1 = 5
-.global skein512_init
-skein512_init:
- push_range 2, 5
- stack_alloc_large 32+64-22 ; |<- 22 ->|
- adiw r30, 1 ; | CONF (32) |
- movw CONF0, r30 ; | null (64) |
- movw r26, r24
- st X+, r22
- st X+, r23
- movw UBICTX0, r26
- ldi r24, 'S'
- st Z+, r24
- ldi r24, 'H'
- st Z+, r24
- ldi r24, 'A'
- st Z+, r24
- ldi r24, '3'
- st Z+, r24
- ldi r24, 1
- st Z+, r24
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r22
- st Z+, r23
- ldi 24, 64
-1: st Z+, r1
- dec r24
- brne 1b
- /* call ubi512_init*/
- sbiw r30, 63
- sbiw r30, 1
- movw r24, UBICTX0
- movw r22, r30
- ldi r20, 4
- rcall ubi512_init
- /* call ubi512_lastBlock*/
- movw r24, UBICTX0
- movw r22, CONF0
- ldi r21, 1
- clr r20
- rcall ubi512_lastBlock
- /* call ubi512_init*/
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 48
- rcall ubi512_init
- stack_free_large 32+64-22
- pop_range 2, 5
- ret
-
-/******************************************************************************/
-.global skein512_nextBlock
-skein512_nextBlock:
- adiw r24, 2
- rjmp ubi512_nextBlock
-
-/******************************************************************************/
-.global skein512_lastBlock
-skein512_lastBlock:
- adiw r24, 2
- rjmp ubi512_lastBlock
-
-/******************************************************************************/
-/*
-void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
- ubi512_ctx_t uctx;
- uint16_t outsize_b;
-
- uint64_t counter=0;
- uint8_t outbuffer[UBI512_BLOCKSIZE_B];
- ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
-
- outsize_b = ctx->outsize_b;
- while(1){
- memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
- ubi512_lastBlock(&uctx, &counter, 64);
- ubi512_ctx2hash(outbuffer, &uctx);
- if(outsize_b<=UBI512_BLOCKSIZE){
- memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
- break;
- }else{
- memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
- dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
- outsize_b -= UBI512_BLOCKSIZE;
- counter++;
- }
- }
-}
-*/
-/*
- * param dest: r24:r25
- * param ctx: r22:r23
- */
- OUTSIZE_B0 = 16
- OUTSIZE_B1 = 17
- UCTX0 = 14
- UCTX1 = 15
- UBICTX0 = 12
- UBICTX1 = 13
- DEST0 = 10
- DEST1 = 11
-.global skein512_ctx2hash
-skein512_ctx2hash:
- push_range 10, 17
- /* 80 || 8 || 64 */
- stack_alloc_large 80+8+64 /* uctx || counter || outbuffer */
- movw DEST0, r24
- adiw r30, 1
- movw UCTX0, r30
- adiw r30, 63
- adiw r30, 17
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- st Z+, r1
- movw r26, 22
- ld OUTSIZE_B0, X+
- ld OUTSIZE_B1, X+
- movw UBICTX0, r26
- /* call ubi512_init */
- movw r24, UBICTX0
- adiw r24, 16
- movw r22, r24
- movw r24, UBICTX0
- ldi r20, 63
- rcall ubi512_init
-
- /* main loop */
- /* copy ubictx in uctx*/
-1: movw r30, UCTX0
- movw r26, UBICTX0
- ldi r24, 80
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* call ubi512_lastBlock */
- movw r24, UCTX0
- adiw r24, 63
- adiw r24, 17
- movw r22, r24
- movw r24, UCTX0
- clr r21
- ldi r20, 64
- rcall ubi512_lastBlock
- /* copy uctx->g to outbuffer */
- movw r26, UCTX0
- adiw r26, 16
- movw r30, UCTX0
- adiw r30, 63
- adiw r30, 17+8
- ldi r24, 64
-2: ld r25, X+
- st Z+, r25
- dec r24
- brne 2b
- /* compare outsize_b with 512*/
- cpi OUTSIZE_B1, 3
- brge 5f
- cpi OUTSIZE_B1, 2
- brlo 3f
- tst OUTSIZE_B0
- breq 3f
-5: /* copy outbuffer to dest */
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 63
- adiw r26, 17+8
- ldi r24, 64
-6: ld r25, X+
- st Z+, r25
- dec r24
- brne 6b
- /* store new dest */
- movw DEST0, r30
- /* adjust counter and outsize_b*/
- subi OUTSIZE_B1, 2
- movw r30, UCTX0
- adiw r30, 63
- adiw r30, 17
- ldi r24, 1
- ld r25, Z
- add r25, r24
- st Z+, r25
- ldi r24, 7
-6: ld r25, Z
- adc r25, r1
- st Z+, r25
- dec r24
- brne 6b
- rjmp 1b
-3: /* last iteraton */
- movw r24, OUTSIZE_B0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r25
- ror r24
- lsr r24
- movw r30, DEST0
- movw r26, UCTX0
- adiw r26, 63
- adiw r26, 17+8
- tst r24
- breq 8f
-7: ld r25, X+
- st Z+, r25
- dec r24
- brne 7b
-8:
- stack_free_large2 80+8+64
- pop_range 10, 17
- ret
-
-/******************************************************************************/
-/*
-void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
- skein512_ctx_t ctx;
- skein512_init(&ctx, outlength_b);
- while(length_b>SKEIN512_BLOCKSIZE){
- skein512_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
- length_b -= SKEIN512_BLOCKSIZE;
- }
- skein512_lastBlock(&ctx, msg, length_b);
- skein512_ctx2hash(dest, &ctx);
-}
-*/
-/*
- * param dest: r24:r25
- * param outlength_b: r22:r23
- * param msg: r20:r21
- * param length_b: r16:r19
- */
-LENGTH_B0 = 2
-LENGTH_B1 = 3
-LENGTH_B2 = 4
-LENGTH_B3 = 5
-DEST0 = 6
-DEST1 = 7
-MSG0 = 8
-MSG1 = 9
-CTX0 = 10
-CTX1 = 11
-.global skein512
-skein512:
- push_range 2, 11
- stack_alloc_large 82
- adiw r30, 1
- movw CTX0, r30
- movw DEST0, r24
- movw MSG0, r20
- movw LENGTH_B0, r16
- movw LENGTH_B2, r18
- /* call skein512_init */
- movw r24, r30
- rcall skein512_init
-1: tst LENGTH_B2
- brne 4f
- tst LENGTH_B3
- brne 4f
- /* call skein512_lastBlock */
- movw r24, CTX0
- movw r22, MSG0
- movw r20, LENGTH_B0
- rcall skein512_lastBlock
- /* call skein512_ctx2hash */
- movw r24, DEST0
- movw r22, CTX0
- rcall skein512_ctx2hash
- /* return */
- stack_free_large 82
- pop_range 2, 11
- ret
-
-4: /* process preceeding blocks */
- movw r24, CTX0
- movw r22, MSG0
- rcall skein512_nextBlock
- ldi r24, 64
- add MSG0, r24
- adc MSG0, r1
- mov r24, LENGTH_B1
- mov r25, LENGTH_B2
- sbiw r24, 2
- sbc LENGTH_B3, r1
- mov LENGTH_B1, r24
- mov LENGTH_B2, r25
- rjmp 1b
-
#define UART0_DATABITS UART_DATABITS_8
#define UART0_RXBUFFER_SIZE 64
#define UART0_TXBUFFER_SIZE 64
-#define UART0_SWFLOWCTRL 0
+#define UART0_SWFLOWCTRL 1
#define UART0_THRESH_LOW 10
#define UART0_THRESH_HIGH 48
+++ /dev/null
-/* hexdigit_tab.c */
-/*
- * This file is part of AnonAccess, an access system which can be used
- * to open door or doing other things with an anonymity featured
- * account managment.
- * Copyright (C) 2006, 2007, 2008 Daniel Otte (daniel.otte@rub.de)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-
-#include <avr/pgmspace.h>
-#include "hexdigit_tab.h"
-
-char hexdigit_tab_P[] PROGMEM =
- {'0','1','2','3',
- '4','5','6','7',
- '8','9','A','B',
- 'C','D','E','F'};
-
-char hexdigit_tab_uc_P[] PROGMEM =
- {'0','1','2','3',
- '4','5','6','7',
- '8','9','A','B',
- 'C','D','E','F'};
-
-
-char hexdigit_tab_lc_P[] PROGMEM =
- {'0','1','2','3',
- '4','5','6','7',
- '8','9','a','b',
- 'c','d','e','f'};
-
-
-
-
-
#include "uart_i.h"
#include "debug.h"
-#include "aes.h"
-#include "aes128_enc.h"
-#include "aes128_dec.h"
-#include "aes192_enc.h"
-#include "aes192_dec.h"
-#include "aes256_enc.h"
-#include "aes256_dec.h"
-#include "aes_keyschedule.h"
+#include "aes/aes.h"
+#include "aes/aes128_enc.h"
+#include "aes/aes128_dec.h"
+#include "aes/aes192_enc.h"
+#include "aes/aes192_dec.h"
+#include "aes/aes256_enc.h"
+#include "aes/aes256_dec.h"
+#include "aes/aes_keyschedule.h"
#include "nessie_bc_test.h"
#include "cli.h"
#include "uart_i.h"
#include "debug.h"
-#include "aes.h"
-#include "aes128_enc.h"
-#include "aes128_dec.h"
-#include "aes_keyschedule.h"
+#include "aes/aes.h"
+#include "aes/aes128_enc.h"
+#include "aes/aes128_dec.h"
+#include "aes/aes_keyschedule.h"
#include "nessie_bc_test.h"
#include "cli.h"
#include "uart_i.h"
#include "debug.h"
-#include "aes.h"
-#include "aes192_enc.h"
-#include "aes192_dec.h"
-#include "aes_keyschedule.h"
+#include "aes/aes.h"
+#include "aes/aes192_enc.h"
+#include "aes/aes192_dec.h"
+#include "aes/aes_keyschedule.h"
#include "nessie_bc_test.h"
#include "cli.h"
#include "uart_i.h"
#include "debug.h"
-#include "aes.h"
-#include "aes256_enc.h"
-#include "aes256_dec.h"
-#include "aes_keyschedule.h"
+#include "aes/aes.h"
+#include "aes/aes256_enc.h"
+#include "aes/aes256_dec.h"
+#include "aes/aes_keyschedule.h"
#include "nessie_bc_test.h"
#include "cli.h"
+++ /dev/null
-/* threefish.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \file threefish.h
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- * \brief Implementation of the Threefish block cipher
- * \ingroup Threefish
- */
-
-#ifndef THREEFISH_H_
-#define THREEFISH_H_
-
-#include <stdint.h>
-
-#define THREEFISH256_BLOCKSIZE 256
-#define THREEFISH256_BLOCKSIZE_B ((THREEFISH256_BLOCKSIZE+7)/8)
-#define THREEFISH512_BLOCKSIZE 512
-#define THREEFISH512_BLOCKSIZE_B ((THREEFISH512_BLOCKSIZE+7)/8)
-#define THREEFISH1024_BLOCKSIZE 1024
-#define THREEFISH1024_BLOCKSIZE_B ((THREEFISH1024_BLOCKSIZE+7)/8)
-
-/** \typedef threefish256_ctx_t
- * \brief holds key data for Threefish-256
- *
- * A variable of this type may hold the key data for Threefish-256 encryption
- * or decryption..
- */
-typedef struct{
- uint64_t k[5];
- uint64_t t[3];
-} threefish256_ctx_t;
-
-/** \typedef threefish512_ctx_t
- * \brief holds key data for Threefish-512
- *
- * A variable of this type may hold the key data for Threefish-512 encryption
- * or decryption..
- */
-typedef struct{
- uint64_t k[9];
- uint64_t t[3];
-} threefish512_ctx_t;
-
-/** \typedef threefish1024_ctx_t
- * \brief holds key data for Threefish-1024
- *
- * A variable of this type may hold the key data for Threefish-1024 encryption
- * or decryption..
- */
-typedef struct{
- uint64_t k[17];
- uint64_t t[3];
-} threefish1024_ctx_t;
-
-
-void threefish_mix(void* data, uint8_t rot);
-void threefish_invmix(void* data, uint8_t rot);
-
-void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx);
-void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx);
-void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx);
-
-void threefish256_enc(void* data, const threefish256_ctx_t* ctx);
-void threefish512_enc(void* data, const threefish512_ctx_t* ctx);
-void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx);
-
-void threefish256_dec(void* data, const threefish256_ctx_t* ctx);
-void threefish512_dec(void* data, const threefish512_ctx_t* ctx);
-void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx);
-
-#endif /* THREEFISH_H_ */
+++ /dev/null
-/* threefish1024_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-#define X(a) (((uint64_t*)data)[(a)])
-
-static
-void permute_inv16(void* data){
- uint64_t t;
- t = X(15);
- X(15) = X(7);
- X(7) = X(9);
- X(9) = X(1);
- X(1) = t;
- t = X(11);
- X(11) = X(5);
- X(5) = X(13);
- X(13) = X(3);
- X(3) = t;
- t = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(14);
- X(14) = X(12);
- X(12) = X(10);
- X(10) = X(8);
- X(8) = t;
-}
-
-static
-void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<13; ++i){
- X(i) -= ctx->k[(s+i)%17];
- }
- X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
- X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
- X(15) -= ctx->k[(s+15)%17] + s;
-}
-
-void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
- uint8_t i=0,s=20;
- uint8_t r0[8] = {47, 58, 17, 28, 34, 33, 25, 55};
- uint8_t r1[8] = {49, 7, 6, 7, 43, 8, 25, 43};
- uint8_t r2[8] = {27, 32, 18, 47, 25, 18, 46, 37};
- uint8_t r3[8] = {58, 45, 25, 48, 60, 57, 13, 40};
- uint8_t r4[8] = {37, 19, 43, 51, 44, 21, 14, 16};
- uint8_t r5[8] = {48, 18, 42, 9, 9, 12, 13, 22};
- uint8_t r6[8] = {53, 2, 40, 35, 59, 32, 52, 38};
- uint8_t r7[8] = {56, 56, 15, 41, 34, 54, 57, 12};
- do{
- if(i%4==0){
- add_key_16(data, ctx, s);
- --s;
- }
- permute_inv16(data);
- threefish_invmix((uint8_t*)data + 0, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- threefish_invmix((uint8_t*)data + 32, r2[i%8]);
- threefish_invmix((uint8_t*)data + 48, r3[i%8]);
- threefish_invmix((uint8_t*)data + 64, r4[i%8]);
- threefish_invmix((uint8_t*)data + 80, r5[i%8]);
- threefish_invmix((uint8_t*)data + 96, r6[i%8]);
- threefish_invmix((uint8_t*)data +112, r7[i%8]);
- ++i;
- }while(i!=80);
- add_key_16(data, ctx, s);
-}
+++ /dev/null
-/* threefish1024_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-24
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void permute_inv16(void* data){
- uint64_t t;
- t = X(15);
- X(15) = X(7);
- X(7) = X(9);
- X(9) = X(1);
- X(1) = t;
- t = X(11);
- X(11) = X(5);
- X(5) = X(13);
- X(13) = X(3);
- X(3) = t;
- t = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(14);
- X(14) = X(12);
- X(12) = X(10);
- X(10) = X(8);
- X(8) = t;
-}
-void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<13; ++i){
- X(i) -= ctx->k[(s+i)%17];
- }
- X(13) -= ctx->k[(s+13)%17] + ctx->t[s%3];
- X(14) -= ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
- X(15) -= ctx->k[(s+15)%17] + s;
-}
-void threefish1024_dec(void* data, const threefish1024_ctx_t* ctx){
- uint8_t i=0,s=20;
- uint8_t r0[8] = {0x69, 0x72, 0x21, 0x34, 0x42, 0x41, 0x31, 0x79};
- uint8_t r1[8] = {0x61, 0x19, 0x1a, 0x19, 0x53, 0x10, 0x31, 0x53};
- uint8_t r2[8] = {0x33, 0x40, 0x22, 0x69, 0x31, 0x22, 0x6a, 0x5b};
- uint8_t r3[8] = {0x72, 0x6b, 0x31, 0x60, 0x74, 0x71, 0x2b, 0x50};
- uint8_t r4[8] = {0x5b, 0x23, 0x53, 0x63, 0x54, 0x3b, 0x2a, 0x20};
- uint8_t r5[8] = {0x60, 0x22, 0x52, 0x11, 0x11, 0x14, 0x2b, 0x3a};
- uint8_t r6[8] = {0x7b, 0x02, 0x50, 0x43, 0x73, 0x40, 0x64, 0x5a};
- uint8_t r7[8] = {0x70, 0x70, 0x29, 0x51, 0x42, 0x7a, 0x71, 0x14};
-
- do{
- if(i%4==0){
- add_key_16(data, ctx, s);
- --s;
- }
- permute_inv16(data);
- threefish_invmix((uint8_t*)data + 0, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- threefish_invmix((uint8_t*)data + 32, r2[i%8]);
- threefish_invmix((uint8_t*)data + 48, r3[i%8]);
- threefish_invmix((uint8_t*)data + 64, r4[i%8]);
- threefish_invmix((uint8_t*)data + 80, r5[i%8]);
- threefish_invmix((uint8_t*)data + 96, r6[i%8]);
- threefish_invmix((uint8_t*)data +112, r7[i%8]);
- ++i;
- }while(i!=80);
- add_key_16(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-IDX4 = 12
-IDX5 = 13
-IDX6 = 14
-IDX7 = 15
-
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish1024_dec
-threefish1024_dec:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- ldi r26, 20
- mov S, r26
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish1024_slut17)
- ldi r31, hi8(threefish1024_slut17)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall sub_z_from_x8
- /* second half */
- ldi r30, lo8(threefish1024_slut17)
- ldi r31, hi8(threefish1024_slut17)
- add r30, S
- adc r31, r1
- adiw r30, 8
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall sub_z_from_x8
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish1024_slut3)
- ldi r31, hi8(threefish1024_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 7*8 /* make Z pointing to (extended tweak) */
- adiw r30, 7*8
- adiw r30, 3*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- ld r0, X
- sub r0, S
- 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
- ld r0, X
- sbc r0, r1
- st X+, r0
- tst S
- brne 3f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-3:
- dec S
-4:
- /* now the permutation */
- movw r26, DATA0 /* X1 <-> X15 */
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8+4
- adiw r30, 7*8+4
- rcall xchg_zx8
- movw r26, DATA0 /* X15 <-> X7 */
- adiw r26, 7*8+4
- adiw r26, 7*8+4
- movw r30, DATA0
- adiw r30, 7*8
- rcall xchg_zx8
- movw r26, DATA0 /* X9 <-> X7 */
- adiw r26, 7*8
- adiw r26, 2*8
- movw r30, DATA0
- adiw r30, 7*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X3 <-> X11 */
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 4*8
- rcall xchg_zx8
- movw r26, DATA0 /* X11 <-> X5 */
- adiw r26, 7*8
- adiw r26, 4*8
- movw r30, DATA0
- adiw r30, 5*8
- rcall xchg_zx8
- movw r26, DATA0 /* X13 <-> X5 */
- adiw r26, 7*8
- adiw r26, 6*8
- movw r30, DATA0
- adiw r30, 5*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X8 <-> X14 */
- adiw r26, 7*8
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 7*8
- rcall xchg_zx8
- movw r26, DATA0 /* X14 <-> X12 */
- adiw r26, 7*8
- adiw r26, 7*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 5*8
- rcall xchg_zx8
- movw r26, DATA0 /* X10 <-> X12 */
- adiw r26, 7*8
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 5*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X4 <-> X6 */
- adiw r26, 4*8
- movw r30, DATA0
- adiw r30, 6*8
- rcall xchg_zx8
-
- /* call mix */
- ldi r30, lo8(threefish1024_rc0)
- ldi r31, hi8(threefish1024_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- adiw r30, 8
- lpm IDX1, Z
- adiw r30, 8
- lpm IDX2, Z
- adiw r30, 8
- lpm IDX3, Z
- adiw r30, 8
- lpm IDX4, Z
- adiw r30, 8
- lpm IDX5, Z
- adiw r30, 8
- lpm IDX6, Z
- push IDX6
- push IDX5
- push IDX4
- push IDX3
- push IDX2
-
- movw r24, DATA0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 32
- mov r22, IDX1
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 48
- pop r22
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 1
- pop r22
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 17
- pop r22
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 33
- pop r22
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 49
- pop r22
- call threefish_invmix_asm /* no rcall? */
- inc I
-9:
- rjmp 1b
-
-threefish1024_slut17:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
- .byte 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78
- .byte 0x80, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
- .byte 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70
- .byte 0x78, 0x80, 0x00, 0x08, 0x10
-threefish1024_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10
- .byte 0x00
-
-threefish1024_rc0: .byte 0x69, 0x72, 0x21, 0x34, 0x42, 0x41, 0x31, 0x79
-threefish1024_rc1: .byte 0x61, 0x19, 0x1a, 0x19, 0x53, 0x10, 0x31, 0x53
-threefish1024_rc2: .byte 0x33, 0x40, 0x22, 0x69, 0x31, 0x22, 0x6a, 0x5b
-threefish1024_rc3: .byte 0x72, 0x6b, 0x31, 0x60, 0x74, 0x71, 0x2b, 0x50
-threefish1024_rc4: .byte 0x5b, 0x23, 0x53, 0x63, 0x54, 0x3b, 0x2a, 0x20
-threefish1024_rc5: .byte 0x60, 0x22, 0x52, 0x11, 0x11, 0x14, 0x2b, 0x3a
-threefish1024_rc6: .byte 0x7b, 0x02, 0x50, 0x43, 0x73, 0x40, 0x64, 0x5a
-threefish1024_rc7: .byte 0x70, 0x70, 0x29, 0x51, 0x42, 0x7a, 0x71, 0x14
-
-sub_z_from_x8:
- ld r0, Z+
- ld r1, X
- sub r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- clr r1
- ret
-
-T0 = IDX0
-T1 = 0
-CNT = 24
-xchg_zx8:
- ldi CNT, 8
-1: ld T0, X
- ld T1, Z
- st X+, T1
- st Z+, T0
- dec CNT
- brne 1b
- ret
-
-
-
+++ /dev/null
-/* threefish1024_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-#define X(a) (((uint64_t*)data)[(a)])
-
-static
-void permute_16(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(9);
- X(9) = X(7);
- X(7) = X(15);
- X(15) = t;
- t = X(3);
- X(3) = X(13);
- X(13) = X(5);
- X(5) = X(11);
- X(11) = t;
- t = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(8);
- X(8) = X(10);
- X(10) = X(12);
- X(12) = X(14);
- X(14) = t;
-}
-
-#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-void threefish1024_init(const void* key, const void* tweak, threefish1024_ctx_t* ctx){
- memcpy(ctx->k, key, 16*8);
- if(tweak){
- memcpy(ctx->t, tweak, 2*8);
- ctx->t[2] = T(0) ^ T(1);
- }else{
- memset(ctx, 0, 3*8);
- }
- uint8_t i;
- ctx->k[16] = THREEFISH_KEY_CONST;
- for(i=0; i<16; ++i){
- ctx->k[16] ^= K(i);
- }
-}
-
-static
-void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<13; ++i){
- X(i) += ctx->k[(s+i)%17];
- }
- X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
- X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
- X(15) += ctx->k[(s+15)%17] + s;
-}
-
-void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
- uint8_t r1[8] = {43, 25, 8, 43, 7, 6, 7, 49};
- uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
- uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
- uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
- uint8_t r5[8] = {22, 13, 12, 9, 9, 42, 18, 48};
- uint8_t r6[8] = {38, 52, 32, 59, 35, 40, 2, 53};
- uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
-
- do{
- if(i%4==0){
- add_key_16(data, ctx, s);
- ++s;
- }
- threefish_mix((uint8_t*)data + 0, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- threefish_mix((uint8_t*)data + 32, r2[i%8]);
- threefish_mix((uint8_t*)data + 48, r3[i%8]);
- threefish_mix((uint8_t*)data + 64, r4[i%8]);
- threefish_mix((uint8_t*)data + 80, r5[i%8]);
- threefish_mix((uint8_t*)data + 96, r6[i%8]);
- threefish_mix((uint8_t*)data +112, r7[i%8]);
- permute_16(data);
- ++i;
- }while(i!=80);
- add_key_16(data, ctx, s);
-}
+++ /dev/null
-/* threefish1024_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-24
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-A0 = 14
-A1 = 15
-A2 = 16
-A3 = 17
-A4 = 18
-A5 = 19
-A6 = 20
-A7 = 21
-/*
-#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-void threefish1024_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
- memcpy(ctx->k, key, 16*8);
- memcpy(ctx->t, tweak, 2*8);
- uint8_t i;
- ctx->k[16] = THREEFISH_KEY_CONST;
- for(i=0; i<8; ++i){
- ctx->k[16] ^= K(i);
- }
- ctx->t[2] = T(0) ^ T(1);
-}
-*/
-/*
- * param key: r24:r25
- * param tweak: r22:r23
- * param ctx: r20:r21
- */
-.global threefish1024_init
-threefish1024_init:
- push_range 14, 17
- movw r30, r20
- movw r26, r24
- ldi r24, 16
- ldi A7, 0x55
- mov A6, A7
- movw A4, A6
- movw A2, A6
- movw A0, A6
-1:
- ld r0, X+
- st Z+, r0
- eor A0, r0
- ld r0, X+
- st Z+, r0
- eor A1, r0
- ld r0, X+
- st Z+, r0
- eor A2, r0
- ld r0, X+
- st Z+, r0
- eor A3, r0
- ld r0, X+
- st Z+, r0
- eor A4, r0
- ld r0, X+
- st Z+, r0
- eor A5, r0
- ld r0, X+
- st Z+, r0
- eor A6, r0
- ld r0, X+
- st Z+, r0
- eor A7, r0
- dec r24
- brne 1b
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- /* now the tweak */
- movw r26, r22
- tst r27
- brne 3f
- tst r26
- brne 3f
- ldi r26, 3*8
-1:
- st Z+, r1
- dec r26
- brne 1b
- rjmp 9f
-3:
- ld A0, X+
- ld A1, X+
- ld A2, X+
- ld A3, X+
- ld A4, X+
- ld A5, X+
- ld A6, X+
- ld A7, X+
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- ld r0, X+
- eor A0, r0
- st Z+, r0
- ld r0, X+
- eor A1, r0
- st Z+, r0
- ld r0, X+
- eor A2, r0
- st Z+, r0
- ld r0, X+
- eor A3, r0
- st Z+, r0
- ld r0, X+
- eor A4, r0
- st Z+, r0
- ld r0, X+
- eor A5, r0
- st Z+, r0
- ld r0, X+
- eor A6, r0
- st Z+, r0
- ld r0, X+
- eor A7, r0
- st Z+, r0
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
-9:
- pop_range 14, 17
- ret
-
-/******************************************************************************/
-/*
-#define X(a) (((uint64_t*)data)[(a)])
-void permute_16(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(9);
- X(9) = X(7);
- X(7) = X(15);
- X(15) = t;
- t = X(3);
- X(3) = X(13);
- X(13) = X(5);
- X(5) = X(11);
- X(11) = t;
- t = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(8);
- X(8) = X(10);
- X(10) = X(12);
- X(12) = X(14);
- X(14) = t;
-}
-void add_key_16(void* data, const threefish1024_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<13; ++i){
- X(i) += ctx->k[(s+i)%17];
- }
- X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
- X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
- X(15) += ctx->k[(s+15)%17] + s;
-}
-void threefish1024_enc(void* data, const threefish1024_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
- uint8_t r1[8] = {43, 25, 8, 43, 7, 6, 7, 49};
- uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
- uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
- uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
- uint8_t r5[8] = {22, 13, 12, 9, 9, 42, 18, 48};
- uint8_t r6[8] = {38, 52, 32, 59, 35, 40, 2, 53};
- uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
- do{
- if(i%4==0){
- add_key_16(data, ctx, s);
- ++s;
- }
- threefish_mix((uint8_t*)data + 0, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- threefish_mix((uint8_t*)data + 32, r2[i%8]);
- threefish_mix((uint8_t*)data + 48, r3[i%8]);
- threefish_mix((uint8_t*)data + 64, r4[i%8]);
- threefish_mix((uint8_t*)data + 80, r5[i%8]);
- threefish_mix((uint8_t*)data + 96, r6[i%8]);
- threefish_mix((uint8_t*)data +112, r7[i%8]);
- permute_16(data);
- ++i;
- }while(i!=80);
- add_key_16(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-IDX4 = 12
-IDX5 = 13
-IDX6 = 14
-IDX7 = 15
-
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish1024_enc
-threefish1024_enc:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- clr S
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish1024_slut17)
- ldi r31, hi8(threefish1024_slut17)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall add_z_to_x8
- /* second half */
- ldi r30, lo8(threefish1024_slut17)
- ldi r31, hi8(threefish1024_slut17)
- add r30, S
- adc r31, r1
- adiw r30, 8
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall add_z_to_x8
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish1024_slut3)
- ldi r31, hi8(threefish1024_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 7*8 /* make Z pointing to (extended tweak) */
- adiw r30, 7*8
- adiw r30, 3*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- ld r0, X
- add r0, S
- 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
- inc S
- mov r26, S
- cpi r26, 21
- brmi 4f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-4:
- /* call mix */
- ldi r30, lo8(threefish1024_rc0)
- ldi r31, hi8(threefish1024_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- adiw r30, 8
- lpm IDX1, Z
- adiw r30, 8
- lpm IDX2, Z
- adiw r30, 8
- lpm IDX3, Z
- adiw r30, 8
- lpm IDX4, Z
- adiw r30, 8
- lpm IDX5, Z
- adiw r30, 8
- lpm IDX6, Z
- push IDX6
- push IDX5
- push IDX4
- push IDX3
- push IDX2
-
- movw r24, DATA0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 32
- mov r22, IDX1
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 48
- pop r22
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 1
- pop r22
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 17
- pop r22
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 33
- pop r22
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 63
- adiw r24, 49
- pop r22
- call threefish_mix_asm /* no rcall? */
- /* now the permutation */
- movw r26, DATA0 /* X1 <-> X15 */
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8+4
- adiw r30, 7*8+4
- rcall xchg_zx8
- movw r26, DATA0 /* X1 <-> X9 */
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 2*8
- rcall xchg_zx8
- movw r26, DATA0 /* X9 <-> X7 */
- adiw r26, 7*8
- adiw r26, 2*8
- movw r30, DATA0
- adiw r30, 7*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X3 <-> X11 */
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 4*8
- rcall xchg_zx8
- movw r26, DATA0 /* X3 <-> X13 */
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 6*8
- rcall xchg_zx8
- movw r26, DATA0 /* X13 <-> X5 */
- adiw r26, 7*8
- adiw r26, 6*8
- movw r30, DATA0
- adiw r30, 5*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X8 <-> X14 */
- adiw r26, 7*8
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 7*8
- rcall xchg_zx8
- movw r26, DATA0 /* X8 <-> X10 */
- adiw r26, 7*8
- adiw r26, 1*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 3*8
- rcall xchg_zx8
- movw r26, DATA0 /* X10 <-> X12 */
- adiw r26, 7*8
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- adiw r30, 5*8
- rcall xchg_zx8
- /* --- */
- movw r26, DATA0 /* X4 <-> X6 */
- adiw r26, 4*8
- movw r30, DATA0
- adiw r30, 6*8
- rcall xchg_zx8
-
- inc I
-; mov r26, I
-; cpi r26, 5
-; brne 9f
-; rjmp exit
-9:
- rjmp 1b
-
-threefish1024_slut17:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
- .byte 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78
- .byte 0x80, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
- .byte 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70
- .byte 0x78, 0x80, 0x00, 0x08, 0x10
-threefish1024_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10
- .byte 0x00
-threefish1024_rc0: .byte 0x79, 0x31, 0x41, 0x42, 0x34, 0x21, 0x72, 0x69
-threefish1024_rc1: .byte 0x53, 0x31, 0x10, 0x53, 0x19, 0x1a, 0x19, 0x61
-threefish1024_rc2: .byte 0x5b, 0x6a, 0x22, 0x31, 0x69, 0x22, 0x40, 0x33
-threefish1024_rc3: .byte 0x50, 0x2b, 0x71, 0x74, 0x60, 0x31, 0x6b, 0x72
-threefish1024_rc4: .byte 0x20, 0x2a, 0x3b, 0x54, 0x63, 0x53, 0x23, 0x5b
-threefish1024_rc5: .byte 0x3a, 0x2b, 0x14, 0x11, 0x11, 0x52, 0x22, 0x60
-threefish1024_rc6: .byte 0x5a, 0x64, 0x40, 0x73, 0x43, 0x50, 0x02, 0x7b
-threefish1024_rc7: .byte 0x14, 0x71, 0x7a, 0x42, 0x51, 0x29, 0x70, 0x70
-
-add_z_to_x8:
- ld r0, Z+
- ld r1, X
- add r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- clr r1
- ret
-
-T0 = IDX0
-T1 = 0
-CNT = 24
-xchg_zx8:
- ldi CNT, 8
-1: ld T0, X
- ld T1, Z
- st X+, T1
- st Z+, T0
- dec CNT
- brne 1b
- ret
-
-
-
+++ /dev/null
-/* threefish256_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-#define X(a) (((uint64_t*)data)[(a)])
-static
-void permute_4(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(3);
- X(3) = t;
-}
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-static
-void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
- X(0) -= ctx->k[(s+0)%5];
- X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
- X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
- X(3) -= ctx->k[(s+3)%5] + s;
-}
-
-void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
- uint8_t i=0,s=18;
- uint8_t r0[8] = {59, 11, 53, 26, 58, 13, 36, 5};
- uint8_t r1[8] = {50, 42, 35, 20, 44, 46, 28, 56};
- do{
- if(i%4==0){
- add_key_4(data, ctx, s);
- --s;
- }
- permute_4(data);
- threefish_invmix(data, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- ++i;
- }while(i!=72);
- add_key_4(data, ctx, s);
-}
-
+++ /dev/null
-/* threefish256_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void permute_4(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(3);
- X(3) = t;
-}
-void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
- X(0) -= ctx->k[(s+0)%5];
- X(1) -= ctx->k[(s+1)%5] + ctx->t[s%3];
- X(2) -= ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
- X(3) -= ctx->k[(s+3)%5] + s;
-}
-void threefish256_dec(void* data, const threefish256_ctx_t* ctx){
- uint8_t i=0,s=18;
- uint8_t r0[8] = {0x73, 0x13, 0x7b, 0x32, 0x72, 0x2b, 0x44, 0x1b};
- uint8_t r1[8] = {0x62, 0x52, 0x43, 0x24, 0x54, 0x6a, 0x34, 0x70};
- do{
- if(i%4==0){
- add_key_4(data, ctx, s);
- --s;
- }
- permute_4(data);
- threefish_invmix(data, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- ++i;
- }while(i!=72);
- add_key_4(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish256_dec
-threefish256_dec:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- ldi r26, 18
- mov S, r26
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish256_slut5)
- ldi r31, hi8(threefish256_slut5)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall sub_z_from_x8
-
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish256_slut3)
- ldi r31, hi8(threefish256_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 5*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- ld r0, X
- sub r0, S
- 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
- ld r0, X
- sbc r0, r1
- st X+, r0
- tst S
- brne 3f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-3:
- dec S
-4:
- /* now the permutation */
- movw r26, DATA0
- adiw r26, 8
- movw r30, r26
- adiw r30, 16
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- /* call mix */
- ldi r30, lo8(threefish256_rc0)
- ldi r31, hi8(threefish256_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- movw r24, DATA0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_invmix_asm /* no rcall? */
- inc I
- rjmp 1b
-
-threefish256_slut5:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
- .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
- .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
-threefish256_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
-
-threefish256_rc0: .byte 0x73, 0x13, 0x7b, 0x32, 0x72, 0x2b, 0x44, 0x1b
-threefish256_rc1: .byte 0x62, 0x52, 0x43, 0x24, 0x54, 0x6a, 0x34, 0x70
-
-sub_z_from_x8:
- ld r0, Z+
- ld r1, X
- sub r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- clr r1
- ret
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* threefish256_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-#define X(a) (((uint64_t*)data)[(a)])
-static
-void permute_4(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(3);
- X(3) = t;
-}
-
-#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-void threefish256_init(const void* key, const void* tweak, threefish256_ctx_t* ctx){
- memcpy(ctx->k, key, 4*8);
- if(tweak){
- memcpy(ctx->t, tweak, 2*8);
- ctx->t[2] = T(0) ^ T(1);
- }else{
- memset(ctx->t, 0, 3*8);
- }
- uint8_t i;
- ctx->k[4] = THREEFISH_KEY_CONST;
- for(i=0; i<4; ++i){
- ctx->k[4] ^= K(i);
- }
-}
-
-static
-void add_key_4(void* data, const threefish256_ctx_t* ctx, uint8_t s){
- X(0) += ctx->k[(s+0)%5];
- X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
- X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
- X(3) += ctx->k[(s+3)%5] + s;
-}
-
-void threefish256_enc(void* data, const threefish256_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
- uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
- do{
- if(i%4==0){
- add_key_4(data, ctx, s);
- ++s;
- }
- threefish_mix(data, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- permute_4(data);
- ++i;
- }while(i!=72);
- add_key_4(data, ctx, s);
-}
-
+++ /dev/null
-/* threefish256_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-A0 = 14
-A1 = 15
-A2 = 16
-A3 = 17
-A4 = 18
-A5 = 19
-A6 = 20
-A7 = 21
-/*
-#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-void threefish256_init(void* key, void* tweak, threefish256_ctx_t* ctx){
- memcpy(ctx->k, key, 4*8);
- memcpy(ctx->t, tweak, 2*8);
- uint8_t i;
- ctx->k[4] = THREEFISH_KEY_CONST;
- for(i=0; i<4; ++i){
- ctx->k[4] ^= K(i);
- }
- ctx->t[2] = T(0) ^ T(1);
-}
-*/
-/*
- * param key: r24:r25
- * param tweak: r22:r23
- * param ctx: r20:r21
- */
-.global threefish256_init
-threefish256_init:
- push_range 14, 17
- movw r30, r20
- movw r26, r24
- ldi r24, 4
- ldi A7, 0x55
- mov A6, A7
- movw A4, A6
- movw A2, A6
- movw A0, A6
-1:
- ld r0, X+
- st Z+, r0
- eor A0, r0
- ld r0, X+
- st Z+, r0
- eor A1, r0
- ld r0, X+
- st Z+, r0
- eor A2, r0
- ld r0, X+
- st Z+, r0
- eor A3, r0
- ld r0, X+
- st Z+, r0
- eor A4, r0
- ld r0, X+
- st Z+, r0
- eor A5, r0
- ld r0, X+
- st Z+, r0
- eor A6, r0
- ld r0, X+
- st Z+, r0
- eor A7, r0
- dec r24
- brne 1b
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- /* now the tweak */
- tst r23
- brne 3f
- tst r22
- brne 3f
- ldi r26, 3*8
-2:
- st Z+, r1
- dec r26
- brne 2b
- rjmp 9f
-3:
- movw r26, r22
- ld A0, X+
- ld A1, X+
- ld A2, X+
- ld A3, X+
- ld A4, X+
- ld A5, X+
- ld A6, X+
- ld A7, X+
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- ld r0, X+
- eor A0, r0
- st Z+, r0
- ld r0, X+
- eor A1, r0
- st Z+, r0
- ld r0, X+
- eor A2, r0
- st Z+, r0
- ld r0, X+
- eor A3, r0
- st Z+, r0
- ld r0, X+
- eor A4, r0
- st Z+, r0
- ld r0, X+
- eor A5, r0
- st Z+, r0
- ld r0, X+
- eor A6, r0
- st Z+, r0
- ld r0, X+
- eor A7, r0
- st Z+, r0
-
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
-9:
- pop_range 14, 17
- ret
-
-/******************************************************************************/
-/*
-#define X(a) (((uint64_t*)data)[(a)])
-void permute_4(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(3);
- X(3) = t;
-}
-void add_key_4(void* data, threefish256_ctx_t* ctx, uint8_t s){ /* s: 0..19 * /
- X(0) += ctx->k[(s+0)%5];
- X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
- X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
- X(3) += ctx->k[(s+3)%5] + s;
-}
-void threefish256_enc(void* data, threefish256_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
- uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
- do{
- if(i%4==0){
- add_key_4(data, ctx, s);
- ++s;
- }
- threefish_mix(data, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- permute_4(data);
- ++i;
- }while(i!=72);
- add_key_4(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish256_enc
-threefish256_enc:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- clr S
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish256_slut5)
- ldi r31, hi8(threefish256_slut5)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall add_z_to_x8
-
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish256_slut3)
- ldi r31, hi8(threefish256_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 5*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- ld r0, X
- add r0, S
- 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
- inc S
- mov r26, S
- cpi r26, 19
- brmi 4f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-4:
- /* call mix */
- ldi r30, lo8(threefish256_rc0)
- ldi r31, hi8(threefish256_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- movw r24, DATA0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_mix_asm /* no rcall? */
- /* now the permutation */
- movw r26, DATA0
- adiw r26, 8
- movw r30, r26
- adiw r30, 16
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- inc I
- rjmp 1b
-
-threefish256_slut5:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
- .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
- .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
-threefish256_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
-;threefish256_rc0: .byte 5, 36, 13, 58, 26, 53, 11, 59
-;threefish256_rc1: .byte 56, 28, 46, 44, 20, 35, 42, 50
-threefish256_rc0: .byte 0x1b, 0x44, 0x2b, 0x72, 0x32, 0x7b, 0x13, 0x73
-threefish256_rc1: .byte 0x70, 0x34, 0x6a, 0x54, 0x24, 0x43, 0x52, 0x62
-
-add_z_to_x8:
- ld r0, Z+
- ld r1, X
- add r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- clr r1
- ret
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* threefish_mix.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-A0 = 14
-A1 = 15
-A2 = 16
-A3 = 17
-A4 = 18
-A5 = 19
-A6 = 20
-A7 = 21
-/*
-#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-void threefish256_init(void* key, void* tweak, threefish256_ctx_t* ctx){
- memcpy(ctx->k, key, 4*8);
- memcpy(ctx->t, tweak, 2*8);
- uint8_t i;
- ctx->k[4] = THREEFISH_KEY_CONST;
- for(i=0; i<4; ++i){
- ctx->k[4] ^= K(i);
- }
- ctx->t[2] = T(0) ^ T(1);
-}
-*/
-/*
- * param key: r24:r25
- * param tweak: r22:r23
- * param ctx: r20:r21
- */
-.global threefish256_init
-threefish256_init:
- push_range 14, 17
- movw r30, r20
- movw r26, r24
- ldi r24, 4
- ldi A7, 0x55
- mov A6, A7
- movw A4, A6
- movw A2, A6
- movw A0, A6
-1:
- ld r0, X+
- st Z+, r0
- eor A0, r0
- ld r0, X+
- st Z+, r0
- eor A1, r0
- ld r0, X+
- st Z+, r0
- eor A2, r0
- ld r0, X+
- st Z+, r0
- eor A3, r0
- ld r0, X+
- st Z+, r0
- eor A4, r0
- ld r0, X+
- st Z+, r0
- eor A5, r0
- ld r0, X+
- st Z+, r0
- eor A6, r0
- ld r0, X+
- st Z+, r0
- eor A7, r0
- dec r24
- brne 1b
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- /* now the tweak */
- movw r26, r22
- tst r27
- brne 3f
- tst r26
- brne 3f
- ldi r26, 3*8
-1:
- st Z+, r1
- dec r26
- brne 1b
- rjmp 9f
-3:
- ld A0, X+
- ld A1, X+
- ld A2, X+
- ld A3, X+
- ld A4, X+
- ld A5, X+
- ld A6, X+
- ld A7, X+
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- ld r0, X+
- eor A0, r0
- st Z+, r0
- ld r0, X+
- eor A1, r0
- st Z+, r0
- ld r0, X+
- eor A2, r0
- st Z+, r0
- ld r0, X+
- eor A3, r0
- st Z+, r0
- ld r0, X+
- eor A4, r0
- st Z+, r0
- ld r0, X+
- eor A5, r0
- st Z+, r0
- ld r0, X+
- eor A6, r0
- st Z+, r0
- ld r0, X+
- eor A7, r0
- st Z+, r0
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
-9:
- pop_range 14, 17
- ret
-
-/******************************************************************************/
-/*
-#define X(a) (((uint64_t*)data)[(a)])
-void permute_4(void* data){
- uint64_t t;
- t = X(1);
- X(1) = X(3);
- X(3) = t;
-}
-void add_key_4(void* data, threefish256_ctx_t* ctx, uint8_t s){ /* s: 0..19 * /
- X(0) += ctx->k[(s+0)%5];
- X(1) += ctx->k[(s+1)%5] + ctx->t[s%3];
- X(2) += ctx->k[(s+2)%5] + ctx->t[(s+1)%3];
- X(3) += ctx->k[(s+3)%5] + s;
-}
-void threefish256_enc(void* data, threefish256_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = { 5, 36, 13, 58, 26, 53, 11, 59};
- uint8_t r1[8] = {56, 28, 46, 44, 20, 35, 42, 50};
- do{
- if(i%4==0){
- add_key_4(data, ctx, s);
- ++s;
- }
- threefish_mix(data, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- permute_4(data);
- ++i;
- }while(i!=72);
- add_key_4(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish256_enc
-threefish256_enc:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- clr S
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish256_slut5)
- ldi r31, hi8(threefish256_slut5)
- mov r26, S
- add r30, r26
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall add_z_to_x8
-
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish256_slut3)
- ldi r31, hi8(threefish256_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 5*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- ld r0, X
- add r0, S
- st X+, r0
- ldi r16, 7
-3:
- ld r0, X
- adc r0, r1
- st X+, r0
- dec r16
- brne 3b
- inc S
- mov r26, S
- cpi r26, 19
- brmi 4f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-4:
- /* call mix */
- ldi r30, lo8(threefish256_rc0)
- ldi r31, hi8(threefish256_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- movw r24, DATA0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_mix_asm /* no rcall? */
- /* now the permutation */
- movw r26, DATA0
- adiw r26, 8
- movw r30, r26
- adiw r30, 16
- ldi r16, 8
-3: ld IDX0, X
- ld IDX1, Z
- st X+, IDX1
- st Z+, IDX0
- dec r16
- brne 3b
- inc I
- rjmp 1b
-
-threefish256_slut5:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
- .byte 0x18, 0x20, 0x00, 0x08, 0x10, 0x18, 0x20, 0x00
- .byte 0x08, 0x10, 0x18, 0x20, 0x00, 0x08, 0x10
-threefish256_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
-threefish256_rc0: .byte 0x1b, 0x44, 0x2b, 0x72, 0x32, 0x7b, 0x13, 0x73
-threefish256_rc1: .byte 0x70, 0x34, 0x6a, 0x54, 0x24, 0x43, 0x52, 0x62
-
-add_z_to_x8:
- ld r0, Z+
- ld r1, X
- add r1, r0
- st X+, r1
- ldi r16, 7
-1:
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- dec r16
- brne 1b
- clr r1
- ret
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* threefish512_dec.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-22
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-
-#define X(a) (((uint64_t*)data)[(a)])
-
-
-static
-void permute_inv8(void* data){
- uint64_t t;
- t = X(6);
- X(6) = X(4);
- X(4) = X(2);
- X(2) = X(0);
- X(0) = t;
- t = X(7);
- X(7) = X(3);
- X(3) = t;
-}
-
-static
-void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<5; ++i){
- X(i) -= ctx->k[(s+i)%9];
- }
- X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
- X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
- X(7) -= ctx->k[(s+7)%9] + s;
-}
-
-void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
- uint8_t i=0,s=18;
- uint8_t r0[8] = {33, 29, 39, 33, 26, 34, 48, 38};
- uint8_t r1[8] = {51, 26, 27, 49, 12, 14, 20, 30};
- uint8_t r2[8] = {39, 11, 41, 8, 58, 15, 43, 50};
- uint8_t r3[8] = {35, 9, 14, 42, 7, 27, 31, 53};
- do{
- if(i%4==0){
- add_key_8(data, ctx, s);
- --s;
- }
- permute_inv8(data);
- threefish_invmix((uint8_t*)data + 0, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- threefish_invmix((uint8_t*)data + 32, r2[i%8]);
- threefish_invmix((uint8_t*)data + 48, r3[i%8]);
- ++i;
- }while(i!=72);
- add_key_8(data, ctx, s);
-}
-
+++ /dev/null
-/* threefish512_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-24
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-#define X(a) (((uint64_t*)data)[(a)])
-
-
-static
-void permute_inv8(void* data){
- uint64_t t;
- t = X(6);
- X(6) = X(4);
- X(4) = X(2);
- X(2) = X(0);
- X(0) = t;
- t = X(7);
- X(7) = X(3);
- X(3) = t;
-}
-
-static
-void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<5; ++i){
- X(i) -= ctx->k[(s+i)%9];
- }
- X(5) -= ctx->k[(s+5)%9] + ctx->t[s%3];
- X(6) -= ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
- X(7) -= ctx->k[(s+7)%9] + s;
-}
-
-void threefish512_dec(void* data, const threefish512_ctx_t* ctx){
- uint8_t i=0,s=18;
- uint8_t r0[8] = {0x41, 0x4b, 0x59, 0x41, 0x32, 0x42, 0x60, 0x5a};
- uint8_t r1[8] = {0x63, 0x32, 0x33, 0x61, 0x14, 0x2a, 0x24, 0x4a};
- uint8_t r2[8] = {0x59, 0x13, 0x51, 0x10, 0x72, 0x29, 0x53, 0x62};
- uint8_t r3[8] = {0x43, 0x11, 0x2a, 0x52, 0x19, 0x33, 0x49, 0x7b};
- do{
- if(i%4==0){
- add_key_8(data, ctx, s);
- --s;
- }
- permute_inv8(data);
- threefish_invmix((uint8_t*)data + 0, r0[i%8]);
- threefish_invmix((uint8_t*)data + 16, r1[i%8]);
- threefish_invmix((uint8_t*)data + 32, r2[i%8]);
- threefish_invmix((uint8_t*)data + 48, r3[i%8]);
- ++i;
- }while(i!=72);
- add_key_8(data, ctx, s);
-}
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-IDX4 = 12
-IDX5 = 13
-IDX6 = 14
-IDX7 = 15
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish512_dec
-threefish512_dec:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- ldi r26, 18
- mov S, r26
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish512_slut9)
- ldi r31, hi8(threefish512_slut9)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall sub_z_from_x8
-
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish512_slut3)
- ldi r31, hi8(threefish512_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 7*8 /* make Z pointing to (extended tweak) */
- adiw r30, 2*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall sub_z_from_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall sub_z_from_x8
- ld r0, X
- sub r0, S
- 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
- ld r0, X
- sbc r0, r1
- st X+, r0
- tst S
- brne 3f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-3:
- dec S
-4:
- /* now the permutation */
- movw r26, DATA0
- movw r30, DATA0
- adiw r30, 6*8
- rcall xchg_zx8
- movw r26, DATA0
- adiw r26, 6*8
- movw r30, DATA0
- adiw r30, 4*8
- rcall xchg_zx8
- movw r26, DATA0
- adiw r26, 2*8
- movw r30, DATA0
- adiw r30, 4*8
- rcall xchg_zx8
- movw r26, DATA0
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- rcall xchg_zx8
- /* call mix */
- ldi r30, lo8(threefish512_rc0)
- ldi r31, hi8(threefish512_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- adiw r30, 8
- lpm IDX1, Z
- push IDX1
- adiw r30, 8
- lpm IDX1, Z
-
- movw r24, DATA0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 32
- pop r22
- ;mov r22, IDX0
- call threefish_invmix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 48
- mov r22, IDX1
- call threefish_invmix_asm /* no rcall? */
- inc I
- rjmp 1b
-
-threefish512_slut9:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
- .byte 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
- .byte 0x38, 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28
- .byte 0x30, 0x38, 0x40
-threefish512_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
-
-threefish512_rc0: .byte 0x41, 0x4b, 0x59, 0x41, 0x32, 0x42, 0x60, 0x5a
-threefish512_rc1: .byte 0x63, 0x32, 0x33, 0x61, 0x14, 0x2a, 0x24, 0x4a
-threefish512_rc2: .byte 0x59, 0x13, 0x51, 0x10, 0x72, 0x29, 0x53, 0x62
-threefish512_rc3: .byte 0x43, 0x11, 0x2a, 0x52, 0x19, 0x33, 0x49, 0x7b
-
-sub_z_from_x8:
- ld r0, Z+
- ld r1, X
- sub r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- sbc r1, r0
- st X+, r1
- clr r1
- ret
-
-T0 = IDX0
-T1 = 0
-CNT = 24
-xchg_zx8:
- ldi CNT, 8
-1: ld T0, X
- ld T1, Z
- st X+, T1
- st Z+, T0
- dec CNT
- brne 1b
- ret
-
-
-
+++ /dev/null
-/* threefish512_enc.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-
-
-#define X(a) (((uint64_t*)data)[(a)])
-
-
-static
-void permute_8(void* data){
- uint64_t t;
- t = X(0);
- X(0) = X(2);
- X(2) = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(3);
- X(3) = X(7);
- X(7) = t;
-}
-/*
-static
-void permute_inv8(void* data){
- uint64_t t;
- t = X(6);
- X(6) = X(4);
- X(4) = X(2);
- X(2) = X(0);
- X(0) = t;
- t = X(7);
- X(7) = X(3);
- X(3) = t;
-}
-*/
-
-#define THREEFISH_KEY_CONST 0x5555555555555555LL /* 2**64/3 */
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-
-void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
- memcpy(ctx->k, key, 8*8);
- if(tweak){
- memcpy(ctx->t, tweak, 2*8);
- ctx->t[2] = T(0) ^ T(1);
- }else{
- memset(ctx->t, 0, 3*8);
- }
- uint8_t i;
- ctx->k[8] = THREEFISH_KEY_CONST;
- for(i=0; i<8; ++i){
- ctx->k[8] ^= K(i);
- }
-}
-
-static
-void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<5; ++i){
- X(i) += ctx->k[(s+i)%9];
- }
- X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
- X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
- X(7) += ctx->k[(s+7)%9] + s;
-}
-
-void threefish512_enc(void* data, const threefish512_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
- uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
- uint8_t r2[8] = {50, 43, 15, 58, 8, 41, 11, 39};
- uint8_t r3[8] = {53, 31, 27, 7, 42, 14, 9, 35};
- do{
- if(i%4==0){
- add_key_8(data, ctx, s);
- ++s;
- }
- threefish_mix((uint8_t*)data + 0, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- threefish_mix((uint8_t*)data + 32, r2[i%8]);
- threefish_mix((uint8_t*)data + 48, r3[i%8]);
- permute_8(data);
- ++i;
- }while(i!=72);
- add_key_8(data, ctx, s);
-}
-
+++ /dev/null
-/* threefish512_enc_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-24
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-A0 = 14
-A1 = 15
-A2 = 16
-A3 = 17
-A4 = 18
-A5 = 19
-A6 = 20
-A7 = 21
-/*
-#define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
-
-#define K(s) (((uint64_t*)key)[(s)])
-#define T(s) (((uint64_t*)tweak)[(s)])
-void threefish512_init(const void* key, const void* tweak, threefish512_ctx_t* ctx){
- memcpy(ctx->k, key, 8*8);
- memcpy(ctx->t, tweak, 2*8);
- uint8_t i;
- ctx->k[8] = THREEFISH_KEY_CONST;
- for(i=0; i<8; ++i){
- ctx->k[8] ^= K(i);
- }
- ctx->t[2] = T(0) ^ T(1);
-}
-*/
-/*
- * param key: r24:r25
- * param tweak: r22:r23
- * param ctx: r20:r21
- */
-.global threefish512_init
-threefish512_init:
- push_range 14, 17
- movw r30, r20
- movw r26, r24
- ldi r24, 8
- ldi A7, 0x55
- mov A6, A7
- movw A4, A6
- movw A2, A6
- movw A0, A6
-1:
- ld r0, X+
- st Z+, r0
- eor A0, r0
- ld r0, X+
- st Z+, r0
- eor A1, r0
- ld r0, X+
- st Z+, r0
- eor A2, r0
- ld r0, X+
- st Z+, r0
- eor A3, r0
- ld r0, X+
- st Z+, r0
- eor A4, r0
- ld r0, X+
- st Z+, r0
- eor A5, r0
- ld r0, X+
- st Z+, r0
- eor A6, r0
- ld r0, X+
- st Z+, r0
- eor A7, r0
- dec r24
- brne 1b
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- /* now the tweak */
- movw r26, r22
- tst r27
- brne 3f
- tst r26
- brne 3f
- ldi r26, 3*8
-1:
- st Z+, r1
- dec r26
- brne 1b
- rjmp 9f
-3:
- ld A0, X+
- ld A1, X+
- ld A2, X+
- ld A3, X+
- ld A4, X+
- ld A5, X+
- ld A6, X+
- ld A7, X+
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
- ld r0, X+
- eor A0, r0
- st Z+, r0
- ld r0, X+
- eor A1, r0
- st Z+, r0
- ld r0, X+
- eor A2, r0
- st Z+, r0
- ld r0, X+
- eor A3, r0
- st Z+, r0
- ld r0, X+
- eor A4, r0
- st Z+, r0
- ld r0, X+
- eor A5, r0
- st Z+, r0
- ld r0, X+
- eor A6, r0
- st Z+, r0
- ld r0, X+
- eor A7, r0
- st Z+, r0
- st Z+, A0
- st Z+, A1
- st Z+, A2
- st Z+, A3
- st Z+, A4
- st Z+, A5
- st Z+, A6
- st Z+, A7
-9:
- pop_range 14, 17
- ret
-
-/******************************************************************************/
-/*
-#define X(a) (((uint64_t*)data)[(a)])
-void permute_8(void* data){
- uint64_t t;
- t = X(0);
- X(0) = X(2);
- X(2) = X(4);
- X(4) = X(6);
- X(6) = t;
- t = X(3);
- X(3) = X(7);
- X(7) = t;
-}
-void add_key_8(void* data, const threefish512_ctx_t* ctx, uint8_t s){
- uint8_t i;
- for(i=0; i<5; ++i){
- X(i) += ctx->k[(s+i)%9];
- }
- X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
- X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
- X(7) += ctx->k[(s+7)%9] + s;
-}
-void threefish512_enc(void* data, const threefish512_ctx_t* ctx){
- uint8_t i=0,s=0;
- uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
- uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
- uint8_t r2[8] = {50, 43, 15, 58, 8, 41, 11, 39};
- uint8_t r3[8] = {53, 31, 27, 7, 42, 14, 9, 35};
- do{
- if(i%4==0){
- add_key_8(data, ctx, s);
- ++s;
- }
- threefish_mix((uint8_t*)data + 0, r0[i%8]);
- threefish_mix((uint8_t*)data + 16, r1[i%8]);
- threefish_mix((uint8_t*)data + 32, r2[i%8]);
- threefish_mix((uint8_t*)data + 48, r3[i%8]);
- permute_8(data);
- ++i;
- }while(i!=72);
- add_key_8(data, ctx, s);
-}
-
-*/
-I = 2
-S = 3
-DATA0 = 4
-DATA1 = 5
-CTX0 = 6
-CTX1 = 7
-IDX0 = 8
-IDX1 = 9
-IDX2 = 10
-IDX3 = 11
-IDX4 = 12
-IDX5 = 13
-IDX6 = 14
-IDX7 = 15
-/*
- * param data: r24:r25
- * param ctx: r22:r23
- */
-.global threefish512_enc
-threefish512_enc:
- push r28
- push r29
- push_range 2, 17
- movw DATA0, r24
- movw CTX0, r22
- clr I
- clr S
-1:
- mov r30, I
- andi r30, 0x03
- breq 2f
- rjmp 4f
-2:
- ldi r30, lo8(threefish512_slut9)
- ldi r31, hi8(threefish512_slut9)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z+
- lpm IDX2, Z+
- lpm IDX3, Z+
- lpm IDX4, Z+
- lpm IDX5, Z+
- lpm IDX6, Z+
- lpm IDX7, Z
- movw r30, CTX0
- movw r26, DATA0
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX2
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX3
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX4
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX5
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX6
- adc r31, r1
- rcall add_z_to_x8
- movw r30, CTX0
- add r30, IDX7
- adc r31, r1
- rcall add_z_to_x8
-
- /* now the remaining key */
- sbiw r26, 3*8
- ldi r30, lo8(threefish512_slut3)
- ldi r31, hi8(threefish512_slut3)
- add r30, S
- adc r31, r1
- lpm IDX0, Z+
- lpm IDX1, Z
- movw r30, CTX0
- adiw r30, 7*8 /* make Z pointing to (extended tweak) */
- adiw r30, 2*8
- movw IDX2, r30
- add r30, IDX0
- adc r31, r1
- rcall add_z_to_x8
- movw r30, IDX2
- add r30, IDX1
- adc r31, r1
- rcall add_z_to_x8
- ld r0, X
- add r0, S
- 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
- inc S
- mov r26, S
- cpi r26, 19
- brmi 4f
-exit:
- pop_range 2, 17
- pop r29
- pop r28
- ret
-4:
- /* call mix */
- ldi r30, lo8(threefish512_rc0)
- ldi r31, hi8(threefish512_rc0)
- mov r26, I
- andi r26, 0x07
- add r30, r26
- adc r31, r1
- lpm r22, Z
- adiw r30, 8
- lpm IDX0, Z
- adiw r30, 8
- lpm IDX1, Z
- push IDX1
- adiw r30, 8
- lpm IDX1, Z
-
- movw r24, DATA0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 16
- mov r22, IDX0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 32
- pop r22
- ;mov r22, IDX0
- call threefish_mix_asm /* no rcall? */
- movw r24, DATA0
- adiw r24, 48
- mov r22, IDX1
- call threefish_mix_asm /* no rcall? */
- /* now the permutation */
- movw r26, DATA0
- movw r30, DATA0
- adiw r30, 6*8
- rcall xchg_zx8
- movw r26, DATA0
- movw r30, DATA0
- adiw r30, 2*8
- rcall xchg_zx8
- movw r26, DATA0
- adiw r26, 2*8
- movw r30, DATA0
- adiw r30, 4*8
- rcall xchg_zx8
- movw r26, DATA0
- adiw r26, 3*8
- movw r30, DATA0
- adiw r30, 7*8
- rcall xchg_zx8
- inc I
- rjmp 1b
-
-threefish512_slut9:
- .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
- .byte 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
- .byte 0x38, 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28
- .byte 0x30, 0x38, 0x40
-threefish512_slut3:
- .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
- .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
- .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
-
-threefish512_rc0: .byte 0x5a, 0x60, 0x42, 0x32, 0x41, 0x59, 0x4b, 0x41
-threefish512_rc1: .byte 0x4a, 0x24, 0x2a, 0x14, 0x61, 0x33, 0x32, 0x63
-threefish512_rc2: .byte 0x62, 0x53, 0x29, 0x72, 0x10, 0x51, 0x13, 0x59
-threefish512_rc3: .byte 0x7b, 0x49, 0x33, 0x19, 0x52, 0x2a, 0x11, 0x43
-
-add_z_to_x8:
- ld r0, Z+
- ld r1, X
- add r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- ld r0, Z+
- ld r1, X
- adc r1, r0
- st X+, r1
- clr r1
- ret
-
-T0 = IDX0
-T1 = 0
-CNT = 24
-xchg_zx8:
- ldi CNT, 8
-1: ld T0, X
- ld T1, Z
- st X+, T1
- st Z+, T0
- dec CNT
- brne 1b
- ret
-
-
-
+++ /dev/null
-/* threefish_invmix.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-21
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/*
-#define X0 (((uint64_t*)data)[0])
-#define X1 (((uint64_t*)data)[1])
-void threefish_invmix(void* data, uint8_t rot){
- uint64_t x;
- x = X1;
- x ^= X0;
- X1 = ((x>>rot)|(x<<(64-rot)));
- X0 -= X1;
-}
-*/
-A0 = 10
-A1 = 11
-A2 = 12
-A3 = 13
-A4 = 14
-A5 = 15
-A6 = 16
-A7 = 17
-
-B0 = 18
-B1 = 19
-B2 = 20
-B3 = 21
-B4 = 22
-B5 = 23
-B6 = 24
-B7 = 25
-vROT = 27
-/*
- * param data: r24:r25
- * param rot: r22
- */
-
-.global threefish_invmix_asm
-threefish_invmix_asm:
- movw r28, r24
- mov vROT,r22
- ldd A0, Y+ 0
- ldd A1, Y+ 1
- ldd A2, Y+ 2
- ldd A3, Y+ 3
- ldd A4, Y+ 4
- ldd A5, Y+ 5
- ldd A6, Y+ 6
- ldd A7, Y+ 7
- ldd B0, Y+ 8
- ldd B1, Y+ 9
- ldd B2, Y+10
- ldd B3, Y+11
- ldd B4, Y+12
- ldd B5, Y+13
- ldd B6, Y+14
- ldd B7, Y+15
- eor B0, A0
- eor B1, A1
- eor B2, A2
- eor B3, A3
- eor B4, A4
- eor B5, A5
- eor B6, A6
- eor B7, A7
-
- mov r26, vROT
- swap r26
- andi r26, 0x07
- ldi r30, pm_lo8(byte_rot_jmptable)
- ldi r31, pm_hi8(byte_rot_jmptable)
- add r30, r26
- adc r31, r1
- ijmp
-post_byterot:
- bst vROT, 3
- andi vROT, 0x07
- brts 1f
- rjmp bit_rotr
-1: rjmp bit_rotl
-post_bitrot:
- sub A0, B0
- sbc A1, B1
- sbc A2, B2
- sbc A3, B3
- sbc A4, B4
- sbc A5, B5
- sbc A6, B6
- sbc A7, B7
-
- std Y+ 0, A0
- std Y+ 1, A1
- std Y+ 2, A2
- std Y+ 3, A3
- std Y+ 4, A4
- std Y+ 5, A5
- std Y+ 6, A6
- std Y+ 7, A7
- std Y+ 8, B0
- std Y+ 9, B1
- std Y+10, B2
- std Y+11, B3
- std Y+12, B4
- std Y+13, B5
- std Y+14, B6
- std Y+15, B7
-exit:
- ret
-
-byte_rot_jmptable:
- rjmp post_byterot;ret; rjmp byte_rotr_0
- rjmp byte_rotr_1
- rjmp byte_rotr_2
- rjmp byte_rotr_3
- rjmp byte_rotr_4
- rjmp byte_rotr_5
- rjmp byte_rotr_6
- rjmp byte_rotr_7
- rjmp post_byterot;ret; rjmp byte_rotr_0
-
-
-
-; 0 1 2 3 4 5 6 7
-; 1 2 3 4 5 6 7 0
-;.global byte_rotr_1
-;.global byte_rotr_0
-byte_rotr_1: /* 10 words */
- mov r0, B0
- mov B0, B1
- mov B1, B2
- mov B2, B3
- mov B3, B4
- mov B4, B5
- mov B5, B6
- mov B6, B7
- mov B7, r0
-byte_rotr_0:
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 2 3 4 5 6 7 0 1
-;.global byte_rotr_2
-byte_rotr_2: /* 11 words */
- mov r0, B0
- mov B0, B2
- mov B2, B4
- mov B4, B6
- mov B6, r0
- mov r0, B1
- mov B1, B3
- mov B3, B5
- mov B5, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 3 4 5 6 7 0 1 2
-;.global byte_rotr_3
-byte_rotr_3: /* 10 words */
- mov r0, B0
- mov B0, B3
- mov B3, B6
- mov B6, B1
- mov B1, B4
- mov B4, B7
- mov B7, B2
- mov B2, B5
- mov B5, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 4 5 6 7 0 1 2 3
-;.global byte_rotr_4
-byte_rotr_4: /* 13 words */
- mov r0, B0
- mov B0, B4
- mov B4, r0
-
- mov r0, B1
- mov B1, B5
- mov B5, r0
-
- mov r0, B2
- mov B2, B6
- mov B6, r0
-
- mov r0, B3
- mov B3, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 5 6 7 0 1 2 3 4
-;.global byte_rotr_5
-byte_rotr_5: /* 10 words */
- mov r0, B0
- mov B0, B5
- mov B5, B2
- mov B2, B7
- mov B7, B4
- mov B4, B1
- mov B1, B6
- mov B6, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 6 7 0 1 2 3 4 5
-;.global byte_rotr_6
-byte_rotr_6: /* 11 words */
- mov r0, B0
- mov B0, B6
- mov B6, B4
- mov B4, B2
- mov B2, r0
-
- mov r0, B1
- mov B1, B7
- mov B7, B5
- mov B5, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 7 0 1 2 3 4 5 6
-;.global byte_rotr_7
-byte_rotr_7: /* 10 words */
- mov r0, B7
- mov B7, B6
- mov B6, B5
- mov B5, B4
- mov B4, B3
- mov B3, B2
- mov B2, B1
- mov B1, B0
- mov B0, r0
- rjmp post_byterot
-
-;.global bit_rotl
-bit_rotl:
- tst vROT
- brne 1f
- rjmp post_bitrot
-1: mov r0, B7
- rol r0
- rol B0
- rol B1
- rol B2
- rol B3
- rol B4
- rol B5
- rol B6
- rol B7
- dec vROT
- rjmp bit_rotl
-
-;.global bit_rotr
-bit_rotr:
- tst vROT
- brne 1f
- rjmp post_bitrot
-1: mov r0, B0
- ror r0
- ror B7
- ror B6
- ror B5
- ror B4
- ror B3
- ror B2
- ror B1
- ror B0
- dec vROT
- rjmp bit_rotr
-
-
+++ /dev/null
-/* threefish_invmix_c.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-21
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-
-#define X0 (((uint64_t*)data)[0])
-#define X1 (((uint64_t*)data)[1])
-void threefish_invmix(void* data, uint8_t rot){
- uint64_t x;
- x = X1;
- x ^= X0;
- X1 = ((x>>rot)|(x<<(64-rot)));
- X0 -= X1;
-}
+++ /dev/null
-/* threefish_mix.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/*
-#define B0 (((uint64_t*)data)[0])
-#define B1 (((uint64_t*)data)[1])
-static
-void mix(void* data, uint8_t rot){
- uint64_t x;
- x = B1;
- B0 += x;
- B1 = ((x<<rot)|(x>>(64-rot))) ^ B0;
-}
-*/
-A0 = 10
-A1 = 11
-A2 = 12
-A3 = 13
-A4 = 14
-A5 = 15
-A6 = 16
-A7 = 17
-
-B0 = 18
-B1 = 19
-B2 = 20
-B3 = 21
-B4 = 22
-B5 = 23
-B6 = 24
-B7 = 25
-vROT = 27
-/*
- * param data: r24:r25
- * param rot: r22
- */
-
-.global threefish_mix_asm
-threefish_mix_asm:
- movw r28, r24
- mov vROT,r22
- ldd A0, Y+ 0
- ldd A1, Y+ 1
- ldd A2, Y+ 2
- ldd A3, Y+ 3
- ldd A4, Y+ 4
- ldd A5, Y+ 5
- ldd A6, Y+ 6
- ldd A7, Y+ 7
- ldd B0, Y+ 8
- ldd B1, Y+ 9
- ldd B2, Y+10
- ldd B3, Y+11
- ldd B4, Y+12
- ldd B5, Y+13
- ldd B6, Y+14
- ldd B7, Y+15
- add A0, B0
- adc A1, B1
- adc A2, B2
- adc A3, B3
- adc A4, B4
- adc A5, B5
- adc A6, B6
- adc A7, B7
-
- mov r26, vROT
- swap r26
- andi r26, 0x07
- ldi r30, pm_lo8(byte_rot_jmptable)
- ldi r31, pm_hi8(byte_rot_jmptable)
- add r30, r26
- adc r31, r1
- ijmp
-post_byterot:
- bst vROT, 3
- andi vROT, 0x07
- brts 1f
- rjmp bit_rotl
-1: rjmp bit_rotr
-post_bitrot:
- eor B0, A0
- eor B1, A1
- eor B2, A2
- eor B3, A3
- eor B4, A4
- eor B5, A5
- eor B6, A6
- eor B7, A7
-
- std Y+ 0, A0
- std Y+ 1, A1
- std Y+ 2, A2
- std Y+ 3, A3
- std Y+ 4, A4
- std Y+ 5, A5
- std Y+ 6, A6
- std Y+ 7, A7
- std Y+ 8, B0
- std Y+ 9, B1
- std Y+10, B2
- std Y+11, B3
- std Y+12, B4
- std Y+13, B5
- std Y+14, B6
- std Y+15, B7
-exit:
- ret
-
-
-byte_rot_jmptable:
- rjmp post_byterot;ret; rjmp byte_rotr_0
- rjmp byte_rotr_7
- rjmp byte_rotr_6
- rjmp byte_rotr_5
- rjmp byte_rotr_4
- rjmp byte_rotr_3
- rjmp byte_rotr_2
- rjmp byte_rotr_1
- rjmp post_byterot;ret; rjmp byte_rotr_0
-
-; 0 1 2 3 4 5 6 7
-; 1 2 3 4 5 6 7 0
-;.global byte_rotr_1
-;.global byte_rotr_0
-byte_rotr_1: /* 10 words */
- mov r0, B0
- mov B0, B1
- mov B1, B2
- mov B2, B3
- mov B3, B4
- mov B4, B5
- mov B5, B6
- mov B6, B7
- mov B7, r0
-byte_rotr_0:
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 2 3 4 5 6 7 0 1
-;.global byte_rotr_2
-byte_rotr_2: /* 11 words */
- mov r0, B0
- mov B0, B2
- mov B2, B4
- mov B4, B6
- mov B6, r0
- mov r0, B1
- mov B1, B3
- mov B3, B5
- mov B5, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 3 4 5 6 7 0 1 2
-;.global byte_rotr_3
-byte_rotr_3: /* 10 words */
- mov r0, B0
- mov B0, B3
- mov B3, B6
- mov B6, B1
- mov B1, B4
- mov B4, B7
- mov B7, B2
- mov B2, B5
- mov B5, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 4 5 6 7 0 1 2 3
-;.global byte_rotr_4
-byte_rotr_4: /* 13 words */
- mov r0, B0
- mov B0, B4
- mov B4, r0
-
- mov r0, B1
- mov B1, B5
- mov B5, r0
-
- mov r0, B2
- mov B2, B6
- mov B6, r0
-
- mov r0, B3
- mov B3, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 5 6 7 0 1 2 3 4
-;.global byte_rotr_5
-byte_rotr_5: /* 10 words */
- mov r0, B0
- mov B0, B5
- mov B5, B2
- mov B2, B7
- mov B7, B4
- mov B4, B1
- mov B1, B6
- mov B6, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 6 7 0 1 2 3 4 5
-;.global byte_rotr_6
-byte_rotr_6: /* 11 words */
- mov r0, B0
- mov B0, B6
- mov B6, B4
- mov B4, B2
- mov B2, r0
-
- mov r0, B1
- mov B1, B7
- mov B7, B5
- mov B5, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 7 0 1 2 3 4 5 6
-;.global byte_rotr_7
-byte_rotr_7: /* 10 words */
- mov r0, B7
- mov B7, B6
- mov B6, B5
- mov B5, B4
- mov B4, B3
- mov B3, B2
- mov B2, B1
- mov B1, B0
- mov B0, r0
- rjmp post_byterot
-
-;.global bit_rotl
-bit_rotl:
- tst vROT
- brne 1f
- rjmp post_bitrot
-1: mov r0, B7
- rol r0
- rol B0
- rol B1
- rol B2
- rol B3
- rol B4
- rol B5
- rol B6
- rol B7
- dec vROT
- rjmp bit_rotl
-
-;.global bit_rotr
-bit_rotr:
- tst vROT
- brne 1f
- rjmp post_bitrot
-1: mov r0, B0
- ror r0
- ror B7
- ror B6
- ror B5
- ror B4
- ror B3
- ror B2
- ror B1
- ror B0
- dec vROT
- rjmp bit_rotr
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* threefish_mix.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/*
-#define B0 (((uint64_t*)data)[0])
-#define B1 (((uint64_t*)data)[1])
-static
-void mix(void* data, uint8_t rot){
- uint64_t x;
- x = B1;
- B0 += x;
- B1 = ((x<<rot)|(x>>(64-rot))) ^ B0;
-}
-*/
-A0 = 10
-A1 = 11
-A2 = 12
-A3 = 13
-A4 = 14
-A5 = 15
-A6 = 16
-A7 = 17
-
-B0 = 18
-B1 = 19
-B2 = 20
-B3 = 21
-B4 = 22
-B5 = 23
-B6 = 24
-B7 = 25
-vROT = 27
-/*
- * param data: r24:r25
- * param rot: r22
- */
-
-.global threefish_mix
-threefish_mix:
- push r28
- push r29
- push_range 10, 17
- movw r28, r24
- mov vROT,r22
- ldd A0, Y+ 0
- ldd A1, Y+ 1
- ldd A2, Y+ 2
- ldd A3, Y+ 3
- ldd A4, Y+ 4
- ldd A5, Y+ 5
- ldd A6, Y+ 6
- ldd A7, Y+ 7
- ldd B0, Y+ 8
- ldd B1, Y+ 9
- ldd B2, Y+10
- ldd B3, Y+11
- ldd B4, Y+12
- ldd B5, Y+13
- ldd B6, Y+14
- ldd B7, Y+15
- add A0, B0
- adc A1, B1
- adc A2, B2
- adc A3, B3
- adc A4, B4
- adc A5, B5
- adc A6, B6
- adc A7, B7
-
- mov r26, vROT
- adiw r26, 3
- lsr r26
- lsr r26
- lsr r26
-; andi r26, 0x07
- ldi r30, pm_lo8(byte_rot_jmptable)
- ldi r31, pm_hi8(byte_rot_jmptable)
- add r30, r26
- adc r31, r1
- ijmp
-post_byterot:
- ldi r30, lo8(bit_rot_lut)
- ldi r31, hi8(bit_rot_lut)
- andi vROT, 0x07
- add r30, vROT
- adc r31, r1
- lpm r27, Z
- bst r27, 7
- andi r27, 0x07
- brts 1f
- rjmp bit_rotl
-1: rjmp bit_rotr
-post_bitrot:
- eor B0, A0
- eor B1, A1
- eor B2, A2
- eor B3, A3
- eor B4, A4
- eor B5, A5
- eor B6, A6
- eor B7, A7
-
- std Y+ 0, A0
- std Y+ 1, A1
- std Y+ 2, A2
- std Y+ 3, A3
- std Y+ 4, A4
- std Y+ 5, A5
- std Y+ 6, A6
- std Y+ 7, A7
- std Y+ 8, B0
- std Y+ 9, B1
- std Y+10, B2
- std Y+11, B3
- std Y+12, B4
- std Y+13, B5
- std Y+14, B6
- std Y+15, B7
-exit:
- pop_range 10, 17
- pop r29
- pop r28
- ret
-
-bit_rot_lut:
- .byte 0x00
- .byte 0x01
- .byte 0x02
- .byte 0x03
- .byte 0x04
- .byte 0x83
- .byte 0x82
- .byte 0x81
-
-byte_rot_jmptable:
- rjmp post_byterot;ret; rjmp byte_rotr_0
- rjmp byte_rotr_7
- rjmp byte_rotr_6
- rjmp byte_rotr_5
- rjmp byte_rotr_4
- rjmp byte_rotr_3
- rjmp byte_rotr_2
- rjmp byte_rotr_1
- rjmp post_byterot;ret; rjmp byte_rotr_0
-
-; 0 1 2 3 4 5 6 7
-; 1 2 3 4 5 6 7 0
-
-byte_rotr_1: /* 10 words */
- mov r0, B0
- mov B0, B1
- mov B1, B2
- mov B2, B3
- mov B3, B4
- mov B4, B5
- mov B5, B6
- mov B6, B7
- mov B7, r0
-byte_rotr_0:
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 2 3 4 5 6 7 0 1
-
-byte_rotr_2: /* 11 words */
- mov r0, B0
- mov B0, B2
- mov B2, B4
- mov B4, B6
- mov B6, r0
- mov r0, B1
- mov B1, B3
- mov B3, B5
- mov B5, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 3 4 5 6 7 0 1 2
-
-byte_rotr_3: /* 10 words */
- mov r0, B0
- mov B0, B3
- mov B3, B6
- mov B6, B1
- mov B1, B4
- mov B4, B7
- mov B7, B2
- mov B2, B5
- mov B5, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 4 5 6 7 0 1 2 3
-byte_rotr_4: /* 13 words */
- mov r0, B0
- mov B0, B4
- mov B4, r0
-
- mov r0, B1
- mov B1, B5
- mov B5, r0
-
- mov r0, B2
- mov B2, B6
- mov B6, r0
-
- mov r0, B3
- mov B3, B7
- mov B7, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 5 6 7 0 1 2 3 4
-byte_rotr_5: /* 10 words */
- mov r0, B0
- mov B0, B5
- mov B5, B2
- mov B2, B7
- mov B7, B4
- mov B4, B1
- mov B1, B6
- mov B6, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 6 7 0 1 2 3 4 5
-byte_rotr_6: /* 11 words */
- mov r0, B0
- mov B0, B6
- mov B6, B4
- mov B4, B2
- mov B2, r0
-
- mov r0, B1
- mov B1, B7
- mov B7, B5
- mov B5, B3
- mov B3, r0
- rjmp post_byterot
-
-; 0 1 2 3 4 5 6 7
-; 7 0 1 2 3 4 5 6
-byte_rotr_7: /* 10 words */
- mov r0, B7
- mov B7, B6
- mov B6, B5
- mov B5, B4
- mov B4, B3
- mov B3, B2
- mov B2, B1
- mov B1, B0
- mov B0, r0
- rjmp post_byterot
-
-bit_rotl:
- tst r27
- brne 1f
- rjmp post_bitrot
-1: mov r0, B7
- rol r0
- rol B0
- rol B1
- rol B2
- rol B3
- rol B4
- rol B5
- rol B6
- rol B7
- dec r27
- rjmp bit_rotl
-
-bit_rotr:
- tst r27
- brne 1f
- rjmp post_bitrot
-1: mov r0, B0
- ror r0
- ror B7
- ror B6
- ror B5
- ror B4
- ror B3
- ror B2
- ror B1
- ror B0
- dec r27
- rjmp bit_rotr
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/* threefish_mix_c.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- *
- *
- *
- */
-
-#include <stdint.h>
-
-#define X0 (((uint64_t*)data)[0])
-#define X1 (((uint64_t*)data)[1])
-void threefish_mix(void* data, uint8_t rot){
- uint64_t x;
- x = X1;
- X0 += x;
- X1 = ((x<<rot)|(x>>(64-rot))) ^ X0;
-}
+++ /dev/null
-/* twister-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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_large_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_large_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-large-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file twister-large-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_large_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_large_init(twister_large_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_large_init
-
-.global twister512_init
-twister512_init:
- ldi r22, lo8(512)
- ldi r23, hi8(512)
-
-.global twister_large_init
-twister_large_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_large_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_large_nextBlock
-.global twister384_nextBlock
-.global twister512_nextBlock
-
-twister384_nextBlock:
-twister512_nextBlock:
-twister_large_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_large_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_large_lastBlock
-.global twister384_lastBlock
-.global twister512_lastBlock
-
-twister384_lastBlock:
-twister512_lastBlock:
-twister_large_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_large_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
-31:
- st Z+, r0
- ld r0, X+
- dec r18
- brne 31b
-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
- tst r19
- breq 7f
-6:
- st Z+, r1
- dec r19
- brne 6b
-7:
- movw r24, CTX_SAVE0
- movw r22, TMP_SAVE0
- rcall twister_large_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
+++ /dev/null
-/* twister-large.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdint.h>
-#include <string.h>
-#include "memxor.h"
-#include "twister.h"
-#include "twister-large.h"
-
-/*********************************************************************/
-
-static
-void checksum_update(twister_large_ctx_t* ctx, uint8_t col){
- uint8_t i, col2;
- uint8_t carry = 0;
- int sum = 0;
-
- col2 = (col+1)%8;
-
- for( i=0; i<8; i++ )
- {
- sum = (int) ctx->checksum[col2][7-i]
- + (int) ctx->state.s[7-i][0] /* col or 0 ???*/
- + carry;
- ctx->checksum[col][7-i] ^= (uint8_t)sum;
- carry = sum>>8;
-
- }
-}
-
-/*********************************************************************/
-
-void twister_large_init(twister_large_ctx_t* ctx, uint16_t hashsize_b){
- memset(ctx->state.s, 0, 64);
- memset(ctx->checksum, 0, 64);
- ctx->state.counter=0xffffffffffffffffLL;
- ctx->state.s[0][7] = hashsize_b>>8;
- ctx->state.s[1][7] = hashsize_b&0xff;
- ctx->state.length_counter_b = 0;
-}
-
-/*********************************************************************/
-
-void twister_large_nextBlock(twister_large_ctx_t* ctx, const void* msg){
- uint8_t tmp[8][8];
-
- /* 1st maxi round */
- memcpy(tmp, ctx->state.s, 64);
- checksum_update(ctx, 0);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
-
- checksum_update(ctx, 1);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
-
- checksum_update(ctx, 2);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
- memxor(ctx->state.s, tmp, 64);
-
- /* 2nd maxi round */
- memcpy(tmp, ctx->state.s, 64);
- checksum_update(ctx, 3);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
-
- twister_blank_round(&(ctx->state));
-
- checksum_update(ctx, 4);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
- memxor(ctx->state.s, tmp, 64);
-
- /* 3rd maxi round */
- memcpy(tmp, ctx->state.s, 64);
- checksum_update(ctx, 5);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
-
- checksum_update(ctx, 6);
- twister_mini_round(&(ctx->state), msg);
- msg = (uint8_t*)msg + 8;
-
- checksum_update(ctx, 7);
- twister_mini_round(&(ctx->state), msg);
-
- twister_blank_round(&(ctx->state));
- memxor(ctx->state.s, tmp, 64);
- ctx->state.length_counter_b += 512;
-}
-
-/*********************************************************************/
-
-void twister_inject_chksum(twister_large_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_large_lastBlock(twister_large_ctx_t* ctx, const void* msg, uint16_t length_b){
- uint8_t tmp[64];
- while(length_b>=512){
- twister_large_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_large_nextBlock(ctx, tmp);
- ctx->state.length_counter_b -= 512 - length_b;
- twister_mini_round(&(ctx->state), &(ctx->state.length_counter_b));
-
- memcpy(tmp, ctx->state.s, 64);
- twister_inject_chksum(ctx, 0);
- twister_inject_chksum(ctx, 1);
- twister_inject_chksum(ctx, 2);
- memxor(ctx->state.s, tmp, 64);
-
- memcpy(tmp, ctx->state.s, 64);
- twister_inject_chksum(ctx, 3);
- twister_inject_chksum(ctx, 4);
- twister_inject_chksum(ctx, 5);
- memxor(ctx->state.s, tmp, 64);
-
- memcpy(tmp, ctx->state.s, 64);
- twister_inject_chksum(ctx, 6);
- twister_inject_chksum(ctx, 7);
- twister_blank_round(&(ctx->state));
- memxor(ctx->state.s, tmp, 64);
-
-}
-
-/*********************************************************************/
-
-void twister_large_ctx2hash(void* dest, twister_large_ctx_t* ctx, uint16_t hashsize_b){
- twister_ctx2hash(dest, &(ctx->state), hashsize_b);
-}
-
-/*********************************************************************/
-/*********************************************************************/
-
-void twister384_init(twister384_ctx_t* ctx){
- twister_large_init(ctx, 384);
-}
-
-/*********************************************************************/
-
-void twister384_nextBlock(twister384_ctx_t* ctx, const void* msg){
- twister_large_nextBlock(ctx, msg);
-}
-
-/*********************************************************************/
-
-void twister384_lastBlock(twister384_ctx_t* ctx, const void* msg, uint16_t length_b){
- twister_large_lastBlock(ctx, msg, length_b);
-}
-
-/*********************************************************************/
-
-void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx){
- twister_large_ctx2hash(dest, ctx, 384);
-}
-
-/*********************************************************************/
-
-void twister384(void* dest, const void* msg, uint32_t msg_length_b){
- twister_large_ctx_t ctx;
- twister_large_init(&ctx, 384);
- while(msg_length_b >=512){
- twister_large_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + 512/8;
- msg_length_b -= 512;
- }
- twister_large_lastBlock(&ctx, msg, msg_length_b);
- twister_large_ctx2hash(dest, &ctx, 384);
-}
-
-/*********************************************************************/
-/*********************************************************************/
-
-
-void twister512_init(twister512_ctx_t* ctx){
- twister_large_init(ctx, 512);
-}
-
-/*********************************************************************/
-
-void twister512_nextBlock(twister512_ctx_t* ctx, const void* msg){
- twister_large_nextBlock(ctx, msg);
-}
-
-/*********************************************************************/
-
-void twister512_lastBlock(twister512_ctx_t* ctx, const void* msg, uint16_t length_b){
- twister_large_lastBlock(ctx, msg, length_b);
-}
-
-/*********************************************************************/
-
-void twister512_ctx2hash(void* dest, twister512_ctx_t* ctx){
- twister_large_ctx2hash(dest, ctx, 512);
-}
-
-/*********************************************************************/
-
-void twister512(void* dest, const void* msg, uint32_t msg_length_b){
- twister_large_ctx_t ctx;
- twister_large_init(&ctx, 512);
- while(msg_length_b >=512){
- twister_large_nextBlock(&ctx, msg);
- msg = (uint8_t*)msg + 512/8;
- msg_length_b -= 512;
- }
- twister_large_lastBlock(&ctx, msg, msg_length_b);
- twister_large_ctx2hash(dest, &ctx, 512);
-}
-
-
-
+++ /dev/null
-/* twister-large.h */
-
-#ifndef TWISTER_large_H_
-#define TWISTER_large_H_
-
-#include <stdint.h>
-#include "twister.h"
-
-typedef uint8_t twister384_hash_t[384/8];
-typedef uint8_t twister512_hash_t[512/8];
-
-typedef struct {
- twister_state_t state;
- twister_checksum_t checksum;
-} twister_large_ctx_t;
-
-typedef twister_large_ctx_t twister384_ctx_t;
-typedef twister_large_ctx_t twister512_ctx_t;
-
-/*********************************************************************/
-
-void twister_large_nextBlock(twister_large_ctx_t* ctx, const void* msg);
-void twister_large_init(twister_large_ctx_t* ctx, uint16_t hashsize_b);
-void twister_large_lastBlock(twister_large_ctx_t* ctx, const void* msg, uint16_t length_b);
-void twister_large_ctx2hash(void* dest, twister_large_ctx_t* ctx, uint16_t hashsize_b);
-
-/*********************************************************************/
-
-void twister384_init(twister384_ctx_t* ctx);
-void twister384_nextBlock(twister384_ctx_t* ctx, const void* msg);
-void twister384_lastBlock(twister384_ctx_t* ctx, const void* msg, uint16_t length_b);
-void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx);
-void twister384(void* dest, const void* msg, uint32_t msg_length_b);
-
-/*********************************************************************/
-
-void twister512_init(twister512_ctx_t* ctx);
-void twister512_nextBlock(twister512_ctx_t* ctx, const void* msg);
-void twister512_lastBlock(twister512_ctx_t* ctx, const void* msg, uint16_t length_b);
-void twister512_ctx2hash(void* dest, twister512_ctx_t* ctx);
-void twister512(void* dest, const void* msg, uint32_t msg_length_b);
-
-
-#endif /* TWISTER_large_H_ */
-
+++ /dev/null
-/* twister-sha3api.c */
-
-#include "sha3-api.h"
-#include "twister-sha3api.h"
-#include "twister.h"
-#include "twister-small.h"
-#include "twister-big.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define BLOCKSIZE 512
-
-HashReturn Init(hashState *state, int hashbitlen){
- if(!state)
- return FAIL;
- if(hashbitlen<32 || hashbitlen>512 || hashbitlen%32)
- return BAD_HASHBITLEN;
-
- if (hashbitlen>=32 && hashbitlen<=256){
- state->hashbitlen = hashbitlen;
- state->big = 0;
- state->ctx = malloc(sizeof(twister_state_t));
- twister_small_init(state->ctx, hashbitlen);
- state->buffer_fill_state=0;
- memset(state->buffer, 0, 64);
- return SUCCESS;
- }
- if (hashbitlen>256 && hashbitlen<=512){
- state->hashbitlen = hashbitlen;
- state->big = 1;
- state->ctx = malloc(sizeof(twister_big_ctx_t));
- twister_big_init(state->ctx, hashbitlen);
- state->buffer_fill_state=0;
- memset(state->buffer, 0, 64);
- return SUCCESS;
- }
- return BAD_HASHBITLEN;
-}
-
-void insertBitToBuffer(hashState *state, uint8_t bit){
- state->buffer[state->buffer_fill_state/8] |=
- bit<<(7-(state->buffer_fill_state%8));
- state->buffer_fill_state++;
-}
-
-
-HashReturn Update(hashState *state, const BitSequence *data,
- DataLength databitlen){
- if(state->buffer_fill_state+databitlen<BLOCKSIZE){
- /* move bits from data to buffer */
- uint16_t i;
- for(i=0; i<databitlen; ++i){
- insertBitToBuffer(state, 1&((data[i/8])>>(7-i%8)));
- }
- return SUCCESS;
- }
- if(state->buffer_fill_state==0){
- while(databitlen>=512){
- if(state->big){
- twister_big_nextBlock(state->ctx, data);
- }else{
- twister_small_nextBlock(state->ctx, data);
- }
- data += 64;
- databitlen -= 512;
- }
- if(databitlen!=0)
- Update(state, data, databitlen);
- return SUCCESS;
- }else{
- DataLength i;
- for(i=0; i<databitlen; ++i){
- if(state->buffer_fill_state==512){
- if(state->big){
- twister_big_nextBlock(state->ctx, state->buffer);
- }else{
- twister_small_nextBlock(state->ctx, state->buffer);
- }
- memset(state->buffer, 0, 64);
- state->buffer_fill_state = 0;
- }
- insertBitToBuffer(state, 1&(data[i/8]>>(7-i%8)));
- }
- return SUCCESS;
- }
- return FAIL;
-}
-
-HashReturn Final(hashState *state, BitSequence *hashval){
- if(state->big){
- twister_big_lastBlock(state->ctx, state->buffer, state->buffer_fill_state);
- twister_big_ctx2hash(hashval, state->ctx, state->hashbitlen);
- return SUCCESS;
- }else{
- twister_small_lastBlock(state->ctx, state->buffer, state->buffer_fill_state);
- twister_small_ctx2hash(hashval, state->ctx, state->hashbitlen);
- return SUCCESS;
- }
-}
-
-HashReturn Hash(int hashbitlen, const BitSequence *data,
- DataLength databitlen, BitSequence *hashval){
- HashReturn ret;
- hashState state;
- ret = Init(&state, hashbitlen);
- if(ret!=SUCCESS)
- return ret;
- ret = Update(&state, data, databitlen);
- if(ret!=SUCCESS)
- return ret;
- return Final(&state, hashval);
-}
-
+++ /dev/null
-/* twister-sha3api.h */
-
-#include "sha3-api.h"
-#include <stdint.h>
-
-typedef struct{
- uint16_t hashbitlen;
- uint8_t big;
- void* ctx; /* points either to twister_state_t or twister_big_ctx_t */
- uint8_t buffer[64];
- uint16_t buffer_fill_state;
-}hashState;
-
-HashReturn Init(hashState *state, int hashbitlen);
-HashReturn Update(hashState *state, const BitSequence *data,
- DataLength databitlen);
-HashReturn Final(hashState *state, BitSequence *hashval);
-HashReturn Hash(int hashbitlen, const BitSequence *data,
- DataLength databitlen, BitSequence *hashval);
-
+++ /dev/null
-/* twister-small-asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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
-31:
- st Z+, r0
- ld r0, X+
- dec r18
- brne 31b
-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
-
- tst r19
- breq 7f
-6:
- st Z+, r1
- dec r19
- brne 6b
-7:
- 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
+++ /dev/null
-/* twister-small.c */
-
-#include <stdint.h>
-#include <string.h>
-#include "memxor.h"
-#include "twister-small.h"
-
-/*********************************************************************/
-
-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, const 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;
-}
-
-/*********************************************************************/
-
-void twister_small_lastBlock(twister_state_t* ctx, const 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 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, const void* msg){
- twister_small_nextBlock(ctx, msg);
-}
-
-/*********************************************************************/
-
-void twister256_lastBlock(twister256_ctx_t* ctx, const void* msg, uint16_t length_b){
- twister_small_lastBlock(ctx, msg, length_b);
-}
-
-/*********************************************************************/
-
-void twister256_ctx2hash(void* dest, twister256_ctx_t* ctx){
- twister_ctx2hash(dest, ctx, 256);
-}
-
-/*********************************************************************/
-
-void twister256(void* dest, const 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, const void* msg){
- twister_small_nextBlock(ctx, msg);
-}
-
-/*********************************************************************/
-
-void twister224_lastBlock(twister224_ctx_t* ctx, const void* msg, uint16_t length_b){
- twister_small_lastBlock(ctx, msg, length_b);
-}
-
-/*********************************************************************/
-
-void twister224_ctx2hash(void* dest, twister224_ctx_t* ctx){
- twister_ctx2hash(dest, ctx, 224);
-}
-
-/*********************************************************************/
-
-void twister224(void* dest, const 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
-
+++ /dev/null
-/* twister-small.h */
-
-#ifndef TWISTER_SMALL_H_
-#define TWISTER_SMALL_H_
-
-#include <stdint.h>
-#include "twister.h"
-
-typedef uint8_t twister256_hash_t[256/8];
-typedef uint8_t twister224_hash_t[224/8];
-
-typedef twister_state_t twister256_ctx_t;
-typedef twister_state_t twister224_ctx_t;
-
-void twister_small_init(twister_state_t* ctx, uint16_t hashsize_b);
-void twister_small_lastBlock(twister_state_t* ctx, const void* msg, uint16_t length_b);
-void twister_small_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b);
-void twister_small_nextBlock(twister_state_t* ctx, const void* msg);
-
-
-void twister256_init(twister256_ctx_t* ctx);
-void twister256_nextBlock(twister256_ctx_t* ctx, const void* msg);
-void twister256_lastBlock(twister256_ctx_t* ctx, const void* msg, uint16_t length_b);
-void twister256_ctx2hash(void* dest, twister_state_t* ctx);
-void twister256(void* dest, const void* msg, uint32_t msg_length_b);
-
-void twister224_init(twister224_ctx_t* ctx);
-void twister224_nextBlock(twister224_ctx_t* ctx, const void* msg);
-void twister224_lastBlock(twister224_ctx_t* ctx, const void* msg, uint16_t length_b);
-void twister224_ctx2hash(void* dest, twister224_ctx_t* ctx);
-void twister224(void* dest, const void* msg, uint32_t msg_length_b);
-
-#endif /* TWISTER_SMALL_H_ */
+++ /dev/null
-/* twister.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "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
-
-#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;
- uint8_t tmp[8][8];
- /* add twist counter */
- for(i=0; i<8; ++i){
- ctx->s[i][1] ^= ((uint8_t*)&(ctx->counter))[7-i];
- }
- ctx->counter--;
- /* 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]);
- }
- }
- /* mix columns with integrates shift rows */
- 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]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,1), (tmp[1][k]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,2), (tmp[2][((++k)&7)]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,3), (tmp[3][((++k)&7)]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,4), (tmp[4][((++k)&7)]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,5), (tmp[5][((++k)&7)]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,6), (tmp[6][((++k)&7)]) );
- ctx->s[j][i] ^=
- MULT( MDS(j,7), (tmp[7][((++k)&7)]) );
-
- }
- }
-}
-void twister_mini_round(twister_state_t* ctx, const 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);
-}
-
-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;
- }
- }
-}
-
-
+++ /dev/null
-/* twister.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file twister.h
- * \author Daniel Otte
- * \date 2008-12-20
- * \license GPLv3 or later
- *
- */
-
-#ifndef TWISTER_H_
-#define TWISTER_H_
-
-#include <stdint.h>
-
-typedef struct {
- uint8_t s[8][8];
- uint64_t counter;
- uint64_t length_counter_b;
-} twister_state_t;
-
-typedef uint8_t twister_checksum_t[8][8];
-
-void twister_blank_round(twister_state_t* ctx);
-void twister_mini_round(twister_state_t* ctx, const void* msg);
-void twister_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b);
-
-#endif /* TWISTER_H_ */
--- /dev/null
+/* gf256mul.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: gf256mul.S
+ * Author: Daniel Otte
+ * Date: 2008-12-19
+ * License: GPLv3 or later
+ * Description: peasant's algorithm for multiplication in GF(2^8)
+ *
+ */
+
+#include <avr/io.h>
+#define OPTIMIZE_SMALL_A
+
+/*
+ * param a: r24
+ * param b: r22
+ * param reducer: r20
+ */
+A = 23
+B = 22
+P = 24
+.global gf256mul
+
+#ifdef OPTIMIZE_SMALL_A
+gf256mul:
+ mov A, r24
+ clr r24
+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
+
+#else
+
+gf256mul:
+ mov r21, r24
+ clr r24
+ ldi r25, 8
+1:
+ lsr A
+ brcc 2f
+ eor P, B
+2:
+ lsl B
+ brcc 3f
+ eor B, r20
+3:
+ dec r25
+ brne 1b
+ ret
+
+#endif
--- /dev/null
+/* gf256mul.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GF256MUL_H_
+#define GF256MUL_H_
+
+/**
+ * \author Daniel Otte
+ * \email daniel.otte@rub.de
+ * \date 2008-12-19
+ * \license GPLv3
+ * \brief
+ *
+ *
+ */
+
+#include <stdint.h>
+
+uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
+
+#endif /* GF256MUL_H_ */
+
--- /dev/null
+/* memxor.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File: memxor.S
+ * Author: Daniel Otte
+ * Date: 2008-08-07
+ * License: GPLv3 or later
+ * Description: memxor, XORing one block into another
+ *
+ */
+
+/*
+ * void memxor(void* dest, const void* src, uint16_t n);
+ */
+ /*
+ * param dest is passed in r24:r25
+ * param src is passed in r22:r23
+ * param n is passed in r20:r21
+ */
+.global memxor
+memxor:
+ movw r30, r24
+ movw r26, r22
+ movw r24, r20
+ adiw r24, 0
+ breq 2f
+1:
+ ld r20, X+
+ ld r21, Z
+ eor r20, r21
+ st Z+, r20
+ sbiw r24, 1
+ brne 1b
+2:
+ ret
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef MEMXOR_H_
+#define MEMXOR_H_
+#include <stdint.h>
+
+void memxor(void* dest, const void* src, uint16_t n);
+
+#endif
--- /dev/null
+/* twister-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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_large_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_large_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-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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
+ *
+ */
+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
+IDX1 = 18
+IDX2 = 19
+TMP = 21
+.global twister_blank_round
+twister_blank_round:
+ push_range 4, 17
+ push r28
+ push r29
+ stack_alloc_large 64, r28, r29
+
+ 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
+ ldi r20, lo8(twister_sbox)
+ ldi r21, hi8(twister_sbox)
+ ldi r19, 64
+
+1: /* sbox substitution */
+ ld r0, X+
+ movw r30, r20
+ add r30, r0
+ adc r31, r1
+ lpm r0, Z
+ st Y+, r0
+ dec r19
+ brne 1b
+
+ /* load MDS-Table to MDS0:MDS7 */
+/*
+ ldi r18, 1
+ mov MDS1, r18
+ mov MDS6, r18
+ mov MDS7, r18
+ ldi r18, 2
+ mov MDS0, r18
+ ldi r18, 5
+ mov MDS5, r18
+ ldi r18, 6
+ mov MDS2, r18
+ ldi r18, 7
+ mov MDS4, r18
+ ldi r18, 8
+ mov MDS3, r18
+*/
+ 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
+; sbiw r28, 63
+; sbiw r28, 1 /* Y points again at tmp buffer */
+; movw Y_SAVE0, r28
+; sbiw r26, 63
+; sbiw r26, 1 /* X points again at state buffer */
+ movw X_SAVE0, r24
+
+ ldi r20, 0x4D /* reducer for gf256mul*/
+ ldi r16, 0
+
+; rjmp 9f
+1:
+ mov IDX1, r16
+ movw r26, X_SAVE0
+ add r26, r16
+ adc r27, r1
+ ldi r17, 0
+2:
+ mov IDX2, r17
+
+ mov r24, MDS0
+ movw r28, Y_SAVE0
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ mov r0, r24
+
+ mov r24, MDS1
+ movw r28, Y_SAVE0
+ adiw r28, 8
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS2
+ movw r28, Y_SAVE0
+ adiw r28, 8*2
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS3
+ movw r28, Y_SAVE0
+ adiw r28, 8*3
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS4
+ movw r28, Y_SAVE0
+ adiw r28, 8*4
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS5
+ movw r28, Y_SAVE0
+ adiw r28, 8*5
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS6
+ movw r28, Y_SAVE0
+ adiw r28, 8*6
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ mov r24, MDS7
+ movw r28, Y_SAVE0
+ adiw r28, 8*7
+ inc IDX1
+ andi IDX1, 0x07
+ add r28, IDX1
+ adc r29, r1
+ ld r22, Y
+ rcall gf256mul
+ eor r0, r24
+
+ st X, r0
+ adiw r26, 8
+/*
+ mov r0, MDS0
+ mov MDS0, MDS1
+ mov MDS1, MDS2
+ mov MDS2, MDS3
+ mov MDS3, MDS4
+ mov MDS4, MDS5
+ mov MDS5, MDS6
+ mov MDS6, MDS7
+ mov MDS7, r0
+*/
+ 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
+
+ cpi r17, 7
+ breq 8f
+ inc r17
+ rjmp 2b
+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
+
+ cpi r16, 7
+ breq 9f
+ inc r16
+ rjmp 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
+
+
+
+
+
+
+
+
--- /dev/null
+/* twister-large-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file twister-large-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_large_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_large_init(twister_large_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_large_init
+
+.global twister512_init
+twister512_init:
+ ldi r22, lo8(512)
+ ldi r23, hi8(512)
+
+.global twister_large_init
+twister_large_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_large_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_large_nextBlock
+.global twister384_nextBlock
+.global twister512_nextBlock
+
+twister384_nextBlock:
+twister512_nextBlock:
+twister_large_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_large_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_large_lastBlock
+.global twister384_lastBlock
+.global twister512_lastBlock
+
+twister384_lastBlock:
+twister512_lastBlock:
+twister_large_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_large_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
+31:
+ st Z+, r0
+ ld r0, X+
+ dec r18
+ brne 31b
+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
+ tst r19
+ breq 7f
+6:
+ st Z+, r1
+ dec r19
+ brne 6b
+7:
+ movw r24, CTX_SAVE0
+ movw r22, TMP_SAVE0
+ rcall twister_large_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
--- /dev/null
+/* twister-large.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include "memxor.h"
+#include "twister.h"
+#include "twister-large.h"
+
+/*********************************************************************/
+
+static
+void checksum_update(twister_large_ctx_t* ctx, uint8_t col){
+ uint8_t i, col2;
+ uint8_t carry = 0;
+ int sum = 0;
+
+ col2 = (col+1)%8;
+
+ for( i=0; i<8; i++ )
+ {
+ sum = (int) ctx->checksum[col2][7-i]
+ + (int) ctx->state.s[7-i][0] /* col or 0 ???*/
+ + carry;
+ ctx->checksum[col][7-i] ^= (uint8_t)sum;
+ carry = sum>>8;
+
+ }
+}
+
+/*********************************************************************/
+
+void twister_large_init(twister_large_ctx_t* ctx, uint16_t hashsize_b){
+ memset(ctx->state.s, 0, 64);
+ memset(ctx->checksum, 0, 64);
+ ctx->state.counter=0xffffffffffffffffLL;
+ ctx->state.s[0][7] = hashsize_b>>8;
+ ctx->state.s[1][7] = hashsize_b&0xff;
+ ctx->state.length_counter_b = 0;
+}
+
+/*********************************************************************/
+
+void twister_large_nextBlock(twister_large_ctx_t* ctx, const void* msg){
+ uint8_t tmp[8][8];
+
+ /* 1st maxi round */
+ memcpy(tmp, ctx->state.s, 64);
+ checksum_update(ctx, 0);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+
+ checksum_update(ctx, 1);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+
+ checksum_update(ctx, 2);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+ memxor(ctx->state.s, tmp, 64);
+
+ /* 2nd maxi round */
+ memcpy(tmp, ctx->state.s, 64);
+ checksum_update(ctx, 3);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+
+ twister_blank_round(&(ctx->state));
+
+ checksum_update(ctx, 4);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+ memxor(ctx->state.s, tmp, 64);
+
+ /* 3rd maxi round */
+ memcpy(tmp, ctx->state.s, 64);
+ checksum_update(ctx, 5);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+
+ checksum_update(ctx, 6);
+ twister_mini_round(&(ctx->state), msg);
+ msg = (uint8_t*)msg + 8;
+
+ checksum_update(ctx, 7);
+ twister_mini_round(&(ctx->state), msg);
+
+ twister_blank_round(&(ctx->state));
+ memxor(ctx->state.s, tmp, 64);
+ ctx->state.length_counter_b += 512;
+}
+
+/*********************************************************************/
+
+void twister_inject_chksum(twister_large_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_large_lastBlock(twister_large_ctx_t* ctx, const void* msg, uint16_t length_b){
+ uint8_t tmp[64];
+ while(length_b>=512){
+ twister_large_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_large_nextBlock(ctx, tmp);
+ ctx->state.length_counter_b -= 512 - length_b;
+ twister_mini_round(&(ctx->state), &(ctx->state.length_counter_b));
+
+ memcpy(tmp, ctx->state.s, 64);
+ twister_inject_chksum(ctx, 0);
+ twister_inject_chksum(ctx, 1);
+ twister_inject_chksum(ctx, 2);
+ memxor(ctx->state.s, tmp, 64);
+
+ memcpy(tmp, ctx->state.s, 64);
+ twister_inject_chksum(ctx, 3);
+ twister_inject_chksum(ctx, 4);
+ twister_inject_chksum(ctx, 5);
+ memxor(ctx->state.s, tmp, 64);
+
+ memcpy(tmp, ctx->state.s, 64);
+ twister_inject_chksum(ctx, 6);
+ twister_inject_chksum(ctx, 7);
+ twister_blank_round(&(ctx->state));
+ memxor(ctx->state.s, tmp, 64);
+
+}
+
+/*********************************************************************/
+
+void twister_large_ctx2hash(void* dest, twister_large_ctx_t* ctx, uint16_t hashsize_b){
+ twister_ctx2hash(dest, &(ctx->state), hashsize_b);
+}
+
+/*********************************************************************/
+/*********************************************************************/
+
+void twister384_init(twister384_ctx_t* ctx){
+ twister_large_init(ctx, 384);
+}
+
+/*********************************************************************/
+
+void twister384_nextBlock(twister384_ctx_t* ctx, const void* msg){
+ twister_large_nextBlock(ctx, msg);
+}
+
+/*********************************************************************/
+
+void twister384_lastBlock(twister384_ctx_t* ctx, const void* msg, uint16_t length_b){
+ twister_large_lastBlock(ctx, msg, length_b);
+}
+
+/*********************************************************************/
+
+void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx){
+ twister_large_ctx2hash(dest, ctx, 384);
+}
+
+/*********************************************************************/
+
+void twister384(void* dest, const void* msg, uint32_t msg_length_b){
+ twister_large_ctx_t ctx;
+ twister_large_init(&ctx, 384);
+ while(msg_length_b >=512){
+ twister_large_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + 512/8;
+ msg_length_b -= 512;
+ }
+ twister_large_lastBlock(&ctx, msg, msg_length_b);
+ twister_large_ctx2hash(dest, &ctx, 384);
+}
+
+/*********************************************************************/
+/*********************************************************************/
+
+
+void twister512_init(twister512_ctx_t* ctx){
+ twister_large_init(ctx, 512);
+}
+
+/*********************************************************************/
+
+void twister512_nextBlock(twister512_ctx_t* ctx, const void* msg){
+ twister_large_nextBlock(ctx, msg);
+}
+
+/*********************************************************************/
+
+void twister512_lastBlock(twister512_ctx_t* ctx, const void* msg, uint16_t length_b){
+ twister_large_lastBlock(ctx, msg, length_b);
+}
+
+/*********************************************************************/
+
+void twister512_ctx2hash(void* dest, twister512_ctx_t* ctx){
+ twister_large_ctx2hash(dest, ctx, 512);
+}
+
+/*********************************************************************/
+
+void twister512(void* dest, const void* msg, uint32_t msg_length_b){
+ twister_large_ctx_t ctx;
+ twister_large_init(&ctx, 512);
+ while(msg_length_b >=512){
+ twister_large_nextBlock(&ctx, msg);
+ msg = (uint8_t*)msg + 512/8;
+ msg_length_b -= 512;
+ }
+ twister_large_lastBlock(&ctx, msg, msg_length_b);
+ twister_large_ctx2hash(dest, &ctx, 512);
+}
+
+
+
--- /dev/null
+/* twister-large.h */
+
+#ifndef TWISTER_large_H_
+#define TWISTER_large_H_
+
+#include <stdint.h>
+#include "twister.h"
+
+typedef uint8_t twister384_hash_t[384/8];
+typedef uint8_t twister512_hash_t[512/8];
+
+typedef struct {
+ twister_state_t state;
+ twister_checksum_t checksum;
+} twister_large_ctx_t;
+
+typedef twister_large_ctx_t twister384_ctx_t;
+typedef twister_large_ctx_t twister512_ctx_t;
+
+/*********************************************************************/
+
+void twister_large_nextBlock(twister_large_ctx_t* ctx, const void* msg);
+void twister_large_init(twister_large_ctx_t* ctx, uint16_t hashsize_b);
+void twister_large_lastBlock(twister_large_ctx_t* ctx, const void* msg, uint16_t length_b);
+void twister_large_ctx2hash(void* dest, twister_large_ctx_t* ctx, uint16_t hashsize_b);
+
+/*********************************************************************/
+
+void twister384_init(twister384_ctx_t* ctx);
+void twister384_nextBlock(twister384_ctx_t* ctx, const void* msg);
+void twister384_lastBlock(twister384_ctx_t* ctx, const void* msg, uint16_t length_b);
+void twister384_ctx2hash(void* dest, twister384_ctx_t* ctx);
+void twister384(void* dest, const void* msg, uint32_t msg_length_b);
+
+/*********************************************************************/
+
+void twister512_init(twister512_ctx_t* ctx);
+void twister512_nextBlock(twister512_ctx_t* ctx, const void* msg);
+void twister512_lastBlock(twister512_ctx_t* ctx, const void* msg, uint16_t length_b);
+void twister512_ctx2hash(void* dest, twister512_ctx_t* ctx);
+void twister512(void* dest, const void* msg, uint32_t msg_length_b);
+
+
+#endif /* TWISTER_large_H_ */
+
--- /dev/null
+/* twister-sha3api.c */
+
+#include "sha3-api.h"
+#include "twister-sha3api.h"
+#include "twister.h"
+#include "twister-small.h"
+#include "twister-big.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define BLOCKSIZE 512
+
+HashReturn Init(hashState *state, int hashbitlen){
+ if(!state)
+ return FAIL;
+ if(hashbitlen<32 || hashbitlen>512 || hashbitlen%32)
+ return BAD_HASHBITLEN;
+
+ if (hashbitlen>=32 && hashbitlen<=256){
+ state->hashbitlen = hashbitlen;
+ state->big = 0;
+ state->ctx = malloc(sizeof(twister_state_t));
+ twister_small_init(state->ctx, hashbitlen);
+ state->buffer_fill_state=0;
+ memset(state->buffer, 0, 64);
+ return SUCCESS;
+ }
+ if (hashbitlen>256 && hashbitlen<=512){
+ state->hashbitlen = hashbitlen;
+ state->big = 1;
+ state->ctx = malloc(sizeof(twister_big_ctx_t));
+ twister_big_init(state->ctx, hashbitlen);
+ state->buffer_fill_state=0;
+ memset(state->buffer, 0, 64);
+ return SUCCESS;
+ }
+ return BAD_HASHBITLEN;
+}
+
+void insertBitToBuffer(hashState *state, uint8_t bit){
+ state->buffer[state->buffer_fill_state/8] |=
+ bit<<(7-(state->buffer_fill_state%8));
+ state->buffer_fill_state++;
+}
+
+
+HashReturn Update(hashState *state, const BitSequence *data,
+ DataLength databitlen){
+ if(state->buffer_fill_state+databitlen<BLOCKSIZE){
+ /* move bits from data to buffer */
+ uint16_t i;
+ for(i=0; i<databitlen; ++i){
+ insertBitToBuffer(state, 1&((data[i/8])>>(7-i%8)));
+ }
+ return SUCCESS;
+ }
+ if(state->buffer_fill_state==0){
+ while(databitlen>=512){
+ if(state->big){
+ twister_big_nextBlock(state->ctx, data);
+ }else{
+ twister_small_nextBlock(state->ctx, data);
+ }
+ data += 64;
+ databitlen -= 512;
+ }
+ if(databitlen!=0)
+ Update(state, data, databitlen);
+ return SUCCESS;
+ }else{
+ DataLength i;
+ for(i=0; i<databitlen; ++i){
+ if(state->buffer_fill_state==512){
+ if(state->big){
+ twister_big_nextBlock(state->ctx, state->buffer);
+ }else{
+ twister_small_nextBlock(state->ctx, state->buffer);
+ }
+ memset(state->buffer, 0, 64);
+ state->buffer_fill_state = 0;
+ }
+ insertBitToBuffer(state, 1&(data[i/8]>>(7-i%8)));
+ }
+ return SUCCESS;
+ }
+ return FAIL;
+}
+
+HashReturn Final(hashState *state, BitSequence *hashval){
+ if(state->big){
+ twister_big_lastBlock(state->ctx, state->buffer, state->buffer_fill_state);
+ twister_big_ctx2hash(hashval, state->ctx, state->hashbitlen);
+ return SUCCESS;
+ }else{
+ twister_small_lastBlock(state->ctx, state->buffer, state->buffer_fill_state);
+ twister_small_ctx2hash(hashval, state->ctx, state->hashbitlen);
+ return SUCCESS;
+ }
+}
+
+HashReturn Hash(int hashbitlen, const BitSequence *data,
+ DataLength databitlen, BitSequence *hashval){
+ HashReturn ret;
+ hashState state;
+ ret = Init(&state, hashbitlen);
+ if(ret!=SUCCESS)
+ return ret;
+ ret = Update(&state, data, databitlen);
+ if(ret!=SUCCESS)
+ return ret;
+ return Final(&state, hashval);
+}
+
--- /dev/null
+/* twister-sha3api.h */
+
+#include "sha3-api.h"
+#include <stdint.h>
+
+typedef struct{
+ uint16_t hashbitlen;
+ uint8_t big;
+ void* ctx; /* points either to twister_state_t or twister_big_ctx_t */
+ uint8_t buffer[64];
+ uint16_t buffer_fill_state;
+}hashState;
+
+HashReturn Init(hashState *state, int hashbitlen);
+HashReturn Update(hashState *state, const BitSequence *data,
+ DataLength databitlen);
+HashReturn Final(hashState *state, BitSequence *hashval);
+HashReturn Hash(int hashbitlen, const BitSequence *data,
+ DataLength databitlen, BitSequence *hashval);
+
--- /dev/null
+/* twister-small-asm.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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
+31:
+ st Z+, r0
+ ld r0, X+
+ dec r18
+ brne 31b
+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
+
+ tst r19
+ breq 7f
+6:
+ st Z+, r1
+ dec r19
+ brne 6b
+7:
+ 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
--- /dev/null
+/* twister-small.c */
+
+#include <stdint.h>
+#include <string.h>
+#include "memxor.h"
+#include "twister-small.h"
+
+/*********************************************************************/
+
+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, const 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;
+}
+
+/*********************************************************************/
+
+void twister_small_lastBlock(twister_state_t* ctx, const 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 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, const void* msg){
+ twister_small_nextBlock(ctx, msg);
+}
+
+/*********************************************************************/
+
+void twister256_lastBlock(twister256_ctx_t* ctx, const void* msg, uint16_t length_b){
+ twister_small_lastBlock(ctx, msg, length_b);
+}
+
+/*********************************************************************/
+
+void twister256_ctx2hash(void* dest, twister256_ctx_t* ctx){
+ twister_ctx2hash(dest, ctx, 256);
+}
+
+/*********************************************************************/
+
+void twister256(void* dest, const 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, const void* msg){
+ twister_small_nextBlock(ctx, msg);
+}
+
+/*********************************************************************/
+
+void twister224_lastBlock(twister224_ctx_t* ctx, const void* msg, uint16_t length_b){
+ twister_small_lastBlock(ctx, msg, length_b);
+}
+
+/*********************************************************************/
+
+void twister224_ctx2hash(void* dest, twister224_ctx_t* ctx){
+ twister_ctx2hash(dest, ctx, 224);
+}
+
+/*********************************************************************/
+
+void twister224(void* dest, const 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
+
--- /dev/null
+/* twister-small.h */
+
+#ifndef TWISTER_SMALL_H_
+#define TWISTER_SMALL_H_
+
+#include <stdint.h>
+#include "twister.h"
+
+typedef uint8_t twister256_hash_t[256/8];
+typedef uint8_t twister224_hash_t[224/8];
+
+typedef twister_state_t twister256_ctx_t;
+typedef twister_state_t twister224_ctx_t;
+
+void twister_small_init(twister_state_t* ctx, uint16_t hashsize_b);
+void twister_small_lastBlock(twister_state_t* ctx, const void* msg, uint16_t length_b);
+void twister_small_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b);
+void twister_small_nextBlock(twister_state_t* ctx, const void* msg);
+
+
+void twister256_init(twister256_ctx_t* ctx);
+void twister256_nextBlock(twister256_ctx_t* ctx, const void* msg);
+void twister256_lastBlock(twister256_ctx_t* ctx, const void* msg, uint16_t length_b);
+void twister256_ctx2hash(void* dest, twister_state_t* ctx);
+void twister256(void* dest, const void* msg, uint32_t msg_length_b);
+
+void twister224_init(twister224_ctx_t* ctx);
+void twister224_nextBlock(twister224_ctx_t* ctx, const void* msg);
+void twister224_lastBlock(twister224_ctx_t* ctx, const void* msg, uint16_t length_b);
+void twister224_ctx2hash(void* dest, twister224_ctx_t* ctx);
+void twister224(void* dest, const void* msg, uint32_t msg_length_b);
+
+#endif /* TWISTER_SMALL_H_ */
--- /dev/null
+ === Twister-224 performance ===
+ type: hashfunction
+ hashsize (bits): 224
+ ctxsize (bytes): 80
+ blocksize (bits): 512
+ init (cycles): 480
+ nextBlock (cycles): 36528
+ lastBlock (cycles): 8071
+ ctx2hash (cycles): 19377
+
+ === Twister-256 performance ===
+ type: hashfunction
+ hashsize (bits): 256
+ ctxsize (bytes): 80
+ blocksize (bits): 512
+ init (cycles): 425
+ nextBlock (cycles): 36535
+ lastBlock (cycles): 8064
+ ctx2hash (cycles): 19438
+
+ === Twister-384 performance ===
+ type: hashfunction
+ hashsize (bits): 384
+ ctxsize (bytes): 144
+ blocksize (bits): 512
+ init (cycles): 745
+ nextBlock (cycles): 55707
+ lastBlock (cycles): 42573
+ ctx2hash (cycles): 27212
+
+ === Twister-512 performance ===
+ type: hashfunction
+ hashsize (bits): 512
+ ctxsize (bytes): 144
+ blocksize (bits): 512
+ init (cycles): 743
+ nextBlock (cycles): 55707
+ lastBlock (cycles): 42573
+ ctx2hash (cycles): 35203
+
--- /dev/null
+/* twister.c */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "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
+
+#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;
+ uint8_t tmp[8][8];
+ /* add twist counter */
+ for(i=0; i<8; ++i){
+ ctx->s[i][1] ^= ((uint8_t*)&(ctx->counter))[7-i];
+ }
+ ctx->counter--;
+ /* 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]);
+ }
+ }
+ /* mix columns with integrates shift rows */
+ 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]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,1), (tmp[1][k]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,2), (tmp[2][((++k)&7)]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,3), (tmp[3][((++k)&7)]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,4), (tmp[4][((++k)&7)]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,5), (tmp[5][((++k)&7)]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,6), (tmp[6][((++k)&7)]) );
+ ctx->s[j][i] ^=
+ MULT( MDS(j,7), (tmp[7][((++k)&7)]) );
+
+ }
+ }
+}
+void twister_mini_round(twister_state_t* ctx, const 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);
+}
+
+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;
+ }
+ }
+}
+
+
--- /dev/null
+/* twister.h */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file twister.h
+ * \author Daniel Otte
+ * \date 2008-12-20
+ * \license GPLv3 or later
+ *
+ */
+
+#ifndef TWISTER_H_
+#define TWISTER_H_
+
+#include <stdint.h>
+
+typedef struct {
+ uint8_t s[8][8];
+ uint64_t counter;
+ uint64_t length_counter_b;
+} twister_state_t;
+
+typedef uint8_t twister_checksum_t[8][8];
+
+void twister_blank_round(twister_state_t* ctx);
+void twister_mini_round(twister_state_t* ctx, const void* msg);
+void twister_ctx2hash(void* dest, twister_state_t* ctx, uint16_t hashsize_b);
+
+#endif /* TWISTER_H_ */
--- /dev/null
+/* twister224.S */
+/*
+ This file is part of the AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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 AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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 AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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_large_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_large_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_large_lastBlock
+
+ movw r24, DST_SAVE0
+ movw r22, CTX_SAVE0
+ ldi r20, lo8(384)
+ ldi r21, hi8(384)
+ rcall twister_large_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 AVR-Crypto-Lib.
+ Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file 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_large_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_large_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_large_lastBlock
+
+ movw r24, DST_SAVE0
+ movw r22, CTX_SAVE0
+ ldi r20, lo8(512)
+ ldi r21, hi8(512)
+ rcall twister_large_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_ */
--- /dev/null
+/******************************************************************
+ * S-BOX for Twister
+ *
+ *
+ *******************************************************************/
+
+#include "config.h"
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+static const uint8_t twister_sbox[256] PROGMEM = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+#ifndef TWISTER_MUL_TABLE
+
+
+/* Twister MDS matrix */
+static const uint8_t twister_mds[8][8] PROGMEM = {
+ {2, 1, 1, 5, 7, 8, 6, 1},
+ {1, 2, 1, 1, 5, 7, 8, 6},
+ {6, 1, 2, 1, 1, 5, 7, 8},
+ {8, 6, 1, 2, 1, 1, 5, 7},
+ {7, 8, 6, 1, 2, 1, 1, 5},
+ {5, 7, 8, 6, 1, 2, 1, 1},
+ {1, 5, 7, 8, 6, 1, 2, 1},
+ {1, 1, 5, 7, 8, 6, 1, 2}
+};
+
+#else
+
+#define S1 0
+#define S2 1
+#define S3 X
+#define S4 X
+#define S5 2
+#define S6 3
+#define S7 4
+#define S8 5
+
+static const uint8_t twister_mds[8][8] PROGMEM = {
+ {S2, S1, S1, S5, S7, S8, S6, S1},
+ {S1, S2, S1, S1, S5, S7, S8, S6},
+ {S6, S1, S2, S1, S1, S5, S7, S8},
+ {S8, S6, S1, S2, S1, S1, S5, S7},
+ {S7, S8, S6, S1, S2, S1, S1, S5},
+ {S5, S7, S8, S6, S1, S2, S1, S1},
+ {S1, S5, S7, S8, S6, S1, S2, S1},
+ {S1, S1, S5, S7, S8, S6, S1, S2}
+};
+
+static const uint8_t twister_multab[8][256] PROGMEM = {
+ { /* 1 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+ },
+ { /* 2 */
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
+ 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
+ 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
+ 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
+ 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254,
+ 77, 79, 73, 75, 69, 71, 65, 67, 93, 95, 89, 91, 85, 87, 81, 83,
+ 109, 111, 105, 107, 101, 103, 97, 99, 125, 127, 121, 123, 117, 119, 113, 115,
+ 13, 15, 9, 11, 5, 7, 1, 3, 29, 31, 25, 27, 21, 23, 17, 19,
+ 45, 47, 41, 43, 37, 39, 33, 35, 61, 63, 57, 59, 53, 55, 49, 51,
+ 205, 207, 201, 203, 197, 199, 193, 195, 221, 223, 217, 219, 213, 215, 209, 211,
+ 237, 239, 233, 235, 229, 231, 225, 227, 253, 255, 249, 251, 245, 247, 241, 243,
+ 141, 143, 137, 139, 133, 135, 129, 131, 157, 159, 153, 155, 149, 151, 145, 147,
+ 173, 175, 169, 171, 165, 167, 161, 163, 189, 191, 185, 187, 181, 183, 177, 179
+ },
+/* { / * 3 * /
+ 0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17,
+ 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33,
+ 96, 99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113,
+ 80, 83, 86, 85, 92, 95, 90, 89, 72, 75, 78, 77, 68, 71, 66, 65,
+ 192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209,
+ 240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225,
+ 160, 163, 166, 165, 172, 175, 170, 169, 184, 187, 190, 189, 180, 183, 178, 177,
+ 144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129,
+ 205, 206, 203, 200, 193, 194, 199, 196, 213, 214, 211, 208, 217, 218, 223, 220,
+ 253, 254, 251, 248, 241, 242, 247, 244, 229, 230, 227, 224, 233, 234, 239, 236,
+ 173, 174, 171, 168, 161, 162, 167, 164, 181, 182, 179, 176, 185, 186, 191, 188,
+ 157, 158, 155, 152, 145, 146, 151, 148, 133, 134, 131, 128, 137, 138, 143, 140,
+ 13, 14, 11, 8, 1, 2, 7, 4, 21, 22, 19, 16, 25, 26, 31, 28,
+ 61, 62, 59, 56, 49, 50, 55, 52, 37, 38, 35, 32, 41, 42, 47, 44,
+ 109, 110, 107, 104, 97, 98, 103, 100, 117, 118, 115, 112, 121, 122, 127, 124,
+ 93, 94, 91, 88, 81, 82, 87, 84, 69, 70, 67, 64, 73, 74, 79, 76
+ },
+ { / * 4 * /
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+ 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+ 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
+ 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
+ 77, 73, 69, 65, 93, 89, 85, 81, 109, 105, 101, 97, 125, 121, 117, 113,
+ 13, 9, 5, 1, 29, 25, 21, 17, 45, 41, 37, 33, 61, 57, 53, 49,
+ 205, 201, 197, 193, 221, 217, 213, 209, 237, 233, 229, 225, 253, 249, 245, 241,
+ 141, 137, 133, 129, 157, 153, 149, 145, 173, 169, 165, 161, 189, 185, 181, 177,
+ 154, 158, 146, 150, 138, 142, 130, 134, 186, 190, 178, 182, 170, 174, 162, 166,
+ 218, 222, 210, 214, 202, 206, 194, 198, 250, 254, 242, 246, 234, 238, 226, 230,
+ 26, 30, 18, 22, 10, 14, 2, 6, 58, 62, 50, 54, 42, 46, 34, 38,
+ 90, 94, 82, 86, 74, 78, 66, 70, 122, 126, 114, 118, 106, 110, 98, 102,
+ 215, 211, 223, 219, 199, 195, 207, 203, 247, 243, 255, 251, 231, 227, 239, 235,
+ 151, 147, 159, 155, 135, 131, 143, 139, 183, 179, 191, 187, 167, 163, 175, 171,
+ 87, 83, 95, 91, 71, 67, 79, 75, 119, 115, 127, 123, 103, 99, 111, 107,
+ 23, 19, 31, 27, 7, 3, 15, 11, 55, 51, 63, 59, 39, 35, 47, 43
+ },
+*/ { /* 5 */
+ 0, 5, 10, 15, 20, 17, 30, 27, 40, 45, 34, 39, 60, 57, 54, 51,
+ 80, 85, 90, 95, 68, 65, 78, 75, 120, 125, 114, 119, 108, 105, 102, 99,
+ 160, 165, 170, 175, 180, 177, 190, 187, 136, 141, 130, 135, 156, 153, 150, 147,
+ 240, 245, 250, 255, 228, 225, 238, 235, 216, 221, 210, 215, 204, 201, 198, 195,
+ 13, 8, 7, 2, 25, 28, 19, 22, 37, 32, 47, 42, 49, 52, 59, 62,
+ 93, 88, 87, 82, 73, 76, 67, 70, 117, 112, 127, 122, 97, 100, 107, 110,
+ 173, 168, 167, 162, 185, 188, 179, 182, 133, 128, 143, 138, 145, 148, 155, 158,
+ 253, 248, 247, 242, 233, 236, 227, 230, 213, 208, 223, 218, 193, 196, 203, 206,
+ 26, 31, 16, 21, 14, 11, 4, 1, 50, 55, 56, 61, 38, 35, 44, 41,
+ 74, 79, 64, 69, 94, 91, 84, 81, 98, 103, 104, 109, 118, 115, 124, 121,
+ 186, 191, 176, 181, 174, 171, 164, 161, 146, 151, 152, 157, 134, 131, 140, 137,
+ 234, 239, 224, 229, 254, 251, 244, 241, 194, 199, 200, 205, 214, 211, 220, 217,
+ 23, 18, 29, 24, 3, 6, 9, 12, 63, 58, 53, 48, 43, 46, 33, 36,
+ 71, 66, 77, 72, 83, 86, 89, 92, 111, 106, 101, 96, 123, 126, 113, 116,
+ 183, 178, 189, 184, 163, 166, 169, 172, 159, 154, 149, 144, 139, 142, 129, 132,
+ 231, 226, 237, 232, 243, 246, 249, 252, 207, 202, 197, 192, 219, 222, 209, 212
+ },
+ { /* 6 */
+ 0, 6, 12, 10, 24, 30, 20, 18, 48, 54, 60, 58, 40, 46, 36, 34,
+ 96, 102, 108, 106, 120, 126, 116, 114, 80, 86, 92, 90, 72, 78, 68, 66,
+ 192, 198, 204, 202, 216, 222, 212, 210, 240, 246, 252, 250, 232, 238, 228, 226,
+ 160, 166, 172, 170, 184, 190, 180, 178, 144, 150, 156, 154, 136, 142, 132, 130,
+ 205, 203, 193, 199, 213, 211, 217, 223, 253, 251, 241, 247, 229, 227, 233, 239,
+ 173, 171, 161, 167, 181, 179, 185, 191, 157, 155, 145, 151, 133, 131, 137, 143,
+ 13, 11, 1, 7, 21, 19, 25, 31, 61, 59, 49, 55, 37, 35, 41, 47,
+ 109, 107, 97, 103, 117, 115, 121, 127, 93, 91, 81, 87, 69, 67, 73, 79,
+ 215, 209, 219, 221, 207, 201, 195, 197, 231, 225, 235, 237, 255, 249, 243, 245,
+ 183, 177, 187, 189, 175, 169, 163, 165, 135, 129, 139, 141, 159, 153, 147, 149,
+ 23, 17, 27, 29, 15, 9, 3, 5, 39, 33, 43, 45, 63, 57, 51, 53,
+ 119, 113, 123, 125, 111, 105, 99, 101, 71, 65, 75, 77, 95, 89, 83, 85,
+ 26, 28, 22, 16, 2, 4, 14, 8, 42, 44, 38, 32, 50, 52, 62, 56,
+ 122, 124, 118, 112, 98, 100, 110, 104, 74, 76, 70, 64, 82, 84, 94, 88,
+ 218, 220, 214, 208, 194, 196, 206, 200, 234, 236, 230, 224, 242, 244, 254, 248,
+ 186, 188, 182, 176, 162, 164, 174, 168, 138, 140, 134, 128, 146, 148, 158, 152
+ },
+ { /* 7 */
+ 0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45,
+ 112, 119, 126, 121, 108, 107, 98, 101, 72, 79, 70, 65, 84, 83, 90, 93,
+ 224, 231, 238, 233, 252, 251, 242, 245, 216, 223, 214, 209, 196, 195, 202, 205,
+ 144, 151, 158, 153, 140, 139, 130, 133, 168, 175, 166, 161, 180, 179, 186, 189,
+ 141, 138, 131, 132, 145, 150, 159, 152, 181, 178, 187, 188, 169, 174, 167, 160,
+ 253, 250, 243, 244, 225, 230, 239, 232, 197, 194, 203, 204, 217, 222, 215, 208,
+ 109, 106, 99, 100, 113, 118, 127, 120, 85, 82, 91, 92, 73, 78, 71, 64,
+ 29, 26, 19, 20, 1, 6, 15, 8, 37, 34, 43, 44, 57, 62, 55, 48,
+ 87, 80, 89, 94, 75, 76, 69, 66, 111, 104, 97, 102, 115, 116, 125, 122,
+ 39, 32, 41, 46, 59, 60, 53, 50, 31, 24, 17, 22, 3, 4, 13, 10,
+ 183, 176, 185, 190, 171, 172, 165, 162, 143, 136, 129, 134, 147, 148, 157, 154,
+ 199, 192, 201, 206, 219, 220, 213, 210, 255, 248, 241, 246, 227, 228, 237, 234,
+ 218, 221, 212, 211, 198, 193, 200, 207, 226, 229, 236, 235, 254, 249, 240, 247,
+ 170, 173, 164, 163, 182, 177, 184, 191, 146, 149, 156, 155, 142, 137, 128, 135,
+ 58, 61, 52, 51, 38, 33, 40, 47, 2, 5, 12, 11, 30, 25, 16, 23,
+ 74, 77, 68, 67, 86, 81, 88, 95, 114, 117, 124, 123, 110, 105, 96, 103
+ },
+ { /* 8 */
+ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
+ 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248,
+ 77, 69, 93, 85, 109, 101, 125, 117, 13, 5, 29, 21, 45, 37, 61, 53,
+ 205, 197, 221, 213, 237, 229, 253, 245, 141, 133, 157, 149, 173, 165, 189, 181,
+ 154, 146, 138, 130, 186, 178, 170, 162, 218, 210, 202, 194, 250, 242, 234, 226,
+ 26, 18, 10, 2, 58, 50, 42, 34, 90, 82, 74, 66, 122, 114, 106, 98,
+ 215, 223, 199, 207, 247, 255, 231, 239, 151, 159, 135, 143, 183, 191, 167, 175,
+ 87, 95, 71, 79, 119, 127, 103, 111, 23, 31, 7, 15, 55, 63, 39, 47,
+ 121, 113, 105, 97, 89, 81, 73, 65, 57, 49, 41, 33, 25, 17, 9, 1,
+ 249, 241, 233, 225, 217, 209, 201, 193, 185, 177, 169, 161, 153, 145, 137, 129,
+ 52, 60, 36, 44, 20, 28, 4, 12, 116, 124, 100, 108, 84, 92, 68, 76,
+ 180, 188, 164, 172, 148, 156, 132, 140, 244, 252, 228, 236, 212, 220, 196, 204,
+ 227, 235, 243, 251, 195, 203, 211, 219, 163, 171, 179, 187, 131, 139, 147, 155,
+ 99, 107, 115, 123, 67, 75, 83, 91, 35, 43, 51, 59, 3, 11, 19, 27,
+ 174, 166, 190, 182, 142, 134, 158, 150, 238, 230, 254, 246, 206, 198, 222, 214,
+ 46, 38, 62, 54, 14, 6, 30, 22, 110, 102, 126, 118, 78, 70, 94, 86
+ }
+};
+
+#endif
+
+
+++ /dev/null
-/* twister224.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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 AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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 AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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_large_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_large_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_large_lastBlock
-
- movw r24, DST_SAVE0
- movw r22, CTX_SAVE0
- ldi r20, lo8(384)
- ldi r21, hi8(384)
- rcall twister_large_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 AVR-Crypto-Lib.
- Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * \file 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_large_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_large_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_large_lastBlock
-
- movw r24, DST_SAVE0
- movw r22, CTX_SAVE0
- ldi r20, lo8(512)
- ldi r21, hi8(512)
- rcall twister_large_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_ */
+++ /dev/null
-/******************************************************************
- * S-BOX for Twister
- *
- *
- *******************************************************************/
-
-#include "config.h"
-#include <stdint.h>
-#include <avr/pgmspace.h>
-
-static const uint8_t twister_sbox[256] PROGMEM = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-#ifndef TWISTER_MUL_TABLE
-
-
-/* Twister MDS matrix */
-static const uint8_t twister_mds[8][8] PROGMEM = {
- {2, 1, 1, 5, 7, 8, 6, 1},
- {1, 2, 1, 1, 5, 7, 8, 6},
- {6, 1, 2, 1, 1, 5, 7, 8},
- {8, 6, 1, 2, 1, 1, 5, 7},
- {7, 8, 6, 1, 2, 1, 1, 5},
- {5, 7, 8, 6, 1, 2, 1, 1},
- {1, 5, 7, 8, 6, 1, 2, 1},
- {1, 1, 5, 7, 8, 6, 1, 2}
-};
-
-#else
-
-#define S1 0
-#define S2 1
-#define S3 X
-#define S4 X
-#define S5 2
-#define S6 3
-#define S7 4
-#define S8 5
-
-static const uint8_t twister_mds[8][8] PROGMEM = {
- {S2, S1, S1, S5, S7, S8, S6, S1},
- {S1, S2, S1, S1, S5, S7, S8, S6},
- {S6, S1, S2, S1, S1, S5, S7, S8},
- {S8, S6, S1, S2, S1, S1, S5, S7},
- {S7, S8, S6, S1, S2, S1, S1, S5},
- {S5, S7, S8, S6, S1, S2, S1, S1},
- {S1, S5, S7, S8, S6, S1, S2, S1},
- {S1, S1, S5, S7, S8, S6, S1, S2}
-};
-
-static const uint8_t twister_multab[8][256] PROGMEM = {
- { /* 1 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
- 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
- },
- { /* 2 */
- 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
- 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
- 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
- 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
- 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
- 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
- 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254,
- 77, 79, 73, 75, 69, 71, 65, 67, 93, 95, 89, 91, 85, 87, 81, 83,
- 109, 111, 105, 107, 101, 103, 97, 99, 125, 127, 121, 123, 117, 119, 113, 115,
- 13, 15, 9, 11, 5, 7, 1, 3, 29, 31, 25, 27, 21, 23, 17, 19,
- 45, 47, 41, 43, 37, 39, 33, 35, 61, 63, 57, 59, 53, 55, 49, 51,
- 205, 207, 201, 203, 197, 199, 193, 195, 221, 223, 217, 219, 213, 215, 209, 211,
- 237, 239, 233, 235, 229, 231, 225, 227, 253, 255, 249, 251, 245, 247, 241, 243,
- 141, 143, 137, 139, 133, 135, 129, 131, 157, 159, 153, 155, 149, 151, 145, 147,
- 173, 175, 169, 171, 165, 167, 161, 163, 189, 191, 185, 187, 181, 183, 177, 179
- },
-/* { / * 3 * /
- 0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17,
- 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33,
- 96, 99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113,
- 80, 83, 86, 85, 92, 95, 90, 89, 72, 75, 78, 77, 68, 71, 66, 65,
- 192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209,
- 240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225,
- 160, 163, 166, 165, 172, 175, 170, 169, 184, 187, 190, 189, 180, 183, 178, 177,
- 144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129,
- 205, 206, 203, 200, 193, 194, 199, 196, 213, 214, 211, 208, 217, 218, 223, 220,
- 253, 254, 251, 248, 241, 242, 247, 244, 229, 230, 227, 224, 233, 234, 239, 236,
- 173, 174, 171, 168, 161, 162, 167, 164, 181, 182, 179, 176, 185, 186, 191, 188,
- 157, 158, 155, 152, 145, 146, 151, 148, 133, 134, 131, 128, 137, 138, 143, 140,
- 13, 14, 11, 8, 1, 2, 7, 4, 21, 22, 19, 16, 25, 26, 31, 28,
- 61, 62, 59, 56, 49, 50, 55, 52, 37, 38, 35, 32, 41, 42, 47, 44,
- 109, 110, 107, 104, 97, 98, 103, 100, 117, 118, 115, 112, 121, 122, 127, 124,
- 93, 94, 91, 88, 81, 82, 87, 84, 69, 70, 67, 64, 73, 74, 79, 76
- },
- { / * 4 * /
- 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
- 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
- 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
- 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
- 77, 73, 69, 65, 93, 89, 85, 81, 109, 105, 101, 97, 125, 121, 117, 113,
- 13, 9, 5, 1, 29, 25, 21, 17, 45, 41, 37, 33, 61, 57, 53, 49,
- 205, 201, 197, 193, 221, 217, 213, 209, 237, 233, 229, 225, 253, 249, 245, 241,
- 141, 137, 133, 129, 157, 153, 149, 145, 173, 169, 165, 161, 189, 185, 181, 177,
- 154, 158, 146, 150, 138, 142, 130, 134, 186, 190, 178, 182, 170, 174, 162, 166,
- 218, 222, 210, 214, 202, 206, 194, 198, 250, 254, 242, 246, 234, 238, 226, 230,
- 26, 30, 18, 22, 10, 14, 2, 6, 58, 62, 50, 54, 42, 46, 34, 38,
- 90, 94, 82, 86, 74, 78, 66, 70, 122, 126, 114, 118, 106, 110, 98, 102,
- 215, 211, 223, 219, 199, 195, 207, 203, 247, 243, 255, 251, 231, 227, 239, 235,
- 151, 147, 159, 155, 135, 131, 143, 139, 183, 179, 191, 187, 167, 163, 175, 171,
- 87, 83, 95, 91, 71, 67, 79, 75, 119, 115, 127, 123, 103, 99, 111, 107,
- 23, 19, 31, 27, 7, 3, 15, 11, 55, 51, 63, 59, 39, 35, 47, 43
- },
-*/ { /* 5 */
- 0, 5, 10, 15, 20, 17, 30, 27, 40, 45, 34, 39, 60, 57, 54, 51,
- 80, 85, 90, 95, 68, 65, 78, 75, 120, 125, 114, 119, 108, 105, 102, 99,
- 160, 165, 170, 175, 180, 177, 190, 187, 136, 141, 130, 135, 156, 153, 150, 147,
- 240, 245, 250, 255, 228, 225, 238, 235, 216, 221, 210, 215, 204, 201, 198, 195,
- 13, 8, 7, 2, 25, 28, 19, 22, 37, 32, 47, 42, 49, 52, 59, 62,
- 93, 88, 87, 82, 73, 76, 67, 70, 117, 112, 127, 122, 97, 100, 107, 110,
- 173, 168, 167, 162, 185, 188, 179, 182, 133, 128, 143, 138, 145, 148, 155, 158,
- 253, 248, 247, 242, 233, 236, 227, 230, 213, 208, 223, 218, 193, 196, 203, 206,
- 26, 31, 16, 21, 14, 11, 4, 1, 50, 55, 56, 61, 38, 35, 44, 41,
- 74, 79, 64, 69, 94, 91, 84, 81, 98, 103, 104, 109, 118, 115, 124, 121,
- 186, 191, 176, 181, 174, 171, 164, 161, 146, 151, 152, 157, 134, 131, 140, 137,
- 234, 239, 224, 229, 254, 251, 244, 241, 194, 199, 200, 205, 214, 211, 220, 217,
- 23, 18, 29, 24, 3, 6, 9, 12, 63, 58, 53, 48, 43, 46, 33, 36,
- 71, 66, 77, 72, 83, 86, 89, 92, 111, 106, 101, 96, 123, 126, 113, 116,
- 183, 178, 189, 184, 163, 166, 169, 172, 159, 154, 149, 144, 139, 142, 129, 132,
- 231, 226, 237, 232, 243, 246, 249, 252, 207, 202, 197, 192, 219, 222, 209, 212
- },
- { /* 6 */
- 0, 6, 12, 10, 24, 30, 20, 18, 48, 54, 60, 58, 40, 46, 36, 34,
- 96, 102, 108, 106, 120, 126, 116, 114, 80, 86, 92, 90, 72, 78, 68, 66,
- 192, 198, 204, 202, 216, 222, 212, 210, 240, 246, 252, 250, 232, 238, 228, 226,
- 160, 166, 172, 170, 184, 190, 180, 178, 144, 150, 156, 154, 136, 142, 132, 130,
- 205, 203, 193, 199, 213, 211, 217, 223, 253, 251, 241, 247, 229, 227, 233, 239,
- 173, 171, 161, 167, 181, 179, 185, 191, 157, 155, 145, 151, 133, 131, 137, 143,
- 13, 11, 1, 7, 21, 19, 25, 31, 61, 59, 49, 55, 37, 35, 41, 47,
- 109, 107, 97, 103, 117, 115, 121, 127, 93, 91, 81, 87, 69, 67, 73, 79,
- 215, 209, 219, 221, 207, 201, 195, 197, 231, 225, 235, 237, 255, 249, 243, 245,
- 183, 177, 187, 189, 175, 169, 163, 165, 135, 129, 139, 141, 159, 153, 147, 149,
- 23, 17, 27, 29, 15, 9, 3, 5, 39, 33, 43, 45, 63, 57, 51, 53,
- 119, 113, 123, 125, 111, 105, 99, 101, 71, 65, 75, 77, 95, 89, 83, 85,
- 26, 28, 22, 16, 2, 4, 14, 8, 42, 44, 38, 32, 50, 52, 62, 56,
- 122, 124, 118, 112, 98, 100, 110, 104, 74, 76, 70, 64, 82, 84, 94, 88,
- 218, 220, 214, 208, 194, 196, 206, 200, 234, 236, 230, 224, 242, 244, 254, 248,
- 186, 188, 182, 176, 162, 164, 174, 168, 138, 140, 134, 128, 146, 148, 158, 152
- },
- { /* 7 */
- 0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45,
- 112, 119, 126, 121, 108, 107, 98, 101, 72, 79, 70, 65, 84, 83, 90, 93,
- 224, 231, 238, 233, 252, 251, 242, 245, 216, 223, 214, 209, 196, 195, 202, 205,
- 144, 151, 158, 153, 140, 139, 130, 133, 168, 175, 166, 161, 180, 179, 186, 189,
- 141, 138, 131, 132, 145, 150, 159, 152, 181, 178, 187, 188, 169, 174, 167, 160,
- 253, 250, 243, 244, 225, 230, 239, 232, 197, 194, 203, 204, 217, 222, 215, 208,
- 109, 106, 99, 100, 113, 118, 127, 120, 85, 82, 91, 92, 73, 78, 71, 64,
- 29, 26, 19, 20, 1, 6, 15, 8, 37, 34, 43, 44, 57, 62, 55, 48,
- 87, 80, 89, 94, 75, 76, 69, 66, 111, 104, 97, 102, 115, 116, 125, 122,
- 39, 32, 41, 46, 59, 60, 53, 50, 31, 24, 17, 22, 3, 4, 13, 10,
- 183, 176, 185, 190, 171, 172, 165, 162, 143, 136, 129, 134, 147, 148, 157, 154,
- 199, 192, 201, 206, 219, 220, 213, 210, 255, 248, 241, 246, 227, 228, 237, 234,
- 218, 221, 212, 211, 198, 193, 200, 207, 226, 229, 236, 235, 254, 249, 240, 247,
- 170, 173, 164, 163, 182, 177, 184, 191, 146, 149, 156, 155, 142, 137, 128, 135,
- 58, 61, 52, 51, 38, 33, 40, 47, 2, 5, 12, 11, 30, 25, 16, 23,
- 74, 77, 68, 67, 86, 81, 88, 95, 114, 117, 124, 123, 110, 105, 96, 103
- },
- { /* 8 */
- 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
- 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248,
- 77, 69, 93, 85, 109, 101, 125, 117, 13, 5, 29, 21, 45, 37, 61, 53,
- 205, 197, 221, 213, 237, 229, 253, 245, 141, 133, 157, 149, 173, 165, 189, 181,
- 154, 146, 138, 130, 186, 178, 170, 162, 218, 210, 202, 194, 250, 242, 234, 226,
- 26, 18, 10, 2, 58, 50, 42, 34, 90, 82, 74, 66, 122, 114, 106, 98,
- 215, 223, 199, 207, 247, 255, 231, 239, 151, 159, 135, 143, 183, 191, 167, 175,
- 87, 95, 71, 79, 119, 127, 103, 111, 23, 31, 7, 15, 55, 63, 39, 47,
- 121, 113, 105, 97, 89, 81, 73, 65, 57, 49, 41, 33, 25, 17, 9, 1,
- 249, 241, 233, 225, 217, 209, 201, 193, 185, 177, 169, 161, 153, 145, 137, 129,
- 52, 60, 36, 44, 20, 28, 4, 12, 116, 124, 100, 108, 84, 92, 68, 76,
- 180, 188, 164, 172, 148, 156, 132, 140, 244, 252, 228, 236, 212, 220, 196, 204,
- 227, 235, 243, 251, 195, 203, 211, 219, 163, 171, 179, 187, 131, 139, 147, 155,
- 99, 107, 115, 123, 67, 75, 83, 91, 35, 43, 51, 59, 3, 11, 19, 27,
- 174, 166, 190, 182, 142, 134, 158, 150, 238, 230, 254, 246, 206, 198, 222, 214,
- 46, 38, 62, 54, 14, 6, 30, 22, 110, 102, 126, 118, 78, 70, 94, 86
- }
-};
-
-#endif
-
-
+++ /dev/null
-/* ubi.h */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#ifndef UBI_H_
-#define UBI_H_
-
-#include <stdint.h>
-
-#define UBI_TYPE_KEY 0
-#define UBI_TYPE_CFG 4
-#define UBI_TYPE_PRS 8
-#define UBI_TYPE_PK 12
-#define UBI_TYPE_KDF 16
-#define UBI_TYPE_NON 20
-#define UBI_TYPE_MSG 48
-#define UBI_TYPE_OUT 63
-
-#define UBI256_BLOCKSIZE 256
-#define UBI256_BLOCKSIZE_B ((UBI256_BLOCKSIZE+7)/8)
-
-#define UBI512_BLOCKSIZE 512
-#define UBI512_BLOCKSIZE_B ((UBI512_BLOCKSIZE+7)/8)
-
-#define UBI1024_BLOCKSIZE 1024
-#define UBI1024_BLOCKSIZE_B ((UBI1024_BLOCKSIZE+7)/8)
-
-
-typedef struct{
- uint8_t tweak[16];
- uint8_t g[32];
-}ubi256_ctx_t;
-
-typedef struct{
- uint8_t tweak[16];
- uint8_t g[64];
-}ubi512_ctx_t;
-
-typedef struct{
- uint8_t tweak[16];
- uint8_t g[128];
-}ubi1024_ctx_t;
-
-void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type);
-void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block);
-void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b);
-void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx);
-
-void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type);
-void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block);
-void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b);
-void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx);
-
-void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type);
-void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block);
-void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b);
-void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx);
-
-typedef struct{
- char schema[4];
- uint16_t version;
- uint16_t reserved1;
- uint64_t out_length;
- uint8_t tree_leaf_size;
- uint8_t tree_fan_out;
- uint8_t tree_max_height;
- uint8_t reserved2[13];
-}skein_config_t;
-
-
-#endif /* UBI_H_ */
+++ /dev/null
-/* ubi1024.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-#include "memxor.h"
-#include "ubi.h"
-
-void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, UBI1024_BLOCKSIZE_B);
-}
-
-void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block){
- threefish1024_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI1024_BLOCKSIZE_B;
- threefish1024_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI1024_BLOCKSIZE_B);
- threefish1024_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI1024_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-
-
-void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish1024_ctx_t tfctx;
- while(length_b>UBI1024_BLOCKSIZE){
- ubi1024_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI1024_BLOCKSIZE_B;
- length_b -= UBI1024_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07)
- ctx->tweak[14] |= 0x80;
- threefish1024_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI1024_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07)
- ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
- threefish1024_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-}
-
-void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI1024_BLOCKSIZE_B);
-}
-
+++ /dev/null
-/* ubi1024_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void ubi1024_init(ubi1024_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, UBI1024_BLOCKSIZE_B);
-}
-*/
-/*
- * param ctx: r24:r25
- * param g: r22:r23
- * param type: r20
- */
-.global ubi1024_init
-ubi1024_init:
- movw r26, r24
- ldi r21, 15
-1: st X+, r1
- dec r21
- brne 1b
- ori r20, 0x40
- st X+, r20
- ldi r21, 128
- movw r30, r22
-2: ld r20, Z+
- st X+, r20
- dec r21
- brne 2b
- ret
-
-/******************************************************************************/
-/*
-void ubi1024_ctx2hash(void* dest, const ubi1024_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI1024_BLOCKSIZE_B);
-}
-*/
-/*
- * param dest: r24:r24
- * param ctx: r22:r23
- */
-.global ubi1024_ctx2hash
-ubi1024_ctx2hash:
- movw r26, r24
- movw r30, r22
- adiw r30, 16
- ldi r22, 128
-1: ld r23, Z+
- st X+, r23
- dec r22
- brne 1b
- ret
-
-/******************************************************************************/
-/*
-void ubi1024_nextBlock(ubi1024_ctx_t* ctx, const void* block){
- threefish1024_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI1024_BLOCKSIZE_B;
- threefish1024_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI1024_BLOCKSIZE_B);
- threefish1024_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI1024_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- */
-CTX0 = 2
-CTX1 = 3
-BLOCK0 = 4
-BLOCK1 = 5
-TFCTX0 = 6
-TFCTX1 = 7
-.global ubi1024_nextBlock
-ubi1024_nextBlock:
- stack_alloc_large 20*8
- push_range 2, 7
- adiw r30, 1 /* Z points to tfctx */
- movw TFCTX0, r30
- movw CTX0, r24
- movw BLOCK0, r22
- movw r26, r24
-/* add BLOCKSIZE_B (128) to tweak */
- ldi r25, 128
- ld r24, X
- add r24, r25
- st X+, r24
- ldi r25, 11
-1: ld r24, X
- adc r24, r1
- st X+, r24
- dec r25
- brne 1b
-/* call threefish1024_init */
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points to ctx->g */
- movw r20, TFCTX0
- rcall threefish1024_init
- /* copy block to ctx->g */
- movw r26, CTX0
- movw r30, BLOCK0
- ldi r25, 128
-1: ld r24, Z+
- st X+, r24
- dec r25
- brne 1b
-/* call threefish1024_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish1024_enc
-/* xor block into ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- ldi r25, 128
-1: ld r24, X+
- ld r23, Z
- eor r23, r24
- st Z+, r23
- dec r25
- brne 1b
-/* clear 'first' bit in tweak */
- sbiw r30, 1+2
- sbiw r30, 63
- sbiw r30, 63
- ld r24, Z
- andi r24, ~0x40
- st Z, r24
-exit:
- pop_range 2, 7
- stack_free_large2 20*8
- ret
-
-/******************************************************************************/
-/*
-void ubi1024_lastBlock(ubi1024_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish1024_ctx_t tfctx;
- while(length_b>UBI1024_BLOCKSIZE){
- ubi1024_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI1024_BLOCKSIZE_B;
- length_b -= UBI1024_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07)
- ctx->tweak[14] |= 0x80;
- threefish1024_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI1024_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07)
- ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
- threefish1024_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- * param ength_b: r20:r21
- */
-MASK_B = 8
-LEN_B = 9
-TFCTX0 = 10
-TFCTX1 = 11
-CTX0 = 12
-CTX1 = 13
-BLOCK0 = 14
-BLOCK1 = 15
-LENGTH0 = 16
-LENGTH1 = 17
-.global ubi1024_lastBlock
-ubi1024_lastBlock:
-/* run nextBlock for preceding blocks*/
- push_range 8, 17
- movw CTX0, r24
- movw BLOCK0, r22
- movw LENGTH0, r20
-1: cpi LENGTH1, 5
- brlo 2f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi1024_nextBlock
- ldi r25, 128
- add BLOCK0, r25
- adc BLOCK1, r1
- subi LENGTH1, 4
- rjmp 1b
-2: cpi LENGTH1, 4
- brlo 3f
- tst LENGTH0
- breq 3f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi1024_nextBlock
- ldi r25, 128
- add BLOCK0, r25
- adc BLOCK1, r1
- subi LENGTH1, 4
-3: /* now the real fun */
- stack_alloc_large 20*8
- adiw r30, 1
- movw TFCTX0, r30
- /* calculate LEN_B */
- movw r24, LENGTH0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r25
- ror r24
- lsr r25
- ror r24
- mov LEN_B, r24
- /* add length to tweak */
- movw r30, CTX0
- ld r24, Z
- add r24, LEN_B
- st Z+, r24
- ldi r25, 11
-1: ld r24, Z
- adc r24, r1
- st Z+, r24
- dec r25
- brne 1b
- /* set 'final' bit*/
- movw r30, CTX0
- ldd r24, Z+15
- ori r24, 0x80
- std Z+15, r24
- /* store in MASK_B if we do bit processing and set 'BitPad' bit*/
- clr MASK_B
- mov r24, LENGTH0
- andi r24, 0x07
- tst r24
- breq 4f
- ldd r25, Z+14
- ori r25, 0x80
- std Z+14, r25
- ldi r25, 0x80
- mov MASK_B, r25
-1: lsr MASK_B
- dec r24
- brne 1b
-4: /* call threefish1024_init*/
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points at ctx->g */
- movw r20, TFCTX0
- rcall threefish1024_init
- /* copy block to ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- mov r24, LEN_B
- ldi r25, 128
- sub r25, LEN_B
- tst r24
-1: breq 2f
- ld r22, X+
- st Z+, r22
- dec r24
- rjmp 1b
-2: tst MASK_B
- breq 29f
- or r22, MASK_B
- st -Z, r22
- adiw r30, 1
-29: tst r25
-3: breq 4f
- st Z+, r1
- dec r25
- rjmp 3b
-4: /* call threefish1024_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish1024_enc
- /* xor block into ctx->g */
- movw r30, CTX0
- movw r26, BLOCK0
- tst LEN_B
-5: breq 6f
- ld r22, X+
- ld r23, Z
- eor r23, r22
- st Z+, r23
- dec LEN_B
- rjmp 5b
-6: tst MASK_B
- breq 7f
- eor r23, MASK_B
- st -Z, r23
-
-7: stack_free_large2 20*8
- pop_range 8, 17
- ret
-
-
+++ /dev/null
-/* ubi256.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-#include "memxor.h"
-#include "ubi.h"
-
-void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, 32);
-}
-
-void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block){
- threefish256_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
- threefish256_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
- threefish256_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI256_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-
-
-void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish256_ctx_t tfctx;
- while(length_b>UBI256_BLOCKSIZE){
- ubi256_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
- length_b -= UBI256_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07){
- ctx->tweak[14] |= 0x80;
- }
- threefish256_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI256_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] |= 0x80>>(length_b&7);
- ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
- }
- threefish256_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-
-}
-
-void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
-}
-
+++ /dev/null
-/* ubi256_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-16
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void ubi256_init(ubi256_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, 32);
-}
-*/
-/*
- * param ctx: r24:r25
- * param g: r22:r23
- * param type: r20
- */
-.global ubi256_init
-ubi256_init:
- movw r26, r24
- ldi r21, 15
-1: st X+, r1
- dec r21
- brne 1b
- ori r20, 0x40
- st X+, r20
- ldi r21, 32
- movw r30, r22
-2: ld r20, Z+
- st X+, r20
- dec r21
- brne 2b
- ret
-
-/******************************************************************************/
-/*
-void ubi256_ctx2hash(void* dest, const ubi256_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
-}
-*/
-/*
- * param dest: r24:r24
- * param ctx: r22:r23
- */
-.global ubi256_ctx2hash
-ubi256_ctx2hash:
- movw r26, r24
- movw r30, r22
- adiw r30, 16
- ldi r22, 32
-1: ld r23, Z+
- st X+, r23
- dec r22
- brne 1b
- ret
-
-/******************************************************************************/
-/*
-void ubi256_nextBlock(ubi256_ctx_t* ctx, const void* block){
- threefish256_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
- threefish256_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
- threefish256_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI256_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- */
-CTX0 = 2
-CTX1 = 3
-BLOCK0 = 4
-BLOCK1 = 5
-TFCTX0 = 6
-TFCTX1 = 7
-.global ubi256_nextBlock
-ubi256_nextBlock:
- stack_alloc_large 64
- push_range 2, 7
- adiw r30, 1 /* Z points to tfctx */
- movw TFCTX0, r30
- movw CTX0, r24
- movw BLOCK0, r22
- movw r26, r24
-/* add BLOCKSIZE_B (32) to tweak */
- ldi r25, 32
- ld r24, X
- add r24, r25
- st X+, r24
- ldi r25, 11
-1: ld r24, X
- adc r24, r1
- st X+, r24
- dec r25
- brne 1b
-/* call threefish256_init */
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points to ctx->g */
- movw r20, TFCTX0
- rcall threefish256_init
- /* copy block to ctx->g */
- movw r26, CTX0
- movw r30, BLOCK0
- ldi r25, 32
-1: ld r24, Z+
- st X+, r24
- dec r25
- brne 1b
-/* call threefish256_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish256_enc
-/* xor block into ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- ldi r25, 32
-1: ld r24, X+
- ld r23, Z
- eor r23, r24
- st Z+, r23
- dec r25
- brne 1b
-/* clear 'first' bit in tweak */
- sbiw r30, 33
- ld r24, Z
- andi r24, ~0x40
- st Z, r24
-exit:
- pop_range 2, 7
- stack_free_large 64
- ret
-
-/******************************************************************************/
-/*
-void ubi256_lastBlock(ubi256_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish256_ctx_t tfctx;
- while(length_b>UBI256_BLOCKSIZE){
- ubi256_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
- length_b -= UBI256_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07){
- ctx->tweak[14] |= 0x80;
- }
- threefish256_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI256_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] |= 0x80>>(length_b&7);
- ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
- }
- threefish256_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- * param ength_b: r20:r21
- */
-MASK_B = 8
-LEN_B = 9
-TFCTX0 = 10
-TFCTX1 = 11
-CTX0 = 12
-CTX1 = 13
-BLOCK0 = 14
-BLOCK1 = 15
-LENGTH0 = 16
-LENGTH1 = 17
-.global ubi256_lastBlock
-ubi256_lastBlock:
-/* run nextBlock for preceding blocks*/
- push_range 8, 17
- movw CTX0, r24
- movw BLOCK0, r22
- movw LENGTH0, r20
-1: cpi LENGTH1, 2
- brlo 2f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi256_nextBlock
- ldi r25, 32
- add BLOCK0, r25
- adc BLOCK1, r1
- dec LENGTH1
- rjmp 1b
-2: tst LENGTH1
- breq 3f
- tst LENGTH0
- breq 3f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi256_nextBlock
- ldi r25, 32
- add BLOCK0, r25
- adc BLOCK1, r1
- dec LENGTH1
-3: /* now the real fun */
- stack_alloc_large 64
- adiw r30, 1
- movw TFCTX0, r30
- /* calculate LEN_B */
- movw r24, LENGTH0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r24
- lsr r24
- mov LEN_B, r24
- /* add length to tweak */
- movw r30, CTX0
- ld r24, Z
- add r24, LEN_B
- st Z+, r24
- ldi r25, 11
-1: ld r24, Z
- adc r24, r1
- st Z+, r24
- dec r25
- brne 1b
- /* set 'final' bit*/
- movw r30, CTX0
- ldd r24, Z+15
- ori r24, 0x80
- std Z+15, r24
- /* store in T if we do bit processing and set 'BitPad' bit*/
- clr MASK_B
- mov r24, LENGTH0
- andi r24, 0x07
- tst r24
- breq 4f
- ldd r25, Z+14
- ori r25, 0x80
- std Z+14, r25
- ldi r25, 0x80
- mov MASK_B, r25
-1: lsr MASK_B
- dec r24
- brne 1b
-4: /* call threefish256_init*/
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points at ctx->g */
- movw r20, TFCTX0
- rcall threefish256_init
- /* copy block to ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- mov r24, LEN_B
- ldi r25, 32
- sub r25, LEN_B
- tst r24
-1: breq 2f
- ld r22, X+
- st Z+, r22
- dec r24
- rjmp 1b
-2: tst MASK_B
- breq 29f
- or r22, MASK_B
- st -Z, r22
- adiw r30, 1
-29: tst r25
-3: breq 4f
- st Z+, r1
- dec r25
- rjmp 3b
-4: /* call threefish256_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish256_enc
- /* xor block into ctx->g */
- movw r30, CTX0
- movw r26, BLOCK0
- tst LEN_B
-5: breq 6f
- ld r22, X+
- ld r23, Z
- eor r23, r22
- st Z+, r23
- dec LEN_B
- rjmp 5b
-6: tst MASK_B
- breq 7f
- eor r23, MASK_B
- st -Z, r23
-
-7: stack_free_large 64
- pop_range 8, 17
- ret
-
-
+++ /dev/null
-/* ubi512.c */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-12
- * \license GPLv3 or later
- *
- */
-
-#include <stdint.h>
-#include <string.h>
-#include "threefish.h"
-#include "memxor.h"
-#include "ubi.h"
-
-void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
-}
-
-void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
- threefish512_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
- threefish512_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
- threefish512_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-
-
-void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish512_ctx_t tfctx;
- while(length_b>UBI512_BLOCKSIZE){
- ubi512_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
- length_b -= UBI512_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07)
- ctx->tweak[14] |= 0x80;
- threefish512_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07)
- ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
- threefish512_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-}
-
-void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
-}
-
+++ /dev/null
-/* ubi512_asm.S */
-/*
- This file is part of the AVR-Crypto-Lib.
- Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * \author Daniel Otte
- * \email daniel.otte@rub.de
- * \date 2009-03-25
- * \license GPLv3 or later
- */
-
-#include "avr-asm-macros.S"
-
-/******************************************************************************/
-/*
-void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
- memset(ctx->tweak, 0, 15);
- ctx->tweak[15] = 0x40+type;
- memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
-}
-*/
-/*
- * param ctx: r24:r25
- * param g: r22:r23
- * param type: r20
- */
-.global ubi512_init
-ubi512_init:
- movw r26, r24
- ldi r21, 15
-1: st X+, r1
- dec r21
- brne 1b
- ori r20, 0x40
- st X+, r20
- ldi r21, 64
- movw r30, r22
-2: ld r20, Z+
- st X+, r20
- dec r21
- brne 2b
- ret
-
-/******************************************************************************/
-/*
-void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
- memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
-}
-*/
-/*
- * param dest: r24:r24
- * param ctx: r22:r23
- */
-.global ubi512_ctx2hash
-ubi512_ctx2hash:
- movw r26, r24
- movw r30, r22
- adiw r30, 16
- ldi r22, 64
-1: ld r23, Z+
- st X+, r23
- dec r22
- brne 1b
- ret
-
-/******************************************************************************/
-/*
-void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
- threefish512_ctx_t tfctx;
- ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
- threefish512_init(ctx->g, ctx->tweak, &tfctx);
- memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
- threefish512_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
- ctx->tweak[15] &= (uint8_t)~0x40;
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- */
-CTX0 = 2
-CTX1 = 3
-BLOCK0 = 4
-BLOCK1 = 5
-TFCTX0 = 6
-TFCTX1 = 7
-.global ubi512_nextBlock
-ubi512_nextBlock:
- stack_alloc_large 12*8
- push_range 2, 7
- adiw r30, 1 /* Z points to tfctx */
- movw TFCTX0, r30
- movw CTX0, r24
- movw BLOCK0, r22
- movw r26, r24
-/* add BLOCKSIZE_B (64) to tweak */
- ldi r25, 64
- ld r24, X
- add r24, r25
- st X+, r24
- ldi r25, 11
-1: ld r24, X
- adc r24, r1
- st X+, r24
- dec r25
- brne 1b
-/* call threefish512_init */
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points to ctx->g */
- movw r20, TFCTX0
- rcall threefish512_init
- /* copy block to ctx->g */
- movw r26, CTX0
- movw r30, BLOCK0
- ldi r25, 64
-1: ld r24, Z+
- st X+, r24
- dec r25
- brne 1b
-/* call threefish512_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish512_enc
-/* xor block into ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- ldi r25, 64
-1: ld r24, X+
- ld r23, Z
- eor r23, r24
- st Z+, r23
- dec r25
- brne 1b
-/* clear 'first' bit in tweak */
- sbiw r30, 33
- sbiw r30, 32
- ld r24, Z
- andi r24, ~0x40
- st Z, r24
-exit:
- pop_range 2, 7
- stack_free_large 12*8
- ret
-
-/******************************************************************************/
-/*
-void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
- threefish512_ctx_t tfctx;
- while(length_b>UBI512_BLOCKSIZE){
- ubi512_nextBlock(ctx, block);
- block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
- length_b -= UBI512_BLOCKSIZE;
- }
- ctx->tweak[15] |= 0x80;
- ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
- if(length_b & 0x07)
- ctx->tweak[14] |= 0x80;
- threefish512_init(ctx->g, ctx->tweak, &tfctx);
- memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
- memcpy(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07)
- ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
- threefish512_enc(ctx->g, &tfctx);
- memxor(ctx->g, block, (length_b+7)/8);
- if(length_b & 0x07){
- ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
- }
-}
-*/
-/*
- * param ctx: r24:r25
- * param block: r22:r23
- * param ength_b: r20:r21
- */
-MASK_B = 8
-LEN_B = 9
-TFCTX0 = 10
-TFCTX1 = 11
-CTX0 = 12
-CTX1 = 13
-BLOCK0 = 14
-BLOCK1 = 15
-LENGTH0 = 16
-LENGTH1 = 17
-.global ubi512_lastBlock
-ubi512_lastBlock:
-/* run nextBlock for preceding blocks*/
- push_range 8, 17
- movw CTX0, r24
- movw BLOCK0, r22
- movw LENGTH0, r20
-1: cpi LENGTH1, 3
- brlo 2f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi512_nextBlock
- ldi r25, 64
- add BLOCK0, r25
- adc BLOCK1, r1
- subi LENGTH1, 2
- rjmp 1b
-2: cpi LENGTH1, 2
- brlo 3f
- tst LENGTH0
- breq 3f
- movw r24, CTX0
- movw r22, BLOCK0
- rcall ubi512_nextBlock
- ldi r25, 64
- add BLOCK0, r25
- adc BLOCK1, r1
- subi LENGTH1, 2
-3: /* now the real fun */
- stack_alloc_large 8*12
- adiw r30, 1
- movw TFCTX0, r30
- /* calculate LEN_B */
- movw r24, LENGTH0
- adiw r24, 7
- lsr r25
- ror r24
- lsr r25
- ror r24
- lsr r24
- mov LEN_B, r24
- /* add length to tweak */
- movw r30, CTX0
- ld r24, Z
- add r24, LEN_B
- st Z+, r24
- ldi r25, 11
-1: ld r24, Z
- adc r24, r1
- st Z+, r24
- dec r25
- brne 1b
- /* set 'final' bit*/
- movw r30, CTX0
- ldd r24, Z+15
- ori r24, 0x80
- std Z+15, r24
- /* store in MASk_B if we do bit processing and set 'BitPad' bit*/
- clr MASK_B
- mov r24, LENGTH0
- andi r24, 0x07
- tst r24
- breq 4f
- ldd r25, Z+14
- ori r25, 0x80
- std Z+14, r25
- ldi r25, 0x80
- mov MASK_B, r25
-1: lsr MASK_B
- dec r24
- brne 1b
-4: /* call threefish512_init*/
- movw r24, CTX0
- adiw r24, 16
- movw r22, CTX0
- movw CTX0, r24 /* CTX points at ctx->g */
- movw r20, TFCTX0
- rcall threefish512_init
- /* copy block to ctx->g */
- movw r26, BLOCK0
- movw r30, CTX0
- mov r24, LEN_B
- ldi r25, 64
- sub r25, LEN_B
- tst r24
-1: breq 2f
- ld r22, X+
- st Z+, r22
- dec r24
- rjmp 1b
-2: tst MASK_B
- breq 29f
- or r22, MASK_B
- st -Z, r22
- adiw r30, 1
-29: tst r25
-3: breq 4f
- st Z+, r1
- dec r25
- rjmp 3b
-4: /* call threefish512_enc */
- movw r24, CTX0
- movw r22, TFCTX0
- rcall threefish512_enc
- /* xor block into ctx->g */
- movw r30, CTX0
- movw r26, BLOCK0
- tst LEN_B
-5: breq 6f
- ld r22, X+
- ld r23, Z
- eor r23, r22
- st Z+, r23
- dec LEN_B
- rjmp 5b
-6: tst MASK_B
- breq 7f
- eor r23, MASK_B
- st -Z, r23
-
-7: stack_free_large 8*12
- pop_range 8, 17
- ret
-
-