adding RSA-OAEP
This commit is contained in:
parent
f947a91725
commit
997bf1010d
|
@ -0,0 +1,25 @@
|
||||||
|
# Makefile for the AVR-Crypto-Lib project
|
||||||
|
#
|
||||||
|
# This file is part of the AVR-Crypto-Lib.
|
||||||
|
# Copyright (C) 2010 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/>.
|
||||||
|
|
||||||
|
SHELL = sh
|
||||||
|
|
||||||
|
include Makefile_sys_conf.inc
|
||||||
|
include Makefile_en21_conf.inc
|
||||||
|
include Makefile_main.inc
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
MCU_TARGET = atmega128
|
||||||
|
F_CPU = 14745600
|
||||||
|
OPTIMIZE = -Os # -Os
|
||||||
|
EXTRALINK = xram.o
|
||||||
|
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||||
|
BOARD_NAME = ethernut2.1
|
||||||
|
|
||||||
|
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
|
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
|
|
||||||
|
override LDFLAGS = -gdwarf-2 -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x807fff -Wl,-Map,#
|
||||||
|
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Makefile for the AVR-Crypto-Lib project
|
||||||
|
#
|
||||||
|
# This file is part of the AVR-Crypto-Lib.
|
||||||
|
# Copyright (C) 2010 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/>.
|
||||||
|
|
||||||
|
SHELL = sh
|
||||||
|
|
||||||
|
include Makefile_sys_conf.inc
|
||||||
|
include Makefile_m644_conf.inc
|
||||||
|
include Makefile_main.inc
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
MCU_TARGET = atmega644
|
||||||
|
F_CPU = 20000000
|
||||||
|
OPTIMIZE = -Os # -Os
|
||||||
|
EXTRALINK =
|
||||||
|
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||||
|
BOARD_NAME = pollin_eval_m644
|
||||||
|
|
||||||
|
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
|
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
|
|
||||||
|
override LDFLAGS = -gdwarf-2 -Wl,-Map,
|
||||||
|
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||||
|
|
||||||
|
PROGRAMMER = avr911
|
||||||
|
PROG_PORT = /dev/ttyUSB1
|
||||||
|
DEFS = -D$(call uc, $(MCU_TARGET)) -DF_CPU=$(F_CPU)
|
||||||
|
FLASHCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -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
|
||||||
|
RESETCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER)
|
|
@ -0,0 +1,396 @@
|
||||||
|
# Makefile for the AVR-Crypto-Lib project
|
||||||
|
#
|
||||||
|
# This file is part of the AVR-Crypto-Lib.
|
||||||
|
# Copyright (C) 2010 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/>.
|
||||||
|
|
||||||
|
BLOCK_CIPHERS :=
|
||||||
|
STREAM_CIPHERS :=
|
||||||
|
HASHES :=
|
||||||
|
MACS :=
|
||||||
|
PRNGS :=
|
||||||
|
ENCODINGS :=
|
||||||
|
SIGNATURE :=
|
||||||
|
PK_CIPHERS :=
|
||||||
|
AUX :=
|
||||||
|
|
||||||
|
|
||||||
|
# we use the gnu make standard library
|
||||||
|
include gmsl
|
||||||
|
|
||||||
|
GLOBAL_INCDIR := ./ $(TESTSRC_DIR)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# inclusion of make stubs
|
||||||
|
include mkfiles/0*.mk
|
||||||
|
include mkfiles/*.mk
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
ALGORITHMS = $(BLOCK_CIPHERS) $(STREAM_CIPHERS) $(HASHES) $(PRNGS) $(MACS) \
|
||||||
|
$(ENCODINGS) $(SIGNATURE) $(PK_CIPHERS) $(AUX)
|
||||||
|
ALGORITHMS_OBJ = $(patsubst %,%_OBJ, $(ALGORITHMS))
|
||||||
|
ALGORITHMS_TESTBIN = $(patsubst %,%_TESTBIN, $(ALGORITHMS))
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# define binary object in $(BIN_DIR)$(ALGO)/<obj>
|
||||||
|
define Assert_Template
|
||||||
|
$(1) = $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(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)_TESTBIN)) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
define TargetSource_Template
|
||||||
|
$(1): $(2)
|
||||||
|
@mkdir -p $(dir $(1)) $(DEP_DIR)
|
||||||
|
@echo "[cc]: $(1) <-- $(2)"
|
||||||
|
@$(CC) $(CFLAGS_A) $(addprefix -I./,$(3)) $(addprefix -D, $(4)) -c -o $(1) $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
define TargetSourceList_Template
|
||||||
|
$(1): $(2)
|
||||||
|
@mkdir -p $(dir $(1)) $(DEP_DIR)
|
||||||
|
@echo "[cc]: $(1) <-- $(2)"
|
||||||
|
@$(CC) $(CFLAGS_A) $(addprefix -I./,$(3)) $(addprefix -D, $(4)) $(LIST_OPT) -c -o /dev/null $(2) > $(1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Function: find_source_file
|
||||||
|
# Arguments: 1: name of the binary file (.o extension) to search
|
||||||
|
# 2: list of directorys to search for file
|
||||||
|
# Returns: Returns paths to source file (mathing the pattern in
|
||||||
|
# $(SOURCE_PATTERN)
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
SOURCE_PATTERN := %.S %.c
|
||||||
|
find_source_file = $(firstword $(foreach d, $(2), \
|
||||||
|
$(filter $(SOURCE_PATTERN), \
|
||||||
|
$(wildcard $(d)$(notdir $(patsubst %.o,%,$1)).*) \
|
||||||
|
) \
|
||||||
|
) )
|
||||||
|
|
||||||
|
|
||||||
|
$(foreach a, $(ALGORITHMS), \
|
||||||
|
$(foreach b, $($(a)_OBJ), \
|
||||||
|
$(eval $(call TargetSource_Template, \
|
||||||
|
$(BIN_DIR)$(call lc, $(a))/$(b), \
|
||||||
|
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||||
|
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||||
|
$($(a)_DEF), \
|
||||||
|
)) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
$(foreach a, $(ALGORITHMS), \
|
||||||
|
$(foreach b, $($(a)_TESTBIN), \
|
||||||
|
$(eval $(call TargetSource_Template, \
|
||||||
|
$(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)$(b), \
|
||||||
|
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||||
|
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||||
|
$($(a)_DEF) \
|
||||||
|
)) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
$(foreach a, $(ALGORITHMS), \
|
||||||
|
$(foreach b, $($(a)_OBJ), \
|
||||||
|
$(eval $(call TargetSourceList_Template, \
|
||||||
|
$(LIST_DIR)$(call lc, $(a))/$(patsubst %.o,%.s,$(b)), \
|
||||||
|
$(call find_source_file, $(b), $($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR) ),\
|
||||||
|
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||||
|
$($(a)_DEF), \
|
||||||
|
)) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
EXTRALINK_BINOBJ = $(patsubst %, $(BIN_DIR)%, $(EXTRALINK))
|
||||||
|
|
||||||
|
$(foreach a, $(EXTRALINK), \
|
||||||
|
$(eval $(call TargetSource_Template, \
|
||||||
|
$(BIN_DIR)$(a), \
|
||||||
|
$(call find_source_file, $(a), $(GLOBAL_INCDIR) ),\
|
||||||
|
$($(a)_DIR) $($(a)_INCDIR) $(GLOBAL_INCDIR), \
|
||||||
|
$($(a)_DEF), \
|
||||||
|
)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define MainTestElf_Template
|
||||||
|
$(1): $(2) $(3) $(4)
|
||||||
|
@mkdir -p $(dir $(1))
|
||||||
|
@echo "[ld]: $(1)"
|
||||||
|
@$(CC) $(CFLAGS_A) $(LDFLAGS)$(patsubst %.elf,%.map,$(1)) -o \
|
||||||
|
$(1) \
|
||||||
|
$(2) $(3) $(EXTRALINK_BINOBJ)\
|
||||||
|
$(LIBS)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach a, $(ALGORITHMS), \
|
||||||
|
$(eval $(call MainTestElf_Template, \
|
||||||
|
$(BIN_DIR)$(call lc, $(a))/$(TEST_DIR)main-$(call lc, $(a))-test.elf, \
|
||||||
|
$($(a)_BINOBJ), \
|
||||||
|
$($(a)_TESTBINOBJ), \
|
||||||
|
$(EXTRALINK_BINOBJ) \
|
||||||
|
)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
all: $(foreach algo, $(ALGORITHMS), $($(algo)_BINOBJ))
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define MakeDir_TEMPLATE
|
||||||
|
$(1):
|
||||||
|
@echo [mkdir] $(1)
|
||||||
|
@mkdir -p $(1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach d, DEP_DIR BIN_DIR TESTSRC_DIR TESTLOG_DIR SPEEDLOG_DIR SIZE_DIR LIST_DIR STAT_DIR AUTOASM_DIR, $(eval $(call MakeDir_TEMPLATE, \
|
||||||
|
$($(d)) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call MakeDir__TEMPLATE, \
|
||||||
|
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
define TestBin_TEMPLATE
|
||||||
|
$(1)_TESTBIN: $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call TestBin_TEMPLATE, \
|
||||||
|
$(algo), \
|
||||||
|
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.elf \
|
||||||
|
)))
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define Listing_TEMPLATE
|
||||||
|
$(1)_LIST: $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call Listing_TEMPLATE, \
|
||||||
|
$(algo), \
|
||||||
|
$(foreach obj,$($(algo)_OBJ), $(LIST_DIR)$(call lc, $(algo))/$(obj:.o=.s)) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
@echo "[objcopy]: $@"
|
||||||
|
@$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define Flash_Template
|
||||||
|
$(1)_FLASH: $(2)
|
||||||
|
@echo "[flash]: $(2)"
|
||||||
|
@$(FLASHCMD)$(call first,$(2))
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call Flash_Template, \
|
||||||
|
$(algo), \
|
||||||
|
$(BIN_DIR)$(call lc, $(algo))/$(TEST_DIR)main-$(call lc, $(algo))-test.hex \
|
||||||
|
)))
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define Speed_Template
|
||||||
|
$(1)_SPEED: $(1)_FLASH
|
||||||
|
@$(RUBY) $(SPEEDTOOL) -c $(SPEEDCMD) -t $(SPEEDLOG_DIR) -a $(call lc, $(1))
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call Speed_Template, \
|
||||||
|
$(algo), $(algo) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
.PHONY: hash_speed
|
||||||
|
hash_speed: $(foreach algo, $(HASHES), $(algo)_SPEED)
|
||||||
|
|
||||||
|
.PHONY: blockcipher_speed
|
||||||
|
blockcipher_speed: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_SPEED)
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
define Size_Template
|
||||||
|
$(1)_SIZE: $(2)
|
||||||
|
@echo "[size] $(1)"
|
||||||
|
$(SIZE) $(2) > $(strip $(SIZE_DIR))$(strip $(call lc, $(1))).size
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), $(eval $(call Size_Template, \
|
||||||
|
$(strip $(algo)), $($(algo)_BINOBJ) \
|
||||||
|
)))
|
||||||
|
|
||||||
|
.PHONY: hash_size
|
||||||
|
hash_size: $(foreach algo, $(HASHES), $(algo)_SIZE)
|
||||||
|
|
||||||
|
.PHONY: blockcipher_size
|
||||||
|
blockcipher_size: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_SIZE)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: tests
|
||||||
|
tests: $(foreach a, $(ALGORITHMS), $(a)_TESTBIN)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define TestRun_Template
|
||||||
|
$(1)_TESTRUN: $(1)_FLASH
|
||||||
|
@echo "[reset]"
|
||||||
|
@sleep 3
|
||||||
|
@$(RESETCMD)
|
||||||
|
@sleep 1
|
||||||
|
@echo "[test]: $(1)"
|
||||||
|
$(RUBY) $(GET_TEST) $(TESTPORT) $(TESTPORTBAUDR) 8 1 nessie $(TESTLOG_DIR)$(TESTPREFIX) $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS),$(eval $(call TestRun_Template, $(algo), $(call lc,$(algo)) )))
|
||||||
|
|
||||||
|
all_testrun: $(foreach algo, $(ALGORITHMS), $(algo)_TESTRUN)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
define Obj_Template
|
||||||
|
$(1)_OBJ: $(2)
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach algo, $(ALGORITHMS), \
|
||||||
|
$(eval $(call Obj_Template, \
|
||||||
|
$(algo), \
|
||||||
|
$($(algo)_BINOBJ)\
|
||||||
|
))\
|
||||||
|
)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: cores
|
||||||
|
|
||||||
|
.PHONY: reset
|
||||||
|
reset:
|
||||||
|
$(RESETCMD)
|
||||||
|
|
||||||
|
.PHONY: cores
|
||||||
|
cores: $(foreach algo, $(ALGORITHMS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: blockchiphers
|
||||||
|
blockciphers: $(foreach algo, $(BLOCK_CIPHERS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: streamchiphers
|
||||||
|
streamciphers: $(foreach algo, $(STREAM_CIPHERS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: hashes
|
||||||
|
hashes: $(foreach algo, $(HASHES), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: macs
|
||||||
|
macs: $(foreach algo, $(MACS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: prngs
|
||||||
|
prngs: $(foreach algo, $(PRNGS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: encodings
|
||||||
|
encodings: $(foreach algo, $(ENCODINGS), $(algo)_OBJ)
|
||||||
|
|
||||||
|
.PHONY: aux
|
||||||
|
aux: $(foreach algo, $(AUX), $(algo)_OBJ)
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
.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 " signature functions:"
|
||||||
|
@echo " $(SIGNATURE)"
|
||||||
|
@echo " public key ciphers:"
|
||||||
|
@echo " $(PK_CIPHERS)"
|
||||||
|
@echo " encodings:"
|
||||||
|
@echo " $(ENCODINGS)"
|
||||||
|
@echo " auxiliary functions:"
|
||||||
|
@echo " $(AUX)"
|
||||||
|
@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 " hash_size - measure size of all hash functions"
|
||||||
|
@echo " hash_speed - measure performance of all hash functions"
|
||||||
|
@echo " blockcipher_size - measure size of all blockciphers"
|
||||||
|
@echo " blockcipher_speed - measure performance of all blockciphers"
|
||||||
|
@echo " docu - build doxygen documentation"
|
||||||
|
@echo " clean - remove a lot of builded files"
|
||||||
|
@echo " depclean - also remove dependency files"
|
||||||
|
@echo " *_TESTBIN - build test program"
|
||||||
|
@echo " *_TESTRUN - run nessie test"
|
||||||
|
@echo " *_OBJ - build algorithm core"
|
||||||
|
@echo " *_FLASH - flash test program"
|
||||||
|
@echo " *_LIST - build assembler listing"
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(BIN_DIR)*
|
||||||
|
|
||||||
|
.PHONY: depclean
|
||||||
|
depclean: clean
|
||||||
|
rm -f $(DEP_DIR)*.d
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# dependency inclusion
|
||||||
|
#
|
||||||
|
|
||||||
|
DEPS := $(wildcard $(DEP_DIR)*.d)
|
||||||
|
|
||||||
|
ifneq ($(DEPS),)
|
||||||
|
include $(DEPS)
|
||||||
|
endif
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
DEBUG = -gdwarf-2
|
||||||
|
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
|
||||||
|
PROGRAMMER = jtagmkII
|
||||||
|
PROG_PORT = usb
|
||||||
|
FLASHCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -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
|
||||||
|
#RESETCMD = avrdude -p $(MCU_TARGET) -P $(PROG_PORT) -c $(PROGRAMMER)
|
||||||
|
RESETCMD = avarice -2 -R -j usb
|
||||||
|
DEP_DIR = deps/$(BOARD_NAME)/#
|
||||||
|
TEST_DIR = test/#
|
||||||
|
BIN_DIR = bin/$(BOARD_NAME)/#
|
||||||
|
TESTSRC_DIR = test_src/
|
||||||
|
#uisp -dprog=bsd -dlpt=/dev/parport1 --upload if=$(PRG).hex
|
||||||
|
ERASECMD =
|
||||||
|
TESTPORT = /dev/ttyUSB0
|
||||||
|
TESTPORTBAUDR = 115200
|
||||||
|
TESTLOG_DIR = testlog/#
|
||||||
|
TESTPREFIX = nessie-
|
||||||
|
SPEEDTOOL = host/get_performance.rb
|
||||||
|
SPEEDLOG_DIR = speed_log/$(BOARD_NAME)/#
|
||||||
|
SPEEDPREFIX =
|
||||||
|
SPEEDCMD = performance
|
||||||
|
SIZE_DIR = size_log/$(BOARD_NAME)/#
|
||||||
|
LIST_DIR = listings/$(BOARD_NAME)/#
|
||||||
|
LIST_OPT = -Wa,-adhln -g
|
||||||
|
STAT_DIR = stats/$(BOARD_NAME)/#
|
||||||
|
AUTOASM_DIR = autoasm/$(BOARD_NAME)/#
|
||||||
|
AUTOASM_OPT = -S
|
||||||
|
CC = avr-gcc
|
||||||
|
CSTD = c99
|
||||||
|
|
||||||
|
SIZESTAT_FILE = sizestats.txt
|
||||||
|
|
||||||
|
OBJCOPY = avr-objcopy
|
||||||
|
OBJDUMP = avr-objdump
|
||||||
|
SIZE = avr-size
|
||||||
|
READELF = readelf
|
||||||
|
RUBY = ruby
|
||||||
|
GET_TEST = host/get_test.rb
|
||||||
|
MAKE = make
|
||||||
|
MAKE2GRAPH = ~/bin/make2graph.rb
|
||||||
|
TWOPI = twopi
|
|
@ -2,6 +2,7 @@
|
||||||
MCU_TARGET = atmega128
|
MCU_TARGET = atmega128
|
||||||
F_CPU = 14745600
|
F_CPU = 14745600
|
||||||
OPTIMIZE = -Os # -Os
|
OPTIMIZE = -Os # -Os
|
||||||
|
EXTRALINK = xram.o
|
||||||
DEBUG = -gdwarf-2
|
DEBUG = -gdwarf-2
|
||||||
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
|
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
|
||||||
PROGRAMMER = jtagmkII
|
PROGRAMMER = jtagmkII
|
||||||
|
@ -37,7 +38,7 @@ CSTD = c99
|
||||||
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
override CFLAGS_A = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $(1))) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
override CFLAGS = -MMD -MF$(DEP_DIR)$(patsubst %.o,%.d,$(notdir $@)) $(DEBUG) $(WARNING) -std=$(CSTD) $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
|
|
||||||
override LDFLAGS = -gdwarf-2 -Wl,-Map,#
|
override LDFLAGS = -gdwarf-2 -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x807fff -Wl,-Map,#
|
||||||
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
override ASFLAGS = -mmcu=$(MCU_TARGET) -Wa,--gdwarf-2
|
||||||
|
|
||||||
SIZESTAT_FILE = sizestats.txt
|
SIZESTAT_FILE = sizestats.txt
|
||||||
|
|
589
bigint/bigint.c
589
bigint/bigint.c
|
@ -1,6 +1,6 @@
|
||||||
/* bigint.c */
|
/* bigint.c */
|
||||||
/*
|
/*
|
||||||
This file is part of the AVR-Crypto-Lib.
|
This file is part of the ARM-Crypto-Lib.
|
||||||
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -32,10 +32,14 @@
|
||||||
|
|
||||||
#include "bigint.h"
|
#include "bigint.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
/*
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "bigint_io.h"
|
#include "bigint_io.h"
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,14 +48,14 @@
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SET_FBS(a, v) do{(a)->info &=0xF8; (a)->info |= (v);}while(0)
|
#define SET_FBS(a, v) do{(a)->info &=~BIGINT_FBS_MASK; (a)->info |= (v);}while(0)
|
||||||
#define GET_FBS(a) ((a)->info&BIGINT_FBS_MASK)
|
#define GET_FBS(a) ((a)->info&BIGINT_FBS_MASK)
|
||||||
#define SET_NEG(a) (a)->info |= BIGINT_NEG_MASK
|
#define SET_NEG(a) (a)->info |= BIGINT_NEG_MASK
|
||||||
#define SET_POS(a) (a)->info &= ~BIGINT_NEG_MASK
|
#define SET_POS(a) (a)->info &= ~BIGINT_NEG_MASK
|
||||||
#define XCHG(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
|
#define XCHG(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
|
||||||
#define XCHG_PTR(a,b) do{ a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
|
#define XCHG_PTR(a,b) do{ a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
|
||||||
b = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
|
b = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
|
||||||
a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b)));}while(0)
|
a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b)));}while(0)
|
||||||
|
|
||||||
#define GET_SIGN(a) ((a)->info&BIGINT_NEG_MASK)
|
#define GET_SIGN(a) ((a)->info&BIGINT_NEG_MASK)
|
||||||
|
|
||||||
|
@ -64,10 +68,10 @@ void bigint_adjust(bigint_t* a){
|
||||||
a->info=0;
|
a->info=0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t t;
|
bigint_word_t t;
|
||||||
uint8_t i = 0x07;
|
uint8_t i = BIGINT_WORD_SIZE-1;
|
||||||
t = a->wordv[a->length_B-1];
|
t = a->wordv[a->length_B-1];
|
||||||
while((t&0x80)==0 && i){
|
while((t&(1L<<(BIGINT_WORD_SIZE-1)))==0 && i){
|
||||||
t<<=1;
|
t<<=1;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
@ -76,31 +80,81 @@ void bigint_adjust(bigint_t* a){
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint16_t bigint_length_b(bigint_t* a){
|
||||||
|
if(!a->length_B || a->length_B==0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (a->length_B-1) * BIGINT_WORD_SIZE + GET_FBS(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint16_t bigint_length_B(bigint_t* a){
|
||||||
|
return a->length_B * sizeof(bigint_word_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint32_t bigint_get_first_set_bit(bigint_t* a){
|
||||||
|
if(a->length_B==0){
|
||||||
|
return (uint32_t)(-1);
|
||||||
|
}
|
||||||
|
return (a->length_B-1)*sizeof(bigint_word_t)*8+GET_FBS(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint32_t bigint_get_last_set_bit(bigint_t* a){
|
||||||
|
uint32_t r=0;
|
||||||
|
uint8_t b=0;
|
||||||
|
bigint_word_t x=1;
|
||||||
|
if(a->length_B==0){
|
||||||
|
return (uint32_t)(-1);
|
||||||
|
}
|
||||||
|
while(a->wordv[r]==0 && r<a->length_B){
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
if(a->wordv[r] == 0){
|
||||||
|
return (uint32_t)(-1);
|
||||||
|
}
|
||||||
|
while((x&a->wordv[r])==0){
|
||||||
|
++b;
|
||||||
|
x <<= 1;
|
||||||
|
}
|
||||||
|
return r*BIGINT_WORD_SIZE+b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
void bigint_copy(bigint_t* dest, const bigint_t* src){
|
void bigint_copy(bigint_t* dest, const bigint_t* src){
|
||||||
|
memcpy(dest->wordv, src->wordv, src->length_B*sizeof(bigint_word_t));
|
||||||
dest->length_B = src->length_B;
|
dest->length_B = src->length_B;
|
||||||
dest->info = src->info;
|
dest->info = src->info;
|
||||||
memcpy(dest->wordv, src->wordv, src->length_B);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/* this should be implemented in assembly */
|
/* this should be implemented in assembly */
|
||||||
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
uint16_t t=0, i;
|
uint16_t i;
|
||||||
|
bigint_wordplus_t t=0LL;
|
||||||
if(a->length_B < b->length_B){
|
if(a->length_B < b->length_B){
|
||||||
XCHG_PTR(a,b);
|
XCHG_PTR(a,b);
|
||||||
}
|
}
|
||||||
for(i=0; i<b->length_B; ++i){
|
for(i=0; i<b->length_B; ++i){
|
||||||
t = a->wordv[i] + b->wordv[i] + t;
|
// t = (bigint_wordplus_t)(a->wordv[i]) + (bigint_wordplus_t)(b->wordv[i]) + t;
|
||||||
dest->wordv[i] = (uint8_t)t;
|
t += a->wordv[i];
|
||||||
t>>=8;
|
t += b->wordv[i];
|
||||||
|
dest->wordv[i] = (bigint_word_t)t;
|
||||||
|
t>>=BIGINT_WORD_SIZE;
|
||||||
}
|
}
|
||||||
for(; i<a->length_B; ++i){
|
for(; i<a->length_B; ++i){
|
||||||
t = a->wordv[i] + t;
|
t += a->wordv[i];
|
||||||
dest->wordv[i] = (uint8_t)t;
|
dest->wordv[i] = (bigint_word_t)t;
|
||||||
t>>=8;
|
t>>=BIGINT_WORD_SIZE;
|
||||||
}
|
}
|
||||||
dest->wordv[i++] = t;
|
dest->wordv[i++] = (bigint_word_t)t;
|
||||||
dest->length_B = i;
|
dest->length_B = i;
|
||||||
bigint_adjust(dest);
|
bigint_adjust(dest);
|
||||||
}
|
}
|
||||||
|
@ -109,30 +163,54 @@ void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
|
|
||||||
/* this should be implemented in assembly */
|
/* this should be implemented in assembly */
|
||||||
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
|
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
|
||||||
uint16_t i,j=0;
|
bigint_t x;
|
||||||
uint16_t t=0;
|
#if BIGINT_WORD_SIZE == 8
|
||||||
if(scale>dest->length_B)
|
memset(dest->wordv + dest->length_B, 0, MAX(dest->length_B, a->length_B + scale) - dest->length_B);
|
||||||
memset(dest->wordv+dest->length_B, 0, scale-dest->length_B);
|
x.wordv = dest->wordv + scale;
|
||||||
for(i=scale; i<a->length_B+scale; ++i,++j){
|
x.length_B = dest->length_B - scale;
|
||||||
t = a->wordv[j] + t;
|
if((int16_t)x.length_B < 0)
|
||||||
|
x.length_B = 0;
|
||||||
|
x.info = dest->info;
|
||||||
|
bigint_add_u(&x, &x, a);
|
||||||
|
dest->length_B = x.length_B + scale;
|
||||||
|
dest->info = 0;
|
||||||
|
bigint_adjust(dest);
|
||||||
|
#else
|
||||||
|
#error unimplemented!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* uint16_t i,j=0;
|
||||||
|
uint16_t scale_w;
|
||||||
|
bigint_word_t *dst;
|
||||||
|
bigint_wordplus_t t=0;
|
||||||
|
scale_w = (scale+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||||
|
if(scale>dest->length_B*sizeof(bigint_word_t)){
|
||||||
|
memset(((uint8_t*)dest->wordv)+dest->length_B*sizeof(bigint_word_t), 0, scale-dest->length_B*sizeof(bigint_word_t));
|
||||||
|
}
|
||||||
|
// a->wordv = (const uint32_t*)(((uint8_t*)a->wordv)+(scale&3));
|
||||||
|
dst = dest->wordv + (scale&(sizeof(bigint_word_t)-1));
|
||||||
|
for(i=scale/sizeof(bigint_word_t); i<a->length_B+scale_w; ++i,++j){
|
||||||
|
t += a->wordv[j];
|
||||||
if(dest->length_B>i){
|
if(dest->length_B>i){
|
||||||
t += dest->wordv[i];
|
t += dst[i];
|
||||||
}
|
}
|
||||||
dest->wordv[i] = (uint8_t)t;
|
dst[i] = (bigint_word_t)t;
|
||||||
t>>=8;
|
t>>=BIGINT_WORD_SIZE;
|
||||||
}
|
}
|
||||||
while(t){
|
while(t){
|
||||||
if(dest->length_B>i){
|
if(dest->length_B>i){
|
||||||
t = dest->wordv[i] + t;
|
t += dst[i];
|
||||||
}
|
}
|
||||||
dest->wordv[i] = (uint8_t)t;
|
dst[i] = (bigint_word_t)t;
|
||||||
t>>=8;
|
t>>=BIGINT_WORD_SIZE;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
if(dest->length_B < i){
|
if(dest->length_B < i){
|
||||||
dest->length_B = i;
|
dest->length_B = i;
|
||||||
}
|
}
|
||||||
bigint_adjust(dest);
|
bigint_adjust(dest);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -141,60 +219,46 @@ void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
|
||||||
void bigint_sub_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
void bigint_sub_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
int8_t borrow=0;
|
int8_t borrow=0;
|
||||||
int8_t r;
|
int8_t r;
|
||||||
int16_t t;
|
bigint_wordplus_signed_t t=0LL;
|
||||||
uint16_t i, min, max;
|
uint16_t i, min, max;
|
||||||
min = MIN(a->length_B, b->length_B);
|
min = MIN(a->length_B, b->length_B);
|
||||||
max = MAX(a->length_B, b->length_B);
|
max = MAX(a->length_B, b->length_B);
|
||||||
r = bigint_cmp_u(a,b);
|
r = bigint_cmp_u(a,b);
|
||||||
if(r==0){
|
if(r==0){
|
||||||
dest->length_B = 0;
|
bigint_set_zero(dest);
|
||||||
dest->wordv[0] = 0;
|
|
||||||
bigint_adjust(dest);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(b->length_B==0){
|
if(b->length_B==0){
|
||||||
dest->length_B = a->length_B;
|
bigint_copy(dest, a);
|
||||||
memcpy(dest->wordv, a->wordv, a->length_B);
|
|
||||||
dest->info = a->info;
|
|
||||||
SET_POS(dest);
|
SET_POS(dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(a->length_B==0){
|
if(a->length_B==0){
|
||||||
dest->length_B = b->length_B;
|
bigint_copy(dest, b);
|
||||||
memcpy(dest->wordv, b->wordv, b->length_B);
|
SET_NEG(dest);
|
||||||
dest->info = b->info;
|
return;
|
||||||
SET_NEG(dest);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(r<0){
|
if(r<0){
|
||||||
bigint_sub_u(dest, b, a);
|
bigint_sub_u(dest, b, a);
|
||||||
SET_NEG(dest);
|
SET_NEG(dest);
|
||||||
}else{
|
return;
|
||||||
for(i=0; i<min; ++i){
|
|
||||||
t = a->wordv[i] - b->wordv[i] - borrow;
|
|
||||||
if(t<0){
|
|
||||||
borrow = 1;
|
|
||||||
dest->wordv[i]=(uint8_t)t;
|
|
||||||
}else{
|
|
||||||
borrow = 0;
|
|
||||||
dest->wordv[i]=(uint8_t)t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(;i<max; ++i){
|
|
||||||
t = a->wordv[i] - borrow;
|
|
||||||
if(t<0){
|
|
||||||
borrow = 1;
|
|
||||||
dest->wordv[i]=(uint8_t)t;
|
|
||||||
}else{
|
|
||||||
borrow = 0;
|
|
||||||
dest->wordv[i]=(uint8_t)t;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
SET_POS(dest);
|
|
||||||
dest->length_B = i;
|
|
||||||
bigint_adjust(dest);
|
|
||||||
}
|
}
|
||||||
|
for(i=0; i<max; ++i){
|
||||||
|
t = a->wordv[i];
|
||||||
|
if(i<min){
|
||||||
|
t -= b->wordv[i];
|
||||||
|
}
|
||||||
|
t -= borrow;
|
||||||
|
dest->wordv[i]=(bigint_word_t)t;
|
||||||
|
if(t<0){
|
||||||
|
borrow = 1;
|
||||||
|
}else{
|
||||||
|
borrow = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SET_POS(dest);
|
||||||
|
dest->length_B = i;
|
||||||
|
bigint_adjust(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -212,8 +276,8 @@ int8_t bigint_cmp_u(const bigint_t* a, const bigint_t* b){
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
i = a->length_B-1;
|
i = a->length_B-1;
|
||||||
do{
|
do{
|
||||||
if(a->wordv[i]!=b->wordv[i]){
|
if(a->wordv[i] != b->wordv[i]){
|
||||||
if(a->wordv[i]>b->wordv[i]){
|
if(a->wordv[i] > b->wordv[i]){
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -307,34 +371,35 @@ int8_t bigint_cmp_s(const bigint_t* a, const bigint_t* b){
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void bigint_shiftleft(bigint_t* a, uint16_t shift){
|
void bigint_shiftleft(bigint_t* a, uint16_t shift){
|
||||||
uint16_t byteshift;
|
uint16_t byteshift, word_alloc;
|
||||||
uint16_t i;
|
int16_t i;
|
||||||
uint8_t bitshift;
|
uint8_t bitshift;
|
||||||
uint16_t t=0;
|
bigint_word_t *p;
|
||||||
byteshift = (shift+3)/8;
|
bigint_wordplus_t t=0;
|
||||||
bitshift = shift&7;
|
if(shift==0){
|
||||||
memmove(a->wordv+byteshift, a->wordv, a->length_B);
|
return;
|
||||||
memset(a->wordv, 0, byteshift);
|
|
||||||
if(bitshift!=0){
|
|
||||||
if(bitshift<=4){ /* shift to the left */
|
|
||||||
for(i=byteshift; i<a->length_B+byteshift; ++i){
|
|
||||||
t |= (a->wordv[i])<<bitshift;
|
|
||||||
a->wordv[i] = (uint8_t)t;
|
|
||||||
t >>= 8;
|
|
||||||
}
|
|
||||||
a->wordv[i] = (uint8_t)t;
|
|
||||||
byteshift++;
|
|
||||||
}else{ /* shift to the right */
|
|
||||||
for(i=a->length_B+byteshift-1; i>byteshift-1; --i){
|
|
||||||
t |= (a->wordv[i])<<(bitshift);
|
|
||||||
a->wordv[i] = (uint8_t)(t>>8);
|
|
||||||
t <<= 8;
|
|
||||||
}
|
|
||||||
t |= (a->wordv[i])<<(bitshift);
|
|
||||||
a->wordv[i] = (uint8_t)(t>>8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a->length_B += byteshift;
|
byteshift = shift/8;
|
||||||
|
bitshift = shift&7;
|
||||||
|
for(i=0;i<=byteshift/sizeof(bigint_word_t); ++i){
|
||||||
|
a->wordv[a->length_B+i] = 0;
|
||||||
|
}
|
||||||
|
if(byteshift){
|
||||||
|
memmove(((uint8_t*)a->wordv)+byteshift, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||||
|
memset(a->wordv, 0, byteshift);
|
||||||
|
}
|
||||||
|
p = (bigint_word_t*)(((uint8_t*)a->wordv)+byteshift);
|
||||||
|
word_alloc = a->length_B+(byteshift+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t)+1;
|
||||||
|
a->wordv[word_alloc-1]=0;
|
||||||
|
if(bitshift!=0){
|
||||||
|
for(i=0; i<a->length_B; ++i){
|
||||||
|
t |= ((bigint_wordplus_t)p[i])<<bitshift;
|
||||||
|
p[i] = (bigint_word_t)t;
|
||||||
|
t >>= BIGINT_WORD_SIZE;
|
||||||
|
}
|
||||||
|
p[i] = (bigint_word_t)t;
|
||||||
|
}
|
||||||
|
a->length_B = word_alloc;
|
||||||
bigint_adjust(a);
|
bigint_adjust(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,32 +409,33 @@ void bigint_shiftright(bigint_t* a, uint16_t shift){
|
||||||
uint16_t byteshift;
|
uint16_t byteshift;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint8_t bitshift;
|
uint8_t bitshift;
|
||||||
uint16_t t=0;
|
bigint_wordplus_t t=0;
|
||||||
byteshift = shift/8;
|
byteshift = shift/8;
|
||||||
bitshift = shift&7;
|
bitshift = shift&7;
|
||||||
if(byteshift >= a->length_B){ /* we would shift out more than we have */
|
if(byteshift >= a->length_B*sizeof(bigint_word_t)){ /* we would shift out more than we have */
|
||||||
bigint_set_zero(a);
|
bigint_set_zero(a);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(byteshift == a->length_B-1 && bitshift>GET_FBS(a)){
|
if(byteshift == a->length_B*sizeof(bigint_word_t)-1 && bitshift>GET_FBS(a)){
|
||||||
bigint_set_zero(a);
|
bigint_set_zero(a);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(byteshift){
|
if(byteshift){
|
||||||
memmove(a->wordv, a->wordv+byteshift, a->length_B-byteshift);
|
memmove(a->wordv, (uint8_t*)a->wordv+byteshift, a->length_B-byteshift);
|
||||||
memset(a->wordv+a->length_B-byteshift, 0, byteshift);
|
memset((uint8_t*)a->wordv+a->length_B-byteshift, 0, byteshift);
|
||||||
}
|
}
|
||||||
|
byteshift /= sizeof(bigint_word_t);
|
||||||
if(bitshift!=0){
|
if(bitshift!=0){
|
||||||
/* shift to the right */
|
/* shift to the right */
|
||||||
for(i=a->length_B-byteshift-1; i>0; --i){
|
for(i=a->length_B-byteshift-1; i>0; --i){
|
||||||
t |= (a->wordv[i])<<(8-bitshift);
|
t |= ((bigint_wordplus_t)(a->wordv[i]))<<(BIGINT_WORD_SIZE-bitshift);
|
||||||
a->wordv[i] = (uint8_t)(t>>8);
|
a->wordv[i] = (bigint_word_t)(t>>BIGINT_WORD_SIZE);
|
||||||
t <<= 8;
|
t <<= BIGINT_WORD_SIZE;
|
||||||
}
|
}
|
||||||
t |= (a->wordv[0])<<(8-bitshift);
|
t |= ((bigint_wordplus_t)(a->wordv[0]))<<(BIGINT_WORD_SIZE-bitshift);
|
||||||
a->wordv[0] = (uint8_t)(t>>8);
|
a->wordv[0] = (bigint_word_t)(t>>BIGINT_WORD_SIZE);
|
||||||
}
|
}
|
||||||
a->length_B -= byteshift;
|
a->length_B -= ((shift/8)+sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||||
bigint_adjust(a);
|
bigint_adjust(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +466,7 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
}
|
}
|
||||||
if(dest==a || dest==b){
|
if(dest==a || dest==b){
|
||||||
bigint_t d;
|
bigint_t d;
|
||||||
uint8_t d_b[a->length_B+b->length_B];
|
bigint_word_t d_b[a->length_B+b->length_B];
|
||||||
d.wordv = d_b;
|
d.wordv = d_b;
|
||||||
bigint_mul_u(&d, a, b);
|
bigint_mul_u(&d, a, b);
|
||||||
bigint_copy(dest, &d);
|
bigint_copy(dest, &d);
|
||||||
|
@ -410,78 +476,80 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
if(a->length_B!=1){
|
if(a->length_B!=1){
|
||||||
XCHG_PTR(a,b);
|
XCHG_PTR(a,b);
|
||||||
}
|
}
|
||||||
uint16_t i, t=0;
|
bigint_wordplus_t t=0;
|
||||||
uint8_t x = a->wordv[0];
|
uint16_t i;
|
||||||
for(i=0; i<b->length_B; ++i){
|
bigint_word_t x = a->wordv[0];
|
||||||
t += b->wordv[i]*x;
|
for(i=0; i < b->length_B; ++i){
|
||||||
dest->wordv[i] = (uint8_t)t;
|
t += ((bigint_wordplus_t)b->wordv[i])*((bigint_wordplus_t)x);
|
||||||
t>>=8;
|
dest->wordv[i] = (bigint_word_t)t;
|
||||||
|
t>>=BIGINT_WORD_SIZE;
|
||||||
}
|
}
|
||||||
dest->wordv[i] = (uint8_t)t;
|
dest->wordv[i] = (bigint_word_t)t;
|
||||||
dest->length_B=i+1;
|
dest->length_B = i+1;
|
||||||
|
dest->info = 0;
|
||||||
bigint_adjust(dest);
|
bigint_adjust(dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(a->length_B<=4 && b->length_B<=4){
|
if(a->length_B * sizeof(bigint_word_t) <= 4 && b->length_B * sizeof(bigint_word_t) <= 4){
|
||||||
uint32_t p=0, q=0;
|
uint32_t p=0, q=0;
|
||||||
uint64_t r;
|
uint64_t r;
|
||||||
memcpy(&p, a->wordv, a->length_B);
|
memcpy(&p, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||||
memcpy(&q, b->wordv, b->length_B);
|
memcpy(&q, b->wordv, b->length_B*sizeof(bigint_word_t));
|
||||||
r = (uint64_t)p*(uint64_t)q;
|
r = (uint64_t)p * (uint64_t)q;
|
||||||
memcpy(dest->wordv, &r, a->length_B+b->length_B);
|
memcpy(dest->wordv, &r, (dest->length_B = a->length_B + b->length_B)*sizeof(bigint_word_t));
|
||||||
dest->length_B = a->length_B+b->length_B;
|
|
||||||
bigint_adjust(dest);
|
bigint_adjust(dest);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bigint_set_zero(dest);
|
bigint_set_zero(dest);
|
||||||
/* split a in xh & xl; split b in yh & yl */
|
/* split a in xh & xl; split b in yh & yl */
|
||||||
uint16_t n;
|
const uint16_t n = (MAX(a->length_B, b->length_B)+1)/2;
|
||||||
n=(MAX(a->length_B, b->length_B)+1)/2;
|
|
||||||
bigint_t xl, xh, yl, yh;
|
bigint_t xl, xh, yl, yh;
|
||||||
xl.wordv = a->wordv;
|
xl.wordv = a->wordv;
|
||||||
yl.wordv = b->wordv;
|
yl.wordv = b->wordv;
|
||||||
if(a->length_B<=n){
|
if(a->length_B<=n){
|
||||||
xh.info=0;
|
bigint_set_zero(&xh);
|
||||||
xh.length_B = 0;
|
|
||||||
xl.length_B = a->length_B;
|
xl.length_B = a->length_B;
|
||||||
xl.info = 0;
|
xl.info = a->info;
|
||||||
}else{
|
}else{
|
||||||
xl.length_B=n;
|
xl.length_B=n;
|
||||||
xl.info = 0;
|
xl.info = 0;
|
||||||
bigint_adjust(&xl);
|
bigint_adjust(&xl);
|
||||||
xh.wordv = a->wordv+n;
|
xh.wordv = &(a->wordv[n]);
|
||||||
xh.length_B = a->length_B-n;
|
xh.length_B = a->length_B-n;
|
||||||
xh.info = 0;
|
xh.info = a->info;
|
||||||
}
|
}
|
||||||
if(b->length_B<=n){
|
if(b->length_B<=n){
|
||||||
yh.info=0;
|
bigint_set_zero(&yh);
|
||||||
yh.length_B = 0;
|
|
||||||
yl.length_B = b->length_B;
|
yl.length_B = b->length_B;
|
||||||
yl.info = b->info;
|
yl.info = b->info;
|
||||||
}else{
|
}else{
|
||||||
yl.length_B=n;
|
yl.length_B=n;
|
||||||
yl.info = 0;
|
yl.info = 0;
|
||||||
bigint_adjust(&yl);
|
bigint_adjust(&yl);
|
||||||
yh.wordv = b->wordv+n;
|
yh.wordv = &(b->wordv[n]);
|
||||||
yh.length_B = b->length_B-n;
|
yh.length_B = b->length_B-n;
|
||||||
yh.info = 0;
|
yh.info = b->info;
|
||||||
}
|
}
|
||||||
/* now we have split up a and b */
|
/* now we have split up a and b */
|
||||||
uint8_t tmp_b[2*n+2], m_b[2*(n+1)];
|
/* remember we want to do:
|
||||||
|
* x*y = (xh*yh)*b**2n + ((xh+xl)*(yh+yl) - xh*yh - xl*yl)*b**n + yh*yl
|
||||||
|
* 5 9 2 4 3 7 5 6 1 8 1
|
||||||
|
*/
|
||||||
|
bigint_word_t tmp_b[2*n+2], m_b[2*(n+1)];
|
||||||
bigint_t tmp, tmp2, m;
|
bigint_t tmp, tmp2, m;
|
||||||
tmp.wordv = tmp_b;
|
tmp.wordv = tmp_b;
|
||||||
tmp2.wordv = tmp_b+n+1;
|
tmp2.wordv = &(tmp_b[n+1]);
|
||||||
m.wordv = m_b;
|
m.wordv = m_b;
|
||||||
|
|
||||||
bigint_mul_u(dest, &xl, &yl); /* dest <= xl*yl */
|
bigint_mul_u(dest, &xl, &yl); /* 1: dest <= xl*yl */
|
||||||
bigint_add_u(&tmp2, &xh, &xl); /* tmp2 <= xh+xl */
|
bigint_add_u(&tmp2, &xh, &xl); /* 2: tmp2 <= xh+xl */
|
||||||
bigint_add_u(&tmp, &yh, &yl); /* tmp <= yh+yl */
|
bigint_add_u(&tmp, &yh, &yl); /* 3: tmp <= yh+yl */
|
||||||
bigint_mul_u(&m, &tmp2, &tmp); /* m <= tmp2*tmp */
|
bigint_mul_u(&m, &tmp2, &tmp); /* 4: m <= tmp2*tmp */
|
||||||
bigint_mul_u(&tmp, &xh, &yh); /* h <= xh*yh */
|
bigint_mul_u(&tmp, &xh, &yh); /* 5: h <= xh*yh */
|
||||||
bigint_sub_u(&m, &m, dest); /* m <= m-dest */
|
bigint_sub_u(&m, &m, dest); /* 6: m <= m-dest */
|
||||||
bigint_sub_u(&m, &m, &tmp); /* m <= m-h */
|
bigint_sub_u(&m, &m, &tmp); /* 7: m <= m-h */
|
||||||
bigint_add_scale_u(dest, &m, n);
|
bigint_add_scale_u(dest, &m, n*sizeof(bigint_word_t)); /* 8: dest <= dest+m**n*/
|
||||||
bigint_add_scale_u(dest, &tmp, 2*n);
|
bigint_add_scale_u(dest, &tmp, 2*n*sizeof(bigint_word_t)); /* 9: dest <= dest+tmp**(2*n) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -517,11 +585,11 @@ void bigint_mul_s(bigint_t* dest, const bigint_t* a, const bigint_t* b){
|
||||||
/* square */
|
/* square */
|
||||||
/* (xh*b^n+xl)^2 = xh^2*b^2n + 2*xh*xl*b^n + xl^2 */
|
/* (xh*b^n+xl)^2 = xh^2*b^2n + 2*xh*xl*b^n + xl^2 */
|
||||||
void bigint_square(bigint_t* dest, const bigint_t* a){
|
void bigint_square(bigint_t* dest, const bigint_t* a){
|
||||||
if(a->length_B<=4){
|
if(a->length_B*sizeof(bigint_word_t)<=4){
|
||||||
uint64_t r=0;
|
uint64_t r=0;
|
||||||
memcpy(&r, a->wordv, a->length_B);
|
memcpy(&r, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||||
r = r*r;
|
r = r*r;
|
||||||
memcpy(dest->wordv, &r, 2*a->length_B);
|
memcpy(dest->wordv, &r, 2*a->length_B*sizeof(bigint_word_t));
|
||||||
SET_POS(dest);
|
SET_POS(dest);
|
||||||
dest->length_B=2*a->length_B;
|
dest->length_B=2*a->length_B;
|
||||||
bigint_adjust(dest);
|
bigint_adjust(dest);
|
||||||
|
@ -529,7 +597,7 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
|
||||||
}
|
}
|
||||||
if(dest==a){
|
if(dest==a){
|
||||||
bigint_t d;
|
bigint_t d;
|
||||||
uint8_t d_b[a->length_B*2];
|
bigint_word_t d_b[a->length_B*2];
|
||||||
d.wordv = d_b;
|
d.wordv = d_b;
|
||||||
bigint_square(&d, a);
|
bigint_square(&d, a);
|
||||||
bigint_copy(dest, &d);
|
bigint_copy(dest, &d);
|
||||||
|
@ -538,79 +606,115 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
n=(a->length_B+1)/2;
|
n=(a->length_B+1)/2;
|
||||||
bigint_t xh, xl, tmp; /* x-high, x-low, temp */
|
bigint_t xh, xl, tmp; /* x-high, x-low, temp */
|
||||||
uint8_t buffer[2*n+1];
|
bigint_word_t buffer[2*n+1];
|
||||||
xl.wordv = a->wordv;
|
xl.wordv = a->wordv;
|
||||||
xl.length_B = n;
|
xl.length_B = n;
|
||||||
xh.wordv = a->wordv+n;
|
xl.info = 0;
|
||||||
|
xh.wordv = &(a->wordv[n]);
|
||||||
xh.length_B = a->length_B-n;
|
xh.length_B = a->length_B-n;
|
||||||
|
xh.info = 0;
|
||||||
|
bigint_adjust(&xl);
|
||||||
|
bigint_adjust(&xh);
|
||||||
tmp.wordv = buffer;
|
tmp.wordv = buffer;
|
||||||
|
/* (xh * b**n + xl)**2 = xh**2 * b**2n + 2 * xh * xl * b**n + xl**2 */
|
||||||
|
|
||||||
|
// cli_putstr("\r\nDBG (a): xl: "); bigint_print_hex(&xl);
|
||||||
|
// cli_putstr("\r\nDBG (b): xh: "); bigint_print_hex(&xh);
|
||||||
bigint_square(dest, &xl);
|
bigint_square(dest, &xl);
|
||||||
|
// cli_putstr("\r\nDBG (1): xl**2: "); bigint_print_hex(dest);
|
||||||
bigint_square(&tmp, &xh);
|
bigint_square(&tmp, &xh);
|
||||||
bigint_add_scale_u(dest, &tmp, 2*n);
|
// cli_putstr("\r\nDBG (2): xh**2: "); bigint_print_hex(&tmp);
|
||||||
|
bigint_add_scale_u(dest, &tmp, 2*n*sizeof(bigint_word_t));
|
||||||
|
// cli_putstr("\r\nDBG (3): xl**2 + xh**2*n**2: "); bigint_print_hex(dest);
|
||||||
bigint_mul_u(&tmp, &xl, &xh);
|
bigint_mul_u(&tmp, &xl, &xh);
|
||||||
|
// cli_putstr("\r\nDBG (4): xl*xh: "); bigint_print_hex(&tmp);
|
||||||
bigint_shiftleft(&tmp, 1);
|
bigint_shiftleft(&tmp, 1);
|
||||||
bigint_add_scale_u(dest, &tmp, n);
|
// cli_putstr("\r\nDBG (5): xl*xh*2: "); bigint_print_hex(&tmp);
|
||||||
|
bigint_add_scale_u(dest, &tmp, n*sizeof(bigint_word_t));
|
||||||
|
// cli_putstr("\r\nDBG (6): x**2: "); bigint_print_hex(dest);
|
||||||
|
// cli_putstr("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void bigint_sub_u_bitscale(bigint_t* a, const bigint_t* b, uint16_t bitscale){
|
void bigint_sub_u_bitscale(bigint_t* a, const bigint_t* b, uint16_t bitscale){
|
||||||
bigint_t tmp;
|
bigint_t tmp, x;
|
||||||
uint8_t tmp_b[b->length_B+1];
|
bigint_word_t tmp_b[b->length_B + 1];
|
||||||
uint16_t i,j,byteshift=bitscale/8;
|
const uint16_t word_shift = bitscale / BIGINT_WORD_SIZE;
|
||||||
uint8_t borrow=0;
|
|
||||||
int16_t t;
|
|
||||||
|
|
||||||
if(a->length_B < b->length_B+byteshift){
|
if(a->length_B < b->length_B + word_shift){
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\nDBG: *bang*\r\n");
|
||||||
|
#endif
|
||||||
bigint_set_zero(a);
|
bigint_set_zero(a);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp.wordv = tmp_b;
|
tmp.wordv = tmp_b;
|
||||||
bigint_copy(&tmp, b);
|
bigint_copy(&tmp, b);
|
||||||
bigint_shiftleft(&tmp, bitscale&7);
|
bigint_shiftleft(&tmp, bitscale % BIGINT_WORD_SIZE);
|
||||||
|
|
||||||
for(j=0,i=byteshift; i<tmp.length_B+byteshift; ++i, ++j){
|
x.info = a->info;
|
||||||
t = a->wordv[i] - tmp.wordv[j] - borrow;
|
x.wordv = &(a->wordv[word_shift]);
|
||||||
a->wordv[i] = (uint8_t)t;
|
x.length_B = a->length_B - word_shift;
|
||||||
if(t<0){
|
|
||||||
borrow = 1;
|
bigint_sub_u(&x, &x, &tmp);
|
||||||
}else{
|
|
||||||
borrow = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(borrow){
|
|
||||||
if(i+1 > a->length_B){
|
|
||||||
bigint_set_zero(a);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
a->wordv[i] -= borrow;
|
|
||||||
if(a->wordv[i]!=0xff){
|
|
||||||
borrow=0;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
bigint_adjust(a);
|
bigint_adjust(a);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void bigint_reduce(bigint_t* a, const bigint_t* r){
|
void bigint_reduce(bigint_t* a, const bigint_t* r){
|
||||||
// bigint_adjust(r);
|
// bigint_adjust((bigint_t*)r);
|
||||||
uint8_t rfbs = GET_FBS(r);
|
uint8_t rfbs = GET_FBS(r);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\nDBG: (a) = "); bigint_print_hex(a);
|
||||||
|
#endif
|
||||||
if(r->length_B==0 || a->length_B==0){
|
if(r->length_B==0 || a->length_B==0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while(a->length_B > r->length_B){
|
if((r->length_B*sizeof(bigint_word_t)<=4) && (a->length_B*sizeof(bigint_word_t)<=4)){
|
||||||
bigint_sub_u_bitscale(a, r, (a->length_B-r->length_B)*8+GET_FBS(a)-rfbs-1);
|
uint32_t p=0, q=0;
|
||||||
|
memcpy(&p, a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||||
|
memcpy(&q, r->wordv, r->length_B*sizeof(bigint_word_t));
|
||||||
|
p %= q;
|
||||||
|
memcpy(a->wordv, &p, a->length_B*sizeof(bigint_word_t));
|
||||||
|
bigint_adjust(a);
|
||||||
|
// cli_putstr("\r\nDBG: (0) = "); bigint_print_hex(a);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
while((GET_FBS(a) > rfbs+1) && (a->length_B == r->length_B)){
|
uint16_t shift;
|
||||||
bigint_sub_u_bitscale(a, r, GET_FBS(a)-rfbs-1);
|
while(a->length_B > r->length_B){
|
||||||
|
shift = (a->length_B - r->length_B) * 8 * sizeof(bigint_word_t) + GET_FBS(a) - rfbs - 1;
|
||||||
|
/*
|
||||||
|
if((a->wordv[a->length_B-1] & ((1LL<<GET_FBS(a)) - 1)) > r->wordv[r->length_B-1]){
|
||||||
|
// cli_putc('~');
|
||||||
|
cli_putstr("\r\n ~ [a] = ");
|
||||||
|
cli_hexdump_rev(&a->wordv[a->length_B-1], 4);
|
||||||
|
cli_putstr(" [r] = ");
|
||||||
|
cli_hexdump_rev(&r->wordv[r->length_B-1], 4);
|
||||||
|
shift += 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// cli_putstr("\r\nDBG: (p) shift = "); cli_hexdump_rev(&shift, 2);
|
||||||
|
// cli_putstr(" a_len = "); cli_hexdump_rev(&a->length_B, 2);
|
||||||
|
// cli_putstr(" r_len = "); cli_hexdump_rev(&r->length_B, 2);
|
||||||
|
// uart_flush(0);
|
||||||
|
bigint_sub_u_bitscale(a, r, shift);
|
||||||
|
// cli_putstr("\r\nDBG: (1) = "); bigint_print_hex(a);
|
||||||
|
}
|
||||||
|
while((GET_FBS(a) > rfbs) && (a->length_B == r->length_B)){
|
||||||
|
shift = GET_FBS(a)-rfbs-1;
|
||||||
|
// cli_putstr("\r\nDBG: (q) shift = "); cli_hexdump_rev(&shift, 2);
|
||||||
|
bigint_sub_u_bitscale(a, r, shift);
|
||||||
|
// cli_putstr("\r\nDBG: (2) = "); bigint_print_hex(a);
|
||||||
}
|
}
|
||||||
while(bigint_cmp_u(a,r)>=0){
|
while(bigint_cmp_u(a,r)>=0){
|
||||||
bigint_sub_u(a,a,r);
|
bigint_sub_u(a,a,r);
|
||||||
|
// cli_putstr("\r\nDBG: (3) = "); bigint_print_hex(a);
|
||||||
}
|
}
|
||||||
|
bigint_adjust(a);
|
||||||
|
// cli_putstr("\r\nDBG: (a) = "); bigint_print_hex(a);
|
||||||
|
// cli_putstr("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -623,71 +727,116 @@ void bigint_expmod_u(bigint_t* dest, const bigint_t* a, const bigint_t* exp, con
|
||||||
}
|
}
|
||||||
|
|
||||||
bigint_t res, base;
|
bigint_t res, base;
|
||||||
uint8_t base_b[MAX(a->length_B,r->length_B*2)], res_b[r->length_B*2];
|
bigint_word_t t, base_b[MAX(a->length_B,r->length_B)], res_b[r->length_B*2];
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint8_t j, t;
|
uint8_t j;
|
||||||
|
// uint16_t *xaddr = &i;
|
||||||
|
// cli_putstr("\r\npre-alloc (");
|
||||||
|
// cli_hexdump_rev(&xaddr, 4);
|
||||||
|
// cli_putstr(") ...");
|
||||||
res.wordv = res_b;
|
res.wordv = res_b;
|
||||||
base.wordv = base_b;
|
base.wordv = base_b;
|
||||||
bigint_copy(&base, a);
|
bigint_copy(&base, a);
|
||||||
|
// cli_putstr("\r\npost-copy");
|
||||||
bigint_reduce(&base, r);
|
bigint_reduce(&base, r);
|
||||||
res.wordv[0]=1;
|
res.wordv[0]=1;
|
||||||
res.length_B=1;
|
res.length_B=1;
|
||||||
res.info = 0;
|
res.info = 0;
|
||||||
bigint_adjust(&res);
|
bigint_adjust(&res);
|
||||||
for(i=0; i+1<exp->length_B; ++i){
|
if(exp->length_B == 0){
|
||||||
t=exp->wordv[i];
|
bigint_copy(dest, &res);
|
||||||
for(j=0; j<8; ++j){
|
return;
|
||||||
if(t&1){
|
}
|
||||||
bigint_mul_u(&res, &res, &base);
|
uint8_t flag = 0;
|
||||||
bigint_reduce(&res, r);
|
t=exp->wordv[exp->length_B - 1];
|
||||||
|
for(i=exp->length_B; i > 0; --i){
|
||||||
|
t = exp->wordv[i - 1];
|
||||||
|
for(j=BIGINT_WORD_SIZE; j > 0; --j){
|
||||||
|
if(!flag){
|
||||||
|
if(t & (1<<(BIGINT_WORD_SIZE-1))){
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bigint_square(&base, &base);
|
if(flag){
|
||||||
bigint_reduce(&base, r);
|
bigint_square(&res, &res);
|
||||||
t>>=1;
|
bigint_reduce(&res, r);
|
||||||
|
if(t & (1<<(BIGINT_WORD_SIZE-1))){
|
||||||
|
bigint_mul_u(&res, &res, &base);
|
||||||
|
bigint_reduce(&res, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t<<=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t=exp->wordv[i];
|
|
||||||
while(t){
|
// cli_putc('+');
|
||||||
if(t&1){
|
|
||||||
bigint_mul_u(&res, &res, &base);
|
|
||||||
bigint_reduce(&res, r);
|
|
||||||
}
|
|
||||||
bigint_square(&base, &base);
|
|
||||||
bigint_reduce(&base, r);
|
|
||||||
t>>=1;
|
|
||||||
}
|
|
||||||
SET_POS(&res);
|
SET_POS(&res);
|
||||||
bigint_copy(dest, &res);
|
bigint_copy(dest, &res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#define cli_putstr(a)
|
||||||
|
#define bigint_print_hex(a)
|
||||||
|
#define cli_hexdump_rev(a,b)
|
||||||
|
#define uart_flush(a)
|
||||||
|
|
||||||
/* gcd <-- gcd(x,y) a*x+b*y=gcd */
|
/* gcd <-- gcd(x,y) a*x+b*y=gcd */
|
||||||
void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, const bigint_t* y){
|
void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, const bigint_t* y){
|
||||||
bigint_t g, x_, y_, u, v, a_, b_, c_, d_;
|
bigint_t g, x_, y_, u, v, a_, b_, c_, d_;
|
||||||
volatile uint16_t i=0;
|
uint16_t i=0;
|
||||||
if(x->length_B==0 || y->length_B==0){
|
if(x->length_B==0 || y->length_B==0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(x->length_B==1 && x->wordv[0]==1){
|
||||||
|
gcd->length_B = 1;
|
||||||
|
gcd->wordv[0] = 1;
|
||||||
|
if(a){
|
||||||
|
a->length_B = 1;
|
||||||
|
a->wordv[0] = 1;
|
||||||
|
SET_POS(a);
|
||||||
|
bigint_adjust(a);
|
||||||
|
}
|
||||||
|
if(b){
|
||||||
|
bigint_set_zero(b);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(y->length_B==1 && y->wordv[0]==1){
|
||||||
|
gcd->length_B = 1;
|
||||||
|
gcd->wordv[0] = 1;
|
||||||
|
if(b){
|
||||||
|
b->length_B = 1;
|
||||||
|
b->wordv[0] = 1;
|
||||||
|
SET_POS(b);
|
||||||
|
bigint_adjust(b);
|
||||||
|
}
|
||||||
|
if(a){
|
||||||
|
bigint_set_zero(a);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while(x->wordv[i]==0 && y->wordv[i]==0){
|
while(x->wordv[i]==0 && y->wordv[i]==0){
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
uint8_t g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i];
|
bigint_word_t g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i];
|
||||||
uint8_t u_b[x->length_B-i], v_b[y->length_B-i];
|
bigint_word_t u_b[x->length_B-i], v_b[y->length_B-i];
|
||||||
uint8_t a_b[y->length_B+2], c_b[y->length_B+2];
|
bigint_word_t a_b[y->length_B+2], c_b[y->length_B+2];
|
||||||
uint8_t b_b[x->length_B+2], d_b[x->length_B+2];
|
bigint_word_t b_b[x->length_B+2], d_b[x->length_B+2];
|
||||||
|
|
||||||
g.wordv = g_b;
|
g.wordv = g_b;
|
||||||
x_.wordv = x_b;
|
x_.wordv = x_b;
|
||||||
y_.wordv = y_b;
|
y_.wordv = y_b;
|
||||||
memset(g_b, 0, i);
|
memset(g_b, 0, i*sizeof(bigint_word_t));
|
||||||
g_b[i]=1;
|
g_b[i]=1;
|
||||||
g.length_B = i+1;
|
g.length_B = i+1;
|
||||||
g.info=0;
|
g.info=0;
|
||||||
x_.info = y_.info = 0;
|
x_.info = y_.info = 0;
|
||||||
x_.length_B = x->length_B-i;
|
x_.length_B = x->length_B-i;
|
||||||
y_.length_B = y->length_B-i;
|
y_.length_B = y->length_B-i;
|
||||||
memcpy(x_.wordv, x->wordv+i, x_.length_B);
|
memcpy(x_.wordv, x->wordv+i, x_.length_B*sizeof(bigint_word_t));
|
||||||
memcpy(y_.wordv, y->wordv+i, y_.length_B);
|
memcpy(y_.wordv, y->wordv+i, y_.length_B*sizeof(bigint_word_t));
|
||||||
for(i=0; (x_.wordv[0]&(1<<i))==0 && (y_.wordv[0]&(1<<i))==0; ++i){
|
for(i=0; (x_.wordv[0]&(1<<i))==0 && (y_.wordv[0]&(1<<i))==0; ++i){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,6 +848,7 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
||||||
bigint_shiftright(&x_, i);
|
bigint_shiftright(&x_, i);
|
||||||
bigint_shiftright(&y_, i);
|
bigint_shiftright(&y_, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
u.wordv = u_b;
|
u.wordv = u_b;
|
||||||
v.wordv = v_b;
|
v.wordv = v_b;
|
||||||
a_.wordv = a_b;
|
a_.wordv = a_b;
|
||||||
|
@ -717,7 +867,9 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
||||||
bigint_set_zero(&b_);
|
bigint_set_zero(&b_);
|
||||||
bigint_set_zero(&c_);
|
bigint_set_zero(&c_);
|
||||||
do{
|
do{
|
||||||
|
cli_putstr("\r\nDBG (gcdext) 0");
|
||||||
while((u.wordv[0]&1)==0){
|
while((u.wordv[0]&1)==0){
|
||||||
|
cli_putstr("\r\nDBG (gcdext) 0.1");
|
||||||
bigint_shiftright(&u, 1);
|
bigint_shiftright(&u, 1);
|
||||||
if((a_.wordv[0]&1) || (b_.wordv[0]&1)){
|
if((a_.wordv[0]&1) || (b_.wordv[0]&1)){
|
||||||
bigint_add_s(&a_, &a_, &y_);
|
bigint_add_s(&a_, &a_, &y_);
|
||||||
|
@ -727,6 +879,7 @@ void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, c
|
||||||
bigint_shiftright(&b_, 1);
|
bigint_shiftright(&b_, 1);
|
||||||
}
|
}
|
||||||
while((v.wordv[0]&1)==0){
|
while((v.wordv[0]&1)==0){
|
||||||
|
cli_putstr("\r\nDBG (gcdext) 0.2");
|
||||||
bigint_shiftright(&v, 1);
|
bigint_shiftright(&v, 1);
|
||||||
if((c_.wordv[0]&1) || (d_.wordv[0]&1)){
|
if((c_.wordv[0]&1) || (d_.wordv[0]&1)){
|
||||||
bigint_add_s(&c_, &c_, &y_);
|
bigint_add_s(&c_, &c_, &y_);
|
||||||
|
@ -770,8 +923,8 @@ void bigint_inverse(bigint_t* dest, const bigint_t* a, const bigint_t* m){
|
||||||
|
|
||||||
void bigint_changeendianess(bigint_t* a){
|
void bigint_changeendianess(bigint_t* a){
|
||||||
uint8_t t, *p, *q;
|
uint8_t t, *p, *q;
|
||||||
p = a->wordv;
|
p = (uint8_t*)(a->wordv);
|
||||||
q = p+a->length_B-1;
|
q = ((uint8_t*)p)+a->length_B*sizeof(bigint_word_t)-1;
|
||||||
while(p<q){
|
while(p<q){
|
||||||
t = *p;
|
t = *p;
|
||||||
*p = *q;
|
*p = *q;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bigint.h */
|
/* bigint.h */
|
||||||
/*
|
/*
|
||||||
This file is part of the AVR-Crypto-Lib.
|
This file is part of the ARM-Crypto-Lib.
|
||||||
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -30,18 +30,29 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define BIGINT_FBS_MASK 0x07 /* the last three bits indicate which is the first bit set */
|
typedef uint8_t bigint_word_t;
|
||||||
|
typedef uint16_t bigint_wordplus_t;
|
||||||
|
typedef int16_t bigint_wordplus_signed_t;
|
||||||
|
typedef uint16_t bigint_ptr_int_t; /* this must be an integer of the size of a pointer for the target architecture */
|
||||||
|
#define BIGINT_WORD_SIZE 8
|
||||||
|
|
||||||
|
#define BIGINT_FBS_MASK (BIGINT_WORD_SIZE-1) /* the last five bits indicate which is the first bit set */
|
||||||
#define BIGINT_NEG_MASK 0x80 /* this bit indicates a negative value */
|
#define BIGINT_NEG_MASK 0x80 /* this bit indicates a negative value */
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint16_t length_B;
|
uint16_t length_B;
|
||||||
uint8_t info;
|
uint8_t info;
|
||||||
uint8_t *wordv; /* word vector, pointing to the LSB */
|
bigint_word_t *wordv; /* word vector, pointing to the LSB */
|
||||||
}bigint_t;
|
}bigint_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void bigint_adjust(bigint_t* a);
|
void bigint_adjust(bigint_t* a);
|
||||||
|
uint32_t bigint_get_first_set_bit(bigint_t* a);
|
||||||
|
uint32_t bigint_get_last_set_bit(bigint_t* a);
|
||||||
|
uint16_t bigint_length_b(bigint_t* a);
|
||||||
|
uint16_t bigint_length_B(bigint_t* a);
|
||||||
void bigint_copy(bigint_t* dest, const bigint_t* src);
|
void bigint_copy(bigint_t* dest, const bigint_t* src);
|
||||||
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b);
|
void bigint_add_u(bigint_t* dest, const bigint_t* a, const bigint_t* b);
|
||||||
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale);
|
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bigint_io.c */
|
/* bigint_io.c */
|
||||||
/*
|
/*
|
||||||
This file is part of the AVR-Crypto-Lib.
|
This file is part of the ARM-Crypto-Lib.
|
||||||
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "hexdigit_tab.h"
|
#include "hexdigit_tab.h"
|
||||||
#include "bigint.h"
|
#include "bigint.h"
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -33,15 +32,37 @@ void bigint_print_hex(const bigint_t* a){
|
||||||
cli_putc('-');
|
cli_putc('-');
|
||||||
}
|
}
|
||||||
// cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
|
// cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
|
||||||
if(a->wordv[a->length_B-1]<0x10){
|
/* if(a->wordv[a->length_B-1]<0x10){
|
||||||
cli_putc(pgm_read_byte(hexdigit_tab_uc_P+a->wordv[a->length_B-1]));
|
cli_putc(hexdigit_tab_uc[a->wordv[a->length_B-1]]);
|
||||||
cli_hexdump_rev(a->wordv, a->length_B-1);
|
cli_hexdump_rev(a->wordv, a->length_B-1);
|
||||||
} else {
|
} else {
|
||||||
cli_hexdump_rev(a->wordv, a->length_B);
|
*/
|
||||||
|
// cli_hexdump_rev(a->wordv, a->length_B*sizeof(bigint_word_t));
|
||||||
|
// }
|
||||||
|
uint32_t idx;
|
||||||
|
uint8_t print_zero=0;
|
||||||
|
uint8_t *p,x,y;
|
||||||
|
p = (uint8_t*)&(a->wordv[a->length_B-1])+sizeof(bigint_word_t)-1;
|
||||||
|
for(idx = a->length_B * sizeof(bigint_word_t); idx > 0; --idx){
|
||||||
|
x = *p >> 4;
|
||||||
|
y = *p & 0xf;
|
||||||
|
if(x!=0 || print_zero!=0){
|
||||||
|
cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[x]));
|
||||||
|
}
|
||||||
|
if(x){
|
||||||
|
print_zero = 1;
|
||||||
|
}
|
||||||
|
if(y!=0 || print_zero!=0){
|
||||||
|
cli_putc(pgm_read_byte(&hexdigit_tab_lc_P[y]));
|
||||||
|
}
|
||||||
|
if(y){
|
||||||
|
print_zero = 1;
|
||||||
|
}
|
||||||
|
--p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BLOCKSIZE 20
|
#define BLOCKSIZE 32
|
||||||
|
|
||||||
static uint8_t char2nibble(char c){
|
static uint8_t char2nibble(char c){
|
||||||
if(c>='0' && c <='9'){
|
if(c>='0' && c <='9'){
|
||||||
|
@ -76,23 +97,24 @@ static uint16_t read_byte(void){
|
||||||
uint8_t bigint_read_hex_echo(bigint_t* a){
|
uint8_t bigint_read_hex_echo(bigint_t* a){
|
||||||
uint16_t allocated=0;
|
uint16_t allocated=0;
|
||||||
uint8_t shift4=0;
|
uint8_t shift4=0;
|
||||||
uint16_t t;
|
uint16_t t, idx = 0;
|
||||||
a->length_B = 0;
|
a->length_B = 0;
|
||||||
a->wordv = NULL;
|
a->wordv = NULL;
|
||||||
a->info = 0;
|
a->info = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
if(allocated-a->length_B < 1){
|
if(allocated - idx < 1){
|
||||||
uint8_t *p;
|
bigint_word_t *p;
|
||||||
p = realloc(a->wordv, allocated+=BLOCKSIZE);
|
p = realloc(a->wordv, allocated += BLOCKSIZE);
|
||||||
if(p==NULL){
|
if(p==NULL){
|
||||||
cli_putstr_P(PSTR("\r\nERROR: Out of memory!"));
|
cli_putstr("\r\nERROR: Out of memory!");
|
||||||
free(a->wordv);
|
free(a->wordv);
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
memset((uint8_t*)p + allocated - BLOCKSIZE, 0, BLOCKSIZE);
|
||||||
a->wordv=p;
|
a->wordv=p;
|
||||||
}
|
}
|
||||||
t = read_byte();
|
t = read_byte();
|
||||||
if(a->length_B==0){
|
if(idx==0){
|
||||||
if(t&0x0400){
|
if(t&0x0400){
|
||||||
/* got minus */
|
/* got minus */
|
||||||
a->info |= BIGINT_NEG_MASK;
|
a->info |= BIGINT_NEG_MASK;
|
||||||
|
@ -106,11 +128,11 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(t<=0x00ff){
|
if(t<=0x00ff){
|
||||||
a->wordv[a->length_B++] = (uint8_t)t;
|
((uint8_t*)(a->wordv))[idx++] = (uint8_t)t;
|
||||||
}else{
|
}else{
|
||||||
if(t&0x0200){
|
if(t&0x0200){
|
||||||
shift4 = 1;
|
shift4 = 1;
|
||||||
a->wordv[a->length_B++] = (uint8_t)((t&0x0f)<<4);
|
((uint8_t*)(a->wordv))[idx++] = (uint8_t)((t&0x0f)<<4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -118,18 +140,18 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
|
||||||
/* we have to reverse the byte array */
|
/* we have to reverse the byte array */
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
uint8_t *p, *q;
|
uint8_t *p, *q;
|
||||||
p = a->wordv;
|
a->length_B = (idx + sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
|
||||||
q = a->wordv+a->length_B-1;
|
p = (uint8_t*)(a->wordv);
|
||||||
|
q = (uint8_t*)a->wordv + a->length_B * sizeof(bigint_word_t) - 1;
|
||||||
while(q>p){
|
while(q>p){
|
||||||
tmp = *p;
|
tmp = *p;
|
||||||
*p = *q;
|
*p = *q;
|
||||||
*q = tmp;
|
*q = tmp;
|
||||||
p++; q--;
|
p++; q--;
|
||||||
}
|
}
|
||||||
|
bigint_adjust(a);
|
||||||
if(shift4){
|
if(shift4){
|
||||||
bigint_adjust(a);
|
|
||||||
bigint_shiftright(a, 4);
|
bigint_shiftright(a, 4);
|
||||||
}
|
}
|
||||||
bigint_adjust(a);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bigint_io.h */
|
/* bigint_io.h */
|
||||||
/*
|
/*
|
||||||
This file is part of the AVR-Crypto-Lib.
|
This file is part of the ARM-Crypto-Lib.
|
||||||
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|
|
@ -23,7 +23,7 @@ $debug = false
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'serialport'
|
require 'serialport'
|
||||||
require 'getopt/std'
|
require 'getopt/std'
|
||||||
require 'ftools'
|
require 'fileutils'
|
||||||
require 'date'
|
require 'date'
|
||||||
$buffer_size = 0
|
$buffer_size = 0
|
||||||
$conffile_check = Hash.new
|
$conffile_check = Hash.new
|
||||||
|
@ -37,7 +37,7 @@ def readconfigfile(fname, conf)
|
||||||
return conf if $conffile_check[fname]==1
|
return conf if $conffile_check[fname]==1
|
||||||
$conffile_check[fname]=1
|
$conffile_check[fname]=1
|
||||||
section = "default"
|
section = "default"
|
||||||
if not File.exists?(fname)
|
if ! File.exists?(fname)
|
||||||
return conf
|
return conf
|
||||||
end
|
end
|
||||||
file = File.open(fname, "r")
|
file = File.open(fname, "r")
|
||||||
|
@ -49,7 +49,7 @@ def readconfigfile(fname, conf)
|
||||||
conf[m[1]] = Hash.new
|
conf[m[1]] = Hash.new
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
next if not /=/.match(line)
|
next if ! /=/.match(line)
|
||||||
m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
|
m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
|
||||||
if m[1]=="include"
|
if m[1]=="include"
|
||||||
Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
|
Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
|
||||||
|
@ -158,7 +158,7 @@ def wait_for_prompt(prompt)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
acc += line
|
acc += line
|
||||||
end while not m=prompt.match(acc)
|
end while ! m=prompt.match(acc)
|
||||||
return m
|
return m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ def add_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -197,7 +197,7 @@ def add_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||||
$sp.print(b.to_s(16)+" ")
|
$sp.print(b.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -207,7 +207,7 @@ def add_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
end while ! m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
b_ = m[2].to_i(16)
|
b_ = m[2].to_i(16)
|
||||||
c_ = m[3].to_i(16)
|
c_ = m[3].to_i(16)
|
||||||
|
@ -236,7 +236,7 @@ def mul_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -246,7 +246,7 @@ def mul_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||||
$sp.print(b.to_s(16)+" ")
|
$sp.print(b.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -256,7 +256,7 @@ def mul_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
b_ = m[2].to_i(16)
|
b_ = m[2].to_i(16)
|
||||||
c_ = m[3].to_i(16)
|
c_ = m[3].to_i(16)
|
||||||
|
@ -330,7 +330,7 @@ def square_test(a)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -340,7 +340,7 @@ def square_test(a)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
c_ = m[2].to_i(16)
|
c_ = m[2].to_i(16)
|
||||||
line.chomp!
|
line.chomp!
|
||||||
|
@ -368,7 +368,7 @@ def reduce_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -378,7 +378,7 @@ def reduce_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||||
$sp.print(b.to_s(16)+" ")
|
$sp.print(b.to_s(16)+" ")
|
||||||
line=''
|
line=''
|
||||||
begin
|
begin
|
||||||
|
@ -390,7 +390,7 @@ def reduce_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
b_ = m[2].to_i(16)
|
b_ = m[2].to_i(16)
|
||||||
c_ = m[3].to_i(16)
|
c_ = m[3].to_i(16)
|
||||||
|
@ -419,7 +419,7 @@ def expmod_test(a,b,c)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -429,7 +429,7 @@ def expmod_test(a,b,c)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||||
$sp.print(b.to_s(16)+" ")
|
$sp.print(b.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -439,7 +439,7 @@ def expmod_test(a,b,c)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter c:[\s]*/.match(line)
|
end while ! /[\s]*enter c:[\s]*/.match(line)
|
||||||
$sp.print(c.to_s(16)+" ")
|
$sp.print(c.to_s(16)+" ")
|
||||||
line=''
|
line=''
|
||||||
begin
|
begin
|
||||||
|
@ -451,7 +451,7 @@ def expmod_test(a,b,c)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
end while ! m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
b_ = m[2].to_i(16)
|
b_ = m[2].to_i(16)
|
||||||
c_ = m[3].to_i(16)
|
c_ = m[3].to_i(16)
|
||||||
|
@ -481,7 +481,7 @@ def gcdext_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter a:[\s]*/.match(line)
|
end while ! /[\s]*enter a:[\s]*/.match(line)
|
||||||
$sp.print(a.to_s(16)+" ")
|
$sp.print(a.to_s(16)+" ")
|
||||||
begin
|
begin
|
||||||
line = $sp.gets()
|
line = $sp.gets()
|
||||||
|
@ -491,7 +491,7 @@ def gcdext_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not /[\s]*enter b:[\s]*/.match(line)
|
end while ! /[\s]*enter b:[\s]*/.match(line)
|
||||||
$sp.print(b.to_s(16)+" ")
|
$sp.print(b.to_s(16)+" ")
|
||||||
line=''
|
line=''
|
||||||
begin
|
begin
|
||||||
|
@ -504,7 +504,7 @@ def gcdext_test(a,b)
|
||||||
puts line
|
puts line
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end while not m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line)
|
end while ! m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line)
|
||||||
a_ = m[1].to_i(16)
|
a_ = m[1].to_i(16)
|
||||||
b_ = m[2].to_i(16)
|
b_ = m[2].to_i(16)
|
||||||
c_ = m[3].to_i(16)
|
c_ = m[3].to_i(16)
|
||||||
|
@ -834,12 +834,16 @@ if File.exists?(logfilename)
|
||||||
i+=1
|
i+=1
|
||||||
end while(File.exists?(logfilename))
|
end while(File.exists?(logfilename))
|
||||||
while(i>2) do
|
while(i>2) do
|
||||||
File.move(sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt'),
|
n1 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt')
|
||||||
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt'), true)
|
n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt')
|
||||||
|
File.rename(n1, n2)
|
||||||
|
printf("%s -> %s\n", n1, n2)
|
||||||
i-=1
|
i-=1
|
||||||
end
|
end
|
||||||
File.move(sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt'),
|
n1 = sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt')
|
||||||
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt'), true)
|
n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt')
|
||||||
|
File.rename(n1, n2)
|
||||||
|
printf("%s -> %s\n", n1, n2)
|
||||||
logfilename = conf['PORT']['testlogbase']+'bigint.txt'
|
logfilename = conf['PORT']['testlogbase']+'bigint.txt'
|
||||||
end
|
end
|
||||||
$logfile = File.open(logfilename, 'w')
|
$logfile = File.open(logfilename, 'w')
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
CLI_STD = cli-stub.o cli-basics.o cli-core.o cli-hexdump.o debug.o hexdigit_tab.o \
|
CLI_STD = cli-stub.o cli-basics.o cli-core.o cli-hexdump.o debug.o hexdigit_tab.o \
|
||||||
dbz_strings.o string-extras-asm.o uart_i-asm.o circularbytebuffer-asm.o
|
dbz_strings.o string-extras-asm.o uart_i-asm.o circularbytebuffer-asm.o \
|
||||||
|
main-test-common.o
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Makefile for RSA
|
||||||
|
ALGO_NAME := RSA_OAEP
|
||||||
|
|
||||||
|
# comment out the following line for removement of RSA from the build process
|
||||||
|
PK_CIPHERS += $(ALGO_NAME)
|
||||||
|
|
||||||
|
$(ALGO_NAME)_DIR := rsa/
|
||||||
|
$(ALGO_NAME)_INCDIR := memxor/ bigint/ noekeon/ hfal/ sha1/ mgf1/
|
||||||
|
$(ALGO_NAME)_OBJ := bigint.o bigint_io.o rsa_basic.o rsa_oaep.o mgf1.o hfal-basic.o hfal_sha1.o sha1.o
|
||||||
|
$(ALGO_NAME)_TESTBIN := main-rsa_oaep-test.o $(CLI_STD) random_dummy.o \
|
||||||
|
noekeon.o noekeon_prng.o memxor.o
|
||||||
|
|
||||||
|
$(ALGO_NAME)_PERFORMANCE_TEST := performance
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* random_dummy.c */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2006-2011 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 "random_dummy.h"
|
||||||
|
|
||||||
|
uint8_t(*prng_get_byte)(void);
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* random.h */
|
||||||
|
/*
|
||||||
|
This file is part of the AVR-Crypto-Lib.
|
||||||
|
Copyright (C) 2011 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 RANDOM_H_
|
||||||
|
#define RANDOM_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern uint8_t(*prng_get_byte)(void);
|
||||||
|
|
||||||
|
#endif /* RANDOM_H_ */
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* rsa_basic.c */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2006-2011 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "bigint.h"
|
||||||
|
#include "bigint_io.h"
|
||||||
|
#include "rsa_basic.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#include "cli.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rsa_enc(bigint_t* data, rsa_publickey_t* key){
|
||||||
|
/*
|
||||||
|
cli_putstr_P(PSTR("\r\n -->rsa_enc()\r\n m = "));
|
||||||
|
bigint_print_hex(data);
|
||||||
|
cli_putstr_P(PSTR("\r\n e = "));
|
||||||
|
bigint_print_hex(key->exponent);
|
||||||
|
cli_putstr_P(PSTR("\r\n n = "));
|
||||||
|
bigint_print_hex(key->modulus);
|
||||||
|
*/
|
||||||
|
bigint_expmod_u(data, data, key->exponent, key->modulus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
(p,q,dp,dq,qinv)
|
||||||
|
m1 = c**dp % p
|
||||||
|
m2 = c**dq % q
|
||||||
|
h = (m1 - m2) * qinv % p
|
||||||
|
m = m2 + q * h
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t rsa_dec_crt_mono(bigint_t* data, rsa_privatekey_t* key){
|
||||||
|
bigint_t m1, m2;
|
||||||
|
m1.wordv = malloc((key->modulus->length_B + 1) * sizeof(bigint_word_t));
|
||||||
|
m2.wordv = malloc(key->components[1]->length_B * sizeof(bigint_word_t));
|
||||||
|
if(!m1.wordv || !m2.wordv){
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM! (" __FILE__ ")"));
|
||||||
|
#endif
|
||||||
|
free(m1.wordv);
|
||||||
|
free(m2.wordv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("\r\nexp_mod a + b "));
|
||||||
|
#endif
|
||||||
|
bigint_expmod_u(&m1, data, key->components[2], key->components[0]);
|
||||||
|
bigint_expmod_u(&m2, data, key->components[3], key->components[1]);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("[done] "));
|
||||||
|
#endif
|
||||||
|
bigint_sub_s(&m1, &m1, &m2);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("[done2] "));
|
||||||
|
#endif
|
||||||
|
while(BIGINT_NEG_MASK & m1.info){
|
||||||
|
#if DEBUG
|
||||||
|
cli_putc(',');
|
||||||
|
#endif
|
||||||
|
bigint_add_s(&m1, &m1, key->components[0]);
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("\r\nreduce_mul "));
|
||||||
|
#endif
|
||||||
|
bigint_reduce(&m1, key->components[0]);
|
||||||
|
bigint_mul_u(&m1, &m1, key->components[4]);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("[done]"));
|
||||||
|
#endif
|
||||||
|
bigint_reduce(&m1, key->components[0]);
|
||||||
|
bigint_mul_u(&m1, &m1, key->components[1]);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR(" [done]"));
|
||||||
|
#endif
|
||||||
|
bigint_add_u(data, &m1, &m2);
|
||||||
|
free(m1.wordv);
|
||||||
|
free(m2.wordv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rsa_dec(bigint_t* data, rsa_privatekey_t* key){
|
||||||
|
if(key->n == 1){
|
||||||
|
bigint_expmod_u(data, data, key->components[0], key->modulus);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(key->n == 5){
|
||||||
|
if (rsa_dec_crt_mono(data, key)){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(key->n<8 || (key->n-5)%3 != 0){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//rsa_dec_crt_multi(data, key, (key->n-5)/3);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B){
|
||||||
|
uint8_t off;
|
||||||
|
off = length_B % sizeof(bigint_word_t);
|
||||||
|
if(!data){
|
||||||
|
if(off){
|
||||||
|
dest->wordv = realloc(dest->wordv, length_B + sizeof(bigint_word_t) - off);
|
||||||
|
memmove((uint8_t*)dest->wordv+off, dest->wordv, length_B);
|
||||||
|
memset(dest->wordv, 0, off);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(off){
|
||||||
|
memcpy((uint8_t*)dest->wordv + off, data, length_B);
|
||||||
|
memset(dest, 0, off);
|
||||||
|
}else{
|
||||||
|
memcpy(dest->wordv, data, length_B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest->length_B = (length_B + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||||
|
bigint_changeendianess(dest);
|
||||||
|
bigint_adjust(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B){
|
||||||
|
*out_length_B = bigint_get_first_set_bit(src) / 8 + 1;
|
||||||
|
if(dest){
|
||||||
|
uint16_t i;
|
||||||
|
for(i=*out_length_B; i>0; --i){
|
||||||
|
*((uint8_t*)dest) = ((uint8_t*)src->wordv)[i-1];
|
||||||
|
dest = (uint8_t*)dest + 1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
uint8_t off;
|
||||||
|
bigint_changeendianess(src);
|
||||||
|
bigint_adjust(src);
|
||||||
|
|
||||||
|
off = bigint_get_last_set_bit(src)/8;
|
||||||
|
if(off){
|
||||||
|
memmove(src->wordv, (uint8_t*)src->wordv+off, *out_length_B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* rsa_basic.h */
|
||||||
|
/*
|
||||||
|
This file is part of the AVR-Crypto-Lib.
|
||||||
|
Copyright (C) 2011 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 RSA_BASIC_H_
|
||||||
|
#define RSA_BASIC_H_
|
||||||
|
|
||||||
|
#include "bigint.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bigint_t* exponent;
|
||||||
|
bigint_t* modulus;
|
||||||
|
} rsa_publickey_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t n;
|
||||||
|
bigint_t* modulus;
|
||||||
|
bigint_t** components;
|
||||||
|
} rsa_privatekey_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rsa_privatekey_t priv;
|
||||||
|
rsa_publickey_t pub;
|
||||||
|
} rsa_fullkey_t;
|
||||||
|
|
||||||
|
|
||||||
|
void rsa_enc(bigint_t* data, rsa_publickey_t* key);
|
||||||
|
uint8_t rsa_dec(bigint_t* data, rsa_privatekey_t* key);
|
||||||
|
void rsa_os2ip(bigint_t* dest, const void* data, uint32_t length_B);
|
||||||
|
void rsa_i2osp(void* dest, bigint_t* src, uint16_t* out_length_B);
|
||||||
|
|
||||||
|
#endif /* RSA_BASIC_H_ */
|
|
@ -0,0 +1,247 @@
|
||||||
|
|
||||||
|
/* rsa_oaep.c */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2006-2012 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "memxor.h"
|
||||||
|
#include "mgf1.h"
|
||||||
|
#include "bigint.h"
|
||||||
|
#include "rsa_basic.h"
|
||||||
|
#include "rsa_oaep.h"
|
||||||
|
|
||||||
|
#include "random_dummy.h"
|
||||||
|
|
||||||
|
#include "hfal/hfal_sha1.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#include "cli.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mgf1_parameter_t mgf1_default_parameter = {
|
||||||
|
&sha1_desc
|
||||||
|
};
|
||||||
|
|
||||||
|
rsa_oaep_parameter_t rsa_oaep_default_parameter = {
|
||||||
|
mgf1,
|
||||||
|
&sha1_desc,
|
||||||
|
&mgf1_default_parameter
|
||||||
|
};
|
||||||
|
|
||||||
|
rsa_label_t rsa_oaep_default_label = {
|
||||||
|
0, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length,
|
||||||
|
const void* src, uint16_t length_B,
|
||||||
|
rsa_publickey_t* key, const rsa_oaep_parameter_t *p,
|
||||||
|
const rsa_label_t* label, const void* seed){
|
||||||
|
|
||||||
|
if(!p){
|
||||||
|
p = &rsa_oaep_default_parameter;
|
||||||
|
}
|
||||||
|
if(!label){
|
||||||
|
label = &rsa_oaep_default_label;
|
||||||
|
}
|
||||||
|
uint16_t hv_len = (hfal_hash_getHashsize(p->hf)+7)/8;
|
||||||
|
if(length_B > bigint_length_B(key->modulus) - 2*hv_len - 2){
|
||||||
|
/* message too long */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint16_t buffer_len = bigint_length_B(key->modulus);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\n buffer_len = ");
|
||||||
|
cli_hexdump_rev(&buffer_len, 2);
|
||||||
|
cli_putstr("\r\n modulus_len = ");
|
||||||
|
cli_hexdump_rev(&key->modulus->length_B, 2);
|
||||||
|
#endif
|
||||||
|
uint8_t* buffer = (uint8_t*)dest;
|
||||||
|
uint8_t off;
|
||||||
|
/* the following needs some explanation:
|
||||||
|
* off is the offset which is used for compensating the effect of
|
||||||
|
* changeendian() when it operates on multi-byte words.
|
||||||
|
* */
|
||||||
|
off = (sizeof(bigint_word_t) - (bigint_get_first_set_bit(key->modulus)/8+1) % sizeof(bigint_word_t))
|
||||||
|
% (sizeof(bigint_word_t));
|
||||||
|
buffer += off;
|
||||||
|
buffer_len -= off;
|
||||||
|
uint8_t* seed_buffer = buffer + 1;
|
||||||
|
uint16_t db_len = buffer_len - hv_len - 1;
|
||||||
|
uint8_t* db = seed_buffer + hv_len;
|
||||||
|
uint16_t maskbuffer_len = db_len>hv_len?db_len:hv_len;
|
||||||
|
uint8_t maskbuffer[maskbuffer_len];
|
||||||
|
bigint_t x;
|
||||||
|
|
||||||
|
memset(dest, 0, seed_buffer - buffer + off);
|
||||||
|
memset(db + hv_len, 0, db_len - hv_len - length_B -1);
|
||||||
|
hfal_hash_mem(p->hf, db, label->label, label->length_b);
|
||||||
|
db[db_len - length_B - 1] = 0x01;
|
||||||
|
memcpy(db+db_len - length_B, src, length_B);
|
||||||
|
if(seed){
|
||||||
|
memcpy(seed_buffer, seed, hv_len);
|
||||||
|
}else{
|
||||||
|
/* generate random seed */
|
||||||
|
if(!prng_get_byte){
|
||||||
|
return 2; /* ERROR: no random generator specified */
|
||||||
|
}
|
||||||
|
uint16_t i;
|
||||||
|
for(i=0; i<hv_len; ++i){
|
||||||
|
seed_buffer[i] = prng_get_byte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\n msg (raw, pre-feistel):\r\n");
|
||||||
|
cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||||
|
#endif
|
||||||
|
p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter);
|
||||||
|
memxor(db, maskbuffer, db_len);
|
||||||
|
p->mgf(maskbuffer, db, db_len, hv_len, p->mgf_parameter);
|
||||||
|
memxor(seed_buffer, maskbuffer, hv_len);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\n msg (raw, post-feistel):\r\n");
|
||||||
|
cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||||
|
#endif
|
||||||
|
x.info = 0;
|
||||||
|
x.length_B = key->modulus->length_B;
|
||||||
|
x.wordv = dest;
|
||||||
|
bigint_adjust(&x);
|
||||||
|
rsa_os2ip(&x, NULL, bigint_length_B(key->modulus));
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\ninput-msg (pre enc):\r\n");
|
||||||
|
cli_hexdump_rev(&src, 2);
|
||||||
|
cli_hexdump_block(src, length_B, 4, 16);
|
||||||
|
#endif
|
||||||
|
rsa_enc(&x, key);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr("\r\ninput-msg (post enc):\r\n");
|
||||||
|
cli_hexdump_rev(&src, 2);
|
||||||
|
cli_hexdump_block(src, length_B, 4, 16);
|
||||||
|
#endif
|
||||||
|
rsa_i2osp(NULL, &x, out_length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length,
|
||||||
|
const void* src, uint16_t length_B,
|
||||||
|
rsa_privatekey_t* key, const rsa_oaep_parameter_t *p,
|
||||||
|
const rsa_label_t* label, void* seed){
|
||||||
|
|
||||||
|
// cli_putstr("\r\n -->rsa_decrypt_oaep()"); uart_flush(0);
|
||||||
|
if(!label){
|
||||||
|
label = &rsa_oaep_default_label;
|
||||||
|
}
|
||||||
|
if(!p){
|
||||||
|
p = &rsa_oaep_default_parameter;
|
||||||
|
}
|
||||||
|
uint16_t x_len, data_len;
|
||||||
|
bigint_t x;
|
||||||
|
uint16_t hv_len = hfal_hash_getHashsize(p->hf)/8;
|
||||||
|
uint8_t label_hv[hv_len];
|
||||||
|
uint16_t msg_len = bigint_get_first_set_bit(key->modulus) / 8 + 1;
|
||||||
|
uint16_t db_len = msg_len - hv_len - 1;
|
||||||
|
uint8_t maskbuffer[db_len>hv_len?db_len:hv_len];
|
||||||
|
|
||||||
|
uint8_t *seed_buffer = dest;
|
||||||
|
uint8_t *db_buffer = seed_buffer + hv_len;
|
||||||
|
|
||||||
|
x_len = bigint_get_first_set_bit(key->modulus)/8;
|
||||||
|
memset(dest, 0, bigint_length_B(key->modulus) - length_B);
|
||||||
|
memcpy((uint8_t*)dest + bigint_length_B(key->modulus) - length_B, src, length_B);
|
||||||
|
|
||||||
|
// cli_putc('a'); uart_flush(0);
|
||||||
|
|
||||||
|
x.wordv = dest;
|
||||||
|
x.length_B = key->modulus->length_B;
|
||||||
|
x.info = 0;
|
||||||
|
bigint_adjust(&x);
|
||||||
|
|
||||||
|
|
||||||
|
// cli_putc('b'); uart_flush(0);
|
||||||
|
rsa_os2ip(&x, NULL, bigint_length_B(key->modulus));
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR("\r\n rsa decrypting ..."));
|
||||||
|
#endif
|
||||||
|
rsa_dec(&x, key);
|
||||||
|
#if DEBUG
|
||||||
|
cli_putstr_P(PSTR(" [done]"));
|
||||||
|
#endif
|
||||||
|
rsa_i2osp(NULL, &x, &data_len);
|
||||||
|
|
||||||
|
// cli_putstr("\r\n msg (raw, pre-move):\r\n");
|
||||||
|
// cli_hexdump_block(dest, bigint_length_B(key->modulus), 4, 16);
|
||||||
|
|
||||||
|
if(data_len > x_len){
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
cli_putstr("\r\n moving some bytes; x_len = ");
|
||||||
|
cli_hexdump_rev(&x_len, 2);
|
||||||
|
cli_putstr(" data_len = ");
|
||||||
|
cli_hexdump_rev(&data_len, 2);
|
||||||
|
uart_flush(0);
|
||||||
|
*/
|
||||||
|
if(x_len != data_len){
|
||||||
|
memmove((uint8_t*)dest + x_len - data_len, dest, data_len);
|
||||||
|
// cli_putstr(" (oh, not dead yet?!)");
|
||||||
|
// uart_flush(0);
|
||||||
|
memset(dest, 0, x_len - data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
hfal_hash_mem(p->hf, label_hv, label->label, label->length_b);
|
||||||
|
/*
|
||||||
|
cli_putstr("\r\n msg (raw, pre-feistel):\r\n");
|
||||||
|
cli_hexdump_block(seed_buffer, bigint_length_B(key->modulus), 4, 16);
|
||||||
|
uart_flush(0);
|
||||||
|
*/
|
||||||
|
p->mgf(maskbuffer, db_buffer, db_len, hv_len, p->mgf_parameter);
|
||||||
|
memxor(seed_buffer, maskbuffer, hv_len);
|
||||||
|
p->mgf(maskbuffer, seed_buffer, hv_len, db_len, p->mgf_parameter);
|
||||||
|
memxor(db_buffer, maskbuffer, db_len);
|
||||||
|
|
||||||
|
if(memcmp(label_hv, db_buffer, hv_len)){
|
||||||
|
// cli_putstr("\r\nDBG: DB:\r\n");
|
||||||
|
// cli_hexdump_block(db_buffer, db_len, 4, 16);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ps_len=0;
|
||||||
|
while(db_buffer[hv_len + ps_len++] == 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
--ps_len;
|
||||||
|
if(db_buffer[hv_len + ps_len] != 1){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(seed){
|
||||||
|
memcpy(seed, seed_buffer, hv_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_len = db_len - hv_len - 1 - ps_len;
|
||||||
|
memmove(dest, db_buffer + hv_len + ps_len + 1, msg_len);
|
||||||
|
|
||||||
|
*out_length = msg_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* rsa_oaep.h */
|
||||||
|
/*
|
||||||
|
This file is part of the AVR-Crypto-Lib.
|
||||||
|
Copyright (C) 2012 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 RSA_OAEP_H_
|
||||||
|
#define RSA_OAEP_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mgf1.h"
|
||||||
|
|
||||||
|
|
||||||
|
void mgf1(void* dest, const void* seed, uint16_t seed_len_B, uint16_t out_length_B, const mgf1_parameter_t* p);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*mgf)(void* dst, const void* seed, uint16_t slen_B, uint16_t dstlen_B, const mgf1_parameter_t* p);
|
||||||
|
const hfdesc_t* hf;
|
||||||
|
mgf1_parameter_t* mgf_parameter;
|
||||||
|
} rsa_oaep_parameter_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t length_b;
|
||||||
|
const void* label;
|
||||||
|
} rsa_label_t;
|
||||||
|
|
||||||
|
extern rsa_oaep_parameter_t rsa_oaep_default_parameter;
|
||||||
|
extern rsa_label_t rsa_oaep_default_label;
|
||||||
|
|
||||||
|
uint8_t rsa_encrypt_oaep(void* dest, uint16_t* out_length,
|
||||||
|
const void* src, uint16_t length_B,
|
||||||
|
rsa_publickey_t* key, const rsa_oaep_parameter_t *p,
|
||||||
|
const rsa_label_t* label, const void* seed);
|
||||||
|
|
||||||
|
uint8_t rsa_decrypt_oaep(void* dest, uint16_t* out_length,
|
||||||
|
const void* src, uint16_t length_B,
|
||||||
|
rsa_privatekey_t* key, const rsa_oaep_parameter_t *p,
|
||||||
|
const rsa_label_t* label, void* seed);
|
||||||
|
|
||||||
|
#endif /* RSA_OAEP_H_ */
|
|
@ -80,33 +80,40 @@ const uint8_t skipjack_ftable[] PROGMEM ={
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
|
uint16_t skipjack_sub_g(uint8_t g, uint8_t k, uint8_t *key){
|
||||||
|
return pgm_read_byte(&(skipjack_ftable[g ^ key[9 - k % 10]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
|
uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
|
||||||
#define G1 (((uint8_t*)&g)[1])
|
#define G1 (((uint8_t*)&g)[1])
|
||||||
#define G2 (((uint8_t*)&g)[0])
|
#define G2 (((uint8_t*)&g)[0])
|
||||||
/* this could also be rolled up */
|
/* this could also be rolled up */
|
||||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
|
k *= 4;
|
||||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
|
G1 ^= skipjack_sub_g(G2, k + 0, key);
|
||||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
|
G2 ^= skipjack_sub_g(G1, k + 1, key);
|
||||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
|
G1 ^= skipjack_sub_g(G2, k + 2, key);
|
||||||
|
G2 ^= skipjack_sub_g(G1, k + 3, key);
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
|
uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
|
||||||
// #define G1 (((uint8_t)&g)[1])
|
// #define G1 (((uint8_t)&g)[1])
|
||||||
// #define G2 (((uint8_t)&g)[0])
|
// #define G2 (((uint8_t)&g)[0])
|
||||||
/* this could also be rolled up */
|
/* this could also be rolled up */
|
||||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
|
k *= 4;
|
||||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
|
G2 ^= skipjack_sub_g(G1, k + 3, key);
|
||||||
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
|
G1 ^= skipjack_sub_g(G2, k + 2, key);
|
||||||
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
|
G2 ^= skipjack_sub_g(G1, k + 1, key);
|
||||||
return g;
|
G1 ^= skipjack_sub_g(G2, k + 0, key);
|
||||||
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
|
void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
t = w[0];
|
t = w[0];
|
||||||
|
@ -117,7 +124,7 @@ void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
t = w[3] ^ w[2];
|
t = w[3] ^ w[2];
|
||||||
|
@ -128,7 +135,7 @@ void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
|
void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
t = w[3];
|
t = w[3];
|
||||||
|
@ -139,7 +146,7 @@ void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static
|
||||||
void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
t = w[1];
|
t = w[1];
|
||||||
|
|
|
@ -182,7 +182,7 @@ cli_hexdump_block:
|
||||||
brne 7f
|
brne 7f
|
||||||
cp WIDTH, LENG_0
|
cp WIDTH, LENG_0
|
||||||
breq 6f
|
breq 6f
|
||||||
brmi 7f
|
brcs 7f
|
||||||
mov r22, LENG_0
|
mov r22, LENG_0
|
||||||
6: inc r4
|
6: inc r4
|
||||||
7:
|
7:
|
||||||
|
@ -190,7 +190,7 @@ cli_hexdump_block:
|
||||||
add DATA_0, WIDTH
|
add DATA_0, WIDTH
|
||||||
adc DATA_1, r1
|
adc DATA_1, r1
|
||||||
sub LENG_0, WIDTH
|
sub LENG_0, WIDTH
|
||||||
sbc LENG_0, r1
|
sbc LENG_1, r1
|
||||||
tst r4
|
tst r4
|
||||||
breq 2b
|
breq 2b
|
||||||
pop r4
|
pop r4
|
||||||
|
|
|
@ -0,0 +1,810 @@
|
||||||
|
/* main-dsa-test.c */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2010 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/>.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* RSA test-suit
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "main-test-common.h"
|
||||||
|
|
||||||
|
#include "noekeon.h"
|
||||||
|
#include "noekeon_prng.h"
|
||||||
|
#include "bigint.h"
|
||||||
|
#include "bigint_io.h"
|
||||||
|
#include "random_dummy.h"
|
||||||
|
#include "rsa_basic.h"
|
||||||
|
#include "rsa_oaep.h"
|
||||||
|
|
||||||
|
#include "performance_test.h"
|
||||||
|
|
||||||
|
const char* algo_name = "RSA-OAEP";
|
||||||
|
|
||||||
|
#define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t))
|
||||||
|
#define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t))
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* additional validation-functions *
|
||||||
|
*****************************************************************************/
|
||||||
|
#if 0
|
||||||
|
/* ==================================
|
||||||
|
* Example 1: A 1024-bit RSA Key Pair
|
||||||
|
* ================================== */
|
||||||
|
|
||||||
|
/* ------------------------------
|
||||||
|
* Components of the RSA Key Pair
|
||||||
|
* ------------------------------ */
|
||||||
|
|
||||||
|
/* RSA modulus n: */
|
||||||
|
const uint8_t modulus[] = {
|
||||||
|
0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
|
||||||
|
0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
|
||||||
|
0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
|
||||||
|
0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
|
||||||
|
0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
|
||||||
|
0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
|
||||||
|
0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
|
||||||
|
0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RSA public exponent e: */
|
||||||
|
const uint8_t public_exponent[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RSA private exponent d: */
|
||||||
|
const uint8_t private_exponent[] = {
|
||||||
|
0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
|
||||||
|
0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
|
||||||
|
0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
|
||||||
|
0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
|
||||||
|
0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
|
||||||
|
0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
|
||||||
|
0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
|
||||||
|
0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prime p: */
|
||||||
|
const uint8_t p[] = {
|
||||||
|
0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
|
||||||
|
0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
|
||||||
|
0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
|
||||||
|
0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prime q: */
|
||||||
|
const uint8_t q[] = {
|
||||||
|
0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
|
||||||
|
0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
|
||||||
|
0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
|
||||||
|
0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
|
||||||
|
};
|
||||||
|
|
||||||
|
/* p's CRT exponent dP: */
|
||||||
|
const uint8_t dp[] = {
|
||||||
|
0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
|
||||||
|
0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
|
||||||
|
0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
|
||||||
|
0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* q's CRT exponent dQ: */
|
||||||
|
const uint8_t dq[] = {
|
||||||
|
0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
|
||||||
|
0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
|
||||||
|
0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
|
||||||
|
0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
|
||||||
|
};
|
||||||
|
|
||||||
|
/* CRT coefficient qInv: */
|
||||||
|
const uint8_t qinv[] = {
|
||||||
|
0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
|
||||||
|
0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
|
||||||
|
0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
|
||||||
|
0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------
|
||||||
|
* RSAES-OAEP Encryption Example 1.1
|
||||||
|
* --------------------------------- */
|
||||||
|
|
||||||
|
/* Message to be, encrypted: */
|
||||||
|
const uint8_t message[] = {
|
||||||
|
0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
|
||||||
|
0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Seed: */
|
||||||
|
const uint8_t seed[] = {
|
||||||
|
0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1,
|
||||||
|
0xdd, 0xa0, 0xa5, 0xef
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Encryption: */
|
||||||
|
const uint8_t encrypted[] = {
|
||||||
|
0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f,
|
||||||
|
0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb,
|
||||||
|
0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01,
|
||||||
|
0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f,
|
||||||
|
0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22,
|
||||||
|
0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26,
|
||||||
|
0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c,
|
||||||
|
0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Message to be encrypted: */
|
||||||
|
const uint8_t message2[] = {
|
||||||
|
0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9,
|
||||||
|
0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Seed: */
|
||||||
|
const uint8_t seed2[] = {
|
||||||
|
0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25,
|
||||||
|
0xfe, 0x4f, 0xe3, 0x5f
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Encryption: */
|
||||||
|
const uint8_t encrypted2[] = {
|
||||||
|
0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf,
|
||||||
|
0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11,
|
||||||
|
0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f,
|
||||||
|
0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52,
|
||||||
|
0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52,
|
||||||
|
0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b,
|
||||||
|
0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1,
|
||||||
|
0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44
|
||||||
|
};
|
||||||
|
|
||||||
|
/**********************************************************************************************/
|
||||||
|
/* ---------------------------------
|
||||||
|
* RSAES-OAEP Encryption Example 2.1
|
||||||
|
* --------------------------------- */
|
||||||
|
|
||||||
|
/* Message to be encrypted: */
|
||||||
|
const uint8_t message3[] = {
|
||||||
|
0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6,
|
||||||
|
0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Seed: */
|
||||||
|
const uint8_t seed3[] = {
|
||||||
|
0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94,
|
||||||
|
0xe7, 0x1b, 0x17, 0x82
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Encryption: */
|
||||||
|
const uint8_t encrypted3[] = {
|
||||||
|
0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99,
|
||||||
|
0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a,
|
||||||
|
0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a,
|
||||||
|
0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34,
|
||||||
|
0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d,
|
||||||
|
0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a,
|
||||||
|
0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f,
|
||||||
|
0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72,
|
||||||
|
0x0e
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
/**********************************************************************************************/
|
||||||
|
|
||||||
|
/* ---------------------------------
|
||||||
|
* RSAES-OAEP Encryption Example 2.4
|
||||||
|
* --------------------------------- */
|
||||||
|
|
||||||
|
/* Message to be encrypted: */
|
||||||
|
const uint8_t message4[] PROGMEM = {
|
||||||
|
0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f,
|
||||||
|
0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21,
|
||||||
|
0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c,
|
||||||
|
0x15, 0x3a, 0x10, 0xf0, 0x0a
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Seed: */
|
||||||
|
const uint8_t seed4[] PROGMEM = {
|
||||||
|
0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3,
|
||||||
|
0x80, 0x5a, 0x81, 0x56
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Encryption: */
|
||||||
|
const uint8_t encrypted4[] PROGMEM = {
|
||||||
|
/* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57,
|
||||||
|
0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c,
|
||||||
|
0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca,
|
||||||
|
0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b,
|
||||||
|
0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8,
|
||||||
|
0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76,
|
||||||
|
0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde,
|
||||||
|
0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76,
|
||||||
|
0x41
|
||||||
|
};
|
||||||
|
|
||||||
|
/**********************************************************************************************/
|
||||||
|
#if 1
|
||||||
|
/* RSA modulus n: */
|
||||||
|
const uint8_t modulus2[] PROGMEM = {
|
||||||
|
0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5,
|
||||||
|
0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e,
|
||||||
|
0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba,
|
||||||
|
0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d,
|
||||||
|
0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d,
|
||||||
|
0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05,
|
||||||
|
0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66,
|
||||||
|
0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f,
|
||||||
|
0x45
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RSA public exponent e: */
|
||||||
|
const uint8_t public_exponent2[] PROGMEM = {
|
||||||
|
0x01, 0x00, 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RSA private exponent d: */
|
||||||
|
const uint8_t private_exponent2[] PROGMEM = {
|
||||||
|
0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa,
|
||||||
|
0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93,
|
||||||
|
0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47,
|
||||||
|
0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc,
|
||||||
|
0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0,
|
||||||
|
0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59,
|
||||||
|
0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25,
|
||||||
|
0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prime p: */
|
||||||
|
const uint8_t p2[] PROGMEM = {
|
||||||
|
0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d,
|
||||||
|
0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0,
|
||||||
|
0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37,
|
||||||
|
0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a,
|
||||||
|
0x43
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prime q: */
|
||||||
|
const uint8_t q2[] PROGMEM = {
|
||||||
|
0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a,
|
||||||
|
0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4,
|
||||||
|
0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b,
|
||||||
|
0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b,
|
||||||
|
0xd7
|
||||||
|
};
|
||||||
|
|
||||||
|
/* p's CRT exponent dP: */
|
||||||
|
const uint8_t dp2[] PROGMEM = {
|
||||||
|
0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c,
|
||||||
|
0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f,
|
||||||
|
0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30,
|
||||||
|
0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55
|
||||||
|
};
|
||||||
|
|
||||||
|
/* q's CRT exponent dQ: */
|
||||||
|
const uint8_t dq2[] PROGMEM = {
|
||||||
|
0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c,
|
||||||
|
0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b,
|
||||||
|
0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91,
|
||||||
|
0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66,
|
||||||
|
0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
/* CRT coefficient qInv: */
|
||||||
|
const uint8_t qinv2[] PROGMEM = {
|
||||||
|
0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73,
|
||||||
|
0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b,
|
||||||
|
0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15,
|
||||||
|
0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/**********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t keys_allocated = 0;
|
||||||
|
rsa_publickey_t pub_key;
|
||||||
|
rsa_privatekey_t priv_key;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define MSG message
|
||||||
|
#define SEED seed
|
||||||
|
#define ENCRYPTED encrypted
|
||||||
|
#define MODULUS modulus
|
||||||
|
#define PUB_EXPONENT public_exponent
|
||||||
|
#define PRIV_EXPONENT private_exponent
|
||||||
|
#define P p
|
||||||
|
#define Q q
|
||||||
|
#define DP dp
|
||||||
|
#define DQ dq
|
||||||
|
#define QINV qinv
|
||||||
|
#else
|
||||||
|
#define MSG message4
|
||||||
|
#define SEED seed4
|
||||||
|
#define ENCRYPTED encrypted4
|
||||||
|
#define MODULUS modulus2
|
||||||
|
#define PUB_EXPONENT public_exponent2
|
||||||
|
#define PRIV_EXPONENT private_exponent2
|
||||||
|
#define P p2
|
||||||
|
#define Q q2
|
||||||
|
#define DP dp2
|
||||||
|
#define DQ dq2
|
||||||
|
#define QINV qinv2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t convert_nibble(uint8_t c){
|
||||||
|
if(c>='0' && c<='9'){
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
c |= 'A' ^ 'a';
|
||||||
|
if(c>='a' && c<='f'){
|
||||||
|
return c - 'a' + 10;
|
||||||
|
}
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *block_ignore_string=" \t\r\n,;";
|
||||||
|
#define BUFFER_LIMIT 120
|
||||||
|
uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
|
||||||
|
uint16_t counter = 0;
|
||||||
|
uint16_t c;
|
||||||
|
uint8_t v, tmp = 0, idx = 0;
|
||||||
|
if(!ignore_string){
|
||||||
|
ignore_string = block_ignore_string;
|
||||||
|
}
|
||||||
|
while(counter < length){
|
||||||
|
c = cli_getc();
|
||||||
|
if(c > 0xff){
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
if(strchr(ignore_string, c)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
v = convert_nibble(c);
|
||||||
|
if(v > 0x0f){
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
if(idx){
|
||||||
|
((uint8_t*)dst)[counter++] = (tmp << 4) | v;
|
||||||
|
idx = 0;
|
||||||
|
if(counter % (BUFFER_LIMIT/2) == 0){
|
||||||
|
cli_putc('.');
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
tmp = v;
|
||||||
|
idx = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t own_atou(const char* str){
|
||||||
|
uint16_t r=0;
|
||||||
|
while(*str && *str >= '0' && *str <= '9'){
|
||||||
|
r *= 10;
|
||||||
|
r += *str++ - '0';
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t read_bigint(bigint_t* a, char* prompt){
|
||||||
|
uint16_t read_length, actual_length;
|
||||||
|
uint8_t off;
|
||||||
|
uint8_t *buffer;
|
||||||
|
char read_int_str[18];
|
||||||
|
cli_putstr(prompt);
|
||||||
|
cli_putstr_P(PSTR("\r\n length: "));
|
||||||
|
cli_getsn(read_int_str, 16);
|
||||||
|
read_length = own_atou(read_int_str);
|
||||||
|
off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
|
||||||
|
buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
|
||||||
|
if(!buffer){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
cli_putstr_P(PSTR("\r\n data: "));
|
||||||
|
memset(buffer, 0, sizeof(bigint_word_t));
|
||||||
|
actual_length = read_os(buffer + off, read_length, NULL);
|
||||||
|
if(actual_length != read_length){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
a->wordv = (bigint_word_t*)buffer;
|
||||||
|
a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||||
|
bigint_changeendianess(a);
|
||||||
|
bigint_adjust(a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pre_alloc_key_crt(void){
|
||||||
|
uint8_t c;
|
||||||
|
pub_key.modulus = malloc(sizeof(bigint_t));
|
||||||
|
if(!pub_key.modulus){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
priv_key.modulus = pub_key.modulus;
|
||||||
|
priv_key.n = 5;
|
||||||
|
priv_key.components = malloc(5 * sizeof(bigint_t*));
|
||||||
|
if(!priv_key.components){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
pub_key.exponent = malloc(sizeof(bigint_t));
|
||||||
|
if(!pub_key.exponent){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
for(c=0; c<5; ++c){
|
||||||
|
priv_key.components[c] = malloc(sizeof(bigint_t));
|
||||||
|
if(!priv_key.components[c]){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_key(void){
|
||||||
|
uint8_t c;
|
||||||
|
free(pub_key.modulus->wordv);
|
||||||
|
free(pub_key.exponent->wordv);
|
||||||
|
free(pub_key.modulus);
|
||||||
|
pub_key.modulus = priv_key.modulus = NULL;
|
||||||
|
free(pub_key.exponent);
|
||||||
|
pub_key.exponent = NULL;
|
||||||
|
for(c = 0; c < priv_key.n; ++c){
|
||||||
|
free(priv_key.components[c]->wordv);
|
||||||
|
free(priv_key.components[c]);
|
||||||
|
}
|
||||||
|
free(priv_key.components);
|
||||||
|
priv_key.components = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t read_key_crt(void){
|
||||||
|
uint8_t r;
|
||||||
|
cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
|
||||||
|
r = pre_alloc_key_crt();
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(pub_key.modulus,"\r\n = module =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t read_key_conv(void){
|
||||||
|
uint8_t r;
|
||||||
|
cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
|
||||||
|
pub_key.modulus = malloc(sizeof(bigint_t));
|
||||||
|
if(!pub_key.modulus){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
r = read_bigint(pub_key.modulus,"\r\n = module =");
|
||||||
|
if(r) return r;
|
||||||
|
priv_key.modulus = pub_key.modulus;
|
||||||
|
priv_key.n = 1;
|
||||||
|
pub_key.exponent = malloc(sizeof(bigint_t));
|
||||||
|
if(!pub_key.exponent){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
priv_key.components = malloc(sizeof(bigint_t*));
|
||||||
|
if(!priv_key.components){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
priv_key.components[0] = malloc(sizeof(bigint_t));
|
||||||
|
if(!priv_key.components[0]){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
|
||||||
|
if(r) return r;
|
||||||
|
r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_priv_conventional(void){
|
||||||
|
bigint_t *epriv;
|
||||||
|
epriv = malloc(sizeof(bigint_t));
|
||||||
|
if(!epriv){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||||
|
epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
|
||||||
|
if(!epriv->wordv){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
|
||||||
|
priv_key.components = malloc(sizeof(bigint_t*));
|
||||||
|
priv_key.components[0] = epriv;
|
||||||
|
priv_key.n = 1;
|
||||||
|
bigint_changeendianess(epriv);
|
||||||
|
bigint_adjust(epriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void load_priv_crt_mono(void){
|
||||||
|
bigint_t **v;
|
||||||
|
const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
|
||||||
|
uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
|
||||||
|
uint8_t i;
|
||||||
|
v = malloc(5 * sizeof(bigint_t));
|
||||||
|
if(!v){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
priv_key.components = malloc(5*sizeof(bigint_t*));
|
||||||
|
if(!priv_key.components){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
priv_key.n = 5;
|
||||||
|
for(i=0; i<5; ++i){
|
||||||
|
v[i] = malloc(sizeof(bigint_t));
|
||||||
|
v[i]->info = 0;
|
||||||
|
v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
|
||||||
|
v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
|
||||||
|
if(!v[i]->wordv){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(v[i]->wordv, bv[i], sv[i]);
|
||||||
|
bigint_changeendianess(v[i]);
|
||||||
|
bigint_adjust(v[i]);
|
||||||
|
priv_key.components[i] = v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
|
||||||
|
a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
|
||||||
|
a->wordv = malloc(BIGINT_CEIL(length_B));
|
||||||
|
if(!a->wordv){
|
||||||
|
cli_putstr_P(PSTR("\r\nOOM!\r\n"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memset(a->wordv, 0, sizeof(bigint_word_t));
|
||||||
|
memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
|
||||||
|
a->info = 0;
|
||||||
|
bigint_changeendianess(a);
|
||||||
|
bigint_adjust(a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_fix_rsa(void){
|
||||||
|
if(keys_allocated){
|
||||||
|
free_key();
|
||||||
|
}
|
||||||
|
keys_allocated = 1;
|
||||||
|
|
||||||
|
if(pre_alloc_key_crt()){
|
||||||
|
cli_putstr_P(PSTR("\r\nOOM!\r\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
|
||||||
|
load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
|
||||||
|
priv_key.n = 5;
|
||||||
|
load_bigint_from_os(priv_key.components[0], P, sizeof(P));
|
||||||
|
load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
|
||||||
|
load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
|
||||||
|
load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
|
||||||
|
load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
|
||||||
|
|
||||||
|
// load_priv_conventional();
|
||||||
|
// load_priv_crt_mono();
|
||||||
|
}
|
||||||
|
|
||||||
|
void quick_test(void){
|
||||||
|
uint8_t *ciphertext, *plaintext, rc;
|
||||||
|
uint8_t seed[sizeof(SEED)];
|
||||||
|
uint16_t clen, plen;
|
||||||
|
ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
|
||||||
|
plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
|
||||||
|
memcpy_P(plaintext, MSG, sizeof(MSG));
|
||||||
|
memcpy_P(seed, SEED, sizeof(SEED));
|
||||||
|
cli_putstr_P(PSTR("\r\nplaintext:"));
|
||||||
|
cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
|
||||||
|
cli_putstr_P(PSTR("\r\nencrypting: ..."));
|
||||||
|
rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
|
||||||
|
if(rc){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
|
||||||
|
cli_hexdump_byte(rc);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
|
||||||
|
cli_hexdump_block(ciphertext, clen, 4, 8);
|
||||||
|
if(clen!=sizeof(ENCRYPTED)){
|
||||||
|
cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
|
||||||
|
}else{
|
||||||
|
if(memcmp_P(ciphertext, ENCRYPTED, clen)){
|
||||||
|
cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
|
||||||
|
}else{
|
||||||
|
cli_putstr_P(PSTR("\r\n>>OK<<"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_putstr_P(PSTR("\r\ndecrypting: ..."));
|
||||||
|
rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
|
||||||
|
if(rc){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
|
||||||
|
cli_hexdump_byte(rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
|
||||||
|
cli_hexdump_block(plaintext, plen, 4, 8);
|
||||||
|
|
||||||
|
free(ciphertext);
|
||||||
|
free(plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_seed_test(void){
|
||||||
|
uint8_t *msg, *ciph, *msg_;
|
||||||
|
uint16_t msg_len, ciph_len, msg_len_;
|
||||||
|
uint8_t seed[20], seed_out[20];
|
||||||
|
char read_int_str[18];
|
||||||
|
cli_putstr_P(PSTR("\r\n== test with given seed =="));
|
||||||
|
cli_putstr_P(PSTR("\r\n = message ="));
|
||||||
|
cli_putstr_P(PSTR("\r\n length: "));
|
||||||
|
cli_getsn(read_int_str, 16);
|
||||||
|
msg_len = own_atou(read_int_str);
|
||||||
|
msg = malloc(msg_len);
|
||||||
|
if(!msg){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ciph = malloc(bigint_length_B(pub_key.modulus));
|
||||||
|
if(!ciph){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg_ = malloc(bigint_length_B(pub_key.modulus));
|
||||||
|
if(!msg_){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: OOM!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cli_putstr_P(PSTR("\r\n data: "));
|
||||||
|
read_os(msg, msg_len, NULL);
|
||||||
|
cli_putstr_P(PSTR("\r\n seed (20 bytes): "));
|
||||||
|
read_os(seed, 20, NULL);
|
||||||
|
|
||||||
|
cli_putstr_P(PSTR("\r\n encrypting ..."));
|
||||||
|
rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
|
||||||
|
cli_putstr_P(PSTR("\r\n ciphertext:"));
|
||||||
|
cli_hexdump_block(ciph, ciph_len, 4, 16);
|
||||||
|
cli_putstr_P(PSTR("\r\n decrypting ... "));
|
||||||
|
rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
|
||||||
|
cli_putstr_P(PSTR("[done]"));
|
||||||
|
if(msg_len != msg_len_){
|
||||||
|
char tstr[16];
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
|
||||||
|
itoa(msg_len_, tstr, 10);
|
||||||
|
cli_putstr(tstr);
|
||||||
|
cli_putstr_P(PSTR(" instead of "));
|
||||||
|
itoa(msg_len, tstr, 10);
|
||||||
|
cli_putstr(tstr);
|
||||||
|
cli_putc(')');
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if(memcmp(msg, msg_, msg_len)){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
|
||||||
|
cli_hexdump_block(msg_, msg_len_, 4, 16);
|
||||||
|
cli_putstr_P(PSTR("\r\nreference:"));
|
||||||
|
cli_hexdump_block(msg, msg_len, 4, 16);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(memcmp(seed, seed_out, 20)){
|
||||||
|
cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
|
||||||
|
cli_hexdump_block(seed_out, 20, 4, 16);
|
||||||
|
cli_putstr_P(PSTR("\r\nreference:"));
|
||||||
|
cli_hexdump_block(seed, 20, 4, 16);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
cli_putstr_P(PSTR("\r\n >>OK<<"));
|
||||||
|
end:
|
||||||
|
free(msg);
|
||||||
|
free(msg_);
|
||||||
|
free(ciph);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_prng(void){
|
||||||
|
uint8_t buf[16];
|
||||||
|
memset(buf, 0, 16);
|
||||||
|
random_seed(buf);
|
||||||
|
cli_putstr_P(PSTR("\r\nPRNG reset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rsa_init(void){
|
||||||
|
prng_get_byte = random8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_key(void){
|
||||||
|
if(keys_allocated){
|
||||||
|
free_key();
|
||||||
|
}
|
||||||
|
keys_allocated = 1;
|
||||||
|
read_key_crt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dump(void){
|
||||||
|
char lstr[16];
|
||||||
|
int len;
|
||||||
|
cli_putstr_P(PSTR("\r\nenter dump length: "));
|
||||||
|
cli_getsn_cecho(lstr, 15);
|
||||||
|
len = own_atou(lstr);
|
||||||
|
cli_putstr_P(PSTR("\r\ndumping 0x"));
|
||||||
|
cli_hexdump_rev(&len, 2);
|
||||||
|
cli_putstr_P(PSTR(" byte:"));
|
||||||
|
cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* main *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const char echo_test_str[] PROGMEM = "echo-test";
|
||||||
|
const char reset_prng_str[] PROGMEM = "reset-prng";
|
||||||
|
const char load_key_str[] PROGMEM = "load-key";
|
||||||
|
const char load_fix_key_str[] PROGMEM = "load-fix-key";
|
||||||
|
const char quick_test_str[] PROGMEM = "quick-test";
|
||||||
|
const char seed_test_str[] PROGMEM = "seed-test";
|
||||||
|
const char dump_test_str[] PROGMEM = "dump-test";
|
||||||
|
const char performance_str[] PROGMEM = "performance";
|
||||||
|
const char echo_str[] PROGMEM = "echo";
|
||||||
|
|
||||||
|
const cmdlist_entry_t cmdlist[] PROGMEM = {
|
||||||
|
{ reset_prng_str, NULL, reset_prng },
|
||||||
|
{ load_key_str, NULL, load_key },
|
||||||
|
{ load_fix_key_str, NULL, load_fix_rsa },
|
||||||
|
{ quick_test_str, NULL, quick_test },
|
||||||
|
{ seed_test_str, NULL, run_seed_test },
|
||||||
|
{ dump_test_str, NULL, test_dump },
|
||||||
|
// { performance_str, NULL, testrun_performance_bigint },
|
||||||
|
{ echo_str, (void*)1, (void_fpt)echo_ctrl },
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
void dump_sp(void){
|
||||||
|
uint8_t x;
|
||||||
|
uint8_t *xa = &x;
|
||||||
|
cli_putstr_P(PSTR("\r\nstack pointer: ~"));
|
||||||
|
cli_hexdump_rev(&xa, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void){
|
||||||
|
main_setup();
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
welcome_msg(algo_name);
|
||||||
|
rsa_init();
|
||||||
|
cmd_interface(cmdlist);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue