adding RSA-OAEP

This commit is contained in:
bg 2012-03-28 02:25:11 +00:00
parent f947a91725
commit 997bf1010d
25 changed files with 14310 additions and 284 deletions

25
Makefile_en21 Normal file
View File

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

14
Makefile_en21_conf.inc Normal file
View File

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

25
Makefile_m644 Normal file
View File

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

20
Makefile_m644_conf.inc Normal file
View File

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

396
Makefile_main.inc Normal file
View File

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

42
Makefile_sys_conf.inc Normal file
View File

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

View File

@ -2,6 +2,7 @@
MCU_TARGET = atmega128
F_CPU = 14745600
OPTIMIZE = -Os # -Os
EXTRALINK = xram.o
DEBUG = -gdwarf-2
WARNING = -pedantic -Wall -Werror -Wstrict-prototypes
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 = -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
SIZESTAT_FILE = sizestats.txt

View File

@ -1,6 +1,6 @@
/* 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)
This program is free software: you can redistribute it and/or modify
@ -32,10 +32,14 @@
#include "bigint.h"
#include <string.h>
/*
#define DEBUG 0
#if DEBUG
#include "cli.h"
#include "bigint_io.h"
*/
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
@ -44,14 +48,14 @@
#define MIN(a,b) (((a)<(b))?(a):(b))
#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 SET_NEG(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_PTR(a,b) do{ a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
b = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b))); \
a = (void*)(((uint16_t)(a)) ^ ((uint16_t)(b)));}while(0)
#define XCHG_PTR(a,b) do{ a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
b = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b))); \
a = (void*)(((bigint_ptr_int_t)(a)) ^ ((bigint_ptr_int_t)(b)));}while(0)
#define GET_SIGN(a) ((a)->info&BIGINT_NEG_MASK)
@ -64,10 +68,10 @@ void bigint_adjust(bigint_t* a){
a->info=0;
return;
}
uint8_t t;
uint8_t i = 0x07;
bigint_word_t t;
uint8_t i = BIGINT_WORD_SIZE-1;
t = a->wordv[a->length_B-1];
while((t&0x80)==0 && i){
while((t&(1L<<(BIGINT_WORD_SIZE-1)))==0 && i){
t<<=1;
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){
memcpy(dest->wordv, src->wordv, src->length_B*sizeof(bigint_word_t));
dest->length_B = src->length_B;
dest->info = src->info;
memcpy(dest->wordv, src->wordv, src->length_B);
}
/******************************************************************************/
/* this should be implemented in assembly */
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){
XCHG_PTR(a,b);
}
for(i=0; i<b->length_B; ++i){
t = a->wordv[i] + b->wordv[i] + t;
dest->wordv[i] = (uint8_t)t;
t>>=8;
// t = (bigint_wordplus_t)(a->wordv[i]) + (bigint_wordplus_t)(b->wordv[i]) + t;
t += a->wordv[i];
t += b->wordv[i];
dest->wordv[i] = (bigint_word_t)t;
t>>=BIGINT_WORD_SIZE;
}
for(; i<a->length_B; ++i){
t = a->wordv[i] + t;
dest->wordv[i] = (uint8_t)t;
t>>=8;
t += a->wordv[i];
dest->wordv[i] = (bigint_word_t)t;
t>>=BIGINT_WORD_SIZE;
}
dest->wordv[i++] = t;
dest->wordv[i++] = (bigint_word_t)t;
dest->length_B = i;
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 */
void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
uint16_t i,j=0;
uint16_t t=0;
if(scale>dest->length_B)
memset(dest->wordv+dest->length_B, 0, scale-dest->length_B);
for(i=scale; i<a->length_B+scale; ++i,++j){
t = a->wordv[j] + t;
bigint_t x;
#if BIGINT_WORD_SIZE == 8
memset(dest->wordv + dest->length_B, 0, MAX(dest->length_B, a->length_B + scale) - dest->length_B);
x.wordv = dest->wordv + scale;
x.length_B = dest->length_B - scale;
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){
t += dest->wordv[i];
t += dst[i];
}
dest->wordv[i] = (uint8_t)t;
t>>=8;
dst[i] = (bigint_word_t)t;
t>>=BIGINT_WORD_SIZE;
}
while(t){
if(dest->length_B>i){
t = dest->wordv[i] + t;
t += dst[i];
}
dest->wordv[i] = (uint8_t)t;
t>>=8;
dst[i] = (bigint_word_t)t;
t>>=BIGINT_WORD_SIZE;
++i;
}
if(dest->length_B < i){
dest->length_B = i;
}
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){
int8_t borrow=0;
int8_t r;
int16_t t;
bigint_wordplus_signed_t t=0LL;
uint16_t i, min, max;
min = MIN(a->length_B, b->length_B);
max = MAX(a->length_B, b->length_B);
r = bigint_cmp_u(a,b);
if(r==0){
dest->length_B = 0;
dest->wordv[0] = 0;
bigint_adjust(dest);
bigint_set_zero(dest);
return;
}
if(b->length_B==0){
dest->length_B = a->length_B;
memcpy(dest->wordv, a->wordv, a->length_B);
dest->info = a->info;
bigint_copy(dest, a);
SET_POS(dest);
return;
}
if(a->length_B==0){
dest->length_B = b->length_B;
memcpy(dest->wordv, b->wordv, b->length_B);
dest->info = b->info;
SET_NEG(dest);
return;
bigint_copy(dest, b);
SET_NEG(dest);
return;
}
if(r<0){
bigint_sub_u(dest, b, a);
SET_NEG(dest);
}else{
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);
return;
}
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;
i = a->length_B-1;
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;
}else{
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){
uint16_t byteshift;
uint16_t i;
uint16_t byteshift, word_alloc;
int16_t i;
uint8_t bitshift;
uint16_t t=0;
byteshift = (shift+3)/8;
bitshift = shift&7;
memmove(a->wordv+byteshift, a->wordv, a->length_B);
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);
}
bigint_word_t *p;
bigint_wordplus_t t=0;
if(shift==0){
return;
}
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);
}
@ -344,32 +409,33 @@ void bigint_shiftright(bigint_t* a, uint16_t shift){
uint16_t byteshift;
uint16_t i;
uint8_t bitshift;
uint16_t t=0;
bigint_wordplus_t t=0;
byteshift = shift/8;
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);
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);
return;
}
if(byteshift){
memmove(a->wordv, a->wordv+byteshift, a->length_B-byteshift);
memset(a->wordv+a->length_B-byteshift, 0, byteshift);
memmove(a->wordv, (uint8_t*)a->wordv+byteshift, a->length_B-byteshift);
memset((uint8_t*)a->wordv+a->length_B-byteshift, 0, byteshift);
}
byteshift /= sizeof(bigint_word_t);
if(bitshift!=0){
/* shift to the right */
for(i=a->length_B-byteshift-1; i>0; --i){
t |= (a->wordv[i])<<(8-bitshift);
a->wordv[i] = (uint8_t)(t>>8);
t <<= 8;
t |= ((bigint_wordplus_t)(a->wordv[i]))<<(BIGINT_WORD_SIZE-bitshift);
a->wordv[i] = (bigint_word_t)(t>>BIGINT_WORD_SIZE);
t <<= BIGINT_WORD_SIZE;
}
t |= (a->wordv[0])<<(8-bitshift);
a->wordv[0] = (uint8_t)(t>>8);
t |= ((bigint_wordplus_t)(a->wordv[0]))<<(BIGINT_WORD_SIZE-bitshift);
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);
}
@ -400,7 +466,7 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){
}
if(dest==a || dest==b){
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;
bigint_mul_u(&d, a, b);
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){
XCHG_PTR(a,b);
}
uint16_t i, t=0;
uint8_t x = a->wordv[0];
for(i=0; i<b->length_B; ++i){
t += b->wordv[i]*x;
dest->wordv[i] = (uint8_t)t;
t>>=8;
bigint_wordplus_t t=0;
uint16_t i;
bigint_word_t x = a->wordv[0];
for(i=0; i < b->length_B; ++i){
t += ((bigint_wordplus_t)b->wordv[i])*((bigint_wordplus_t)x);
dest->wordv[i] = (bigint_word_t)t;
t>>=BIGINT_WORD_SIZE;
}
dest->wordv[i] = (uint8_t)t;
dest->length_B=i+1;
dest->wordv[i] = (bigint_word_t)t;
dest->length_B = i+1;
dest->info = 0;
bigint_adjust(dest);
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;
uint64_t r;
memcpy(&p, a->wordv, a->length_B);
memcpy(&q, b->wordv, b->length_B);
r = (uint64_t)p*(uint64_t)q;
memcpy(dest->wordv, &r, a->length_B+b->length_B);
dest->length_B = a->length_B+b->length_B;
memcpy(&p, a->wordv, a->length_B*sizeof(bigint_word_t));
memcpy(&q, b->wordv, b->length_B*sizeof(bigint_word_t));
r = (uint64_t)p * (uint64_t)q;
memcpy(dest->wordv, &r, (dest->length_B = a->length_B + b->length_B)*sizeof(bigint_word_t));
bigint_adjust(dest);
return;
}
bigint_set_zero(dest);
/* split a in xh & xl; split b in yh & yl */
uint16_t n;
n=(MAX(a->length_B, b->length_B)+1)/2;
const uint16_t n = (MAX(a->length_B, b->length_B)+1)/2;
bigint_t xl, xh, yl, yh;
xl.wordv = a->wordv;
yl.wordv = b->wordv;
if(a->length_B<=n){
xh.info=0;
xh.length_B = 0;
bigint_set_zero(&xh);
xl.length_B = a->length_B;
xl.info = 0;
xl.info = a->info;
}else{
xl.length_B=n;
xl.info = 0;
bigint_adjust(&xl);
xh.wordv = a->wordv+n;
xh.wordv = &(a->wordv[n]);
xh.length_B = a->length_B-n;
xh.info = 0;
xh.info = a->info;
}
if(b->length_B<=n){
yh.info=0;
yh.length_B = 0;
bigint_set_zero(&yh);
yl.length_B = b->length_B;
yl.info = b->info;
}else{
yl.length_B=n;
yl.info = 0;
bigint_adjust(&yl);
yh.wordv = b->wordv+n;
yh.wordv = &(b->wordv[n]);
yh.length_B = b->length_B-n;
yh.info = 0;
yh.info = b->info;
}
/* 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;
tmp.wordv = tmp_b;
tmp2.wordv = tmp_b+n+1;
tmp2.wordv = &(tmp_b[n+1]);
m.wordv = m_b;
bigint_mul_u(dest, &xl, &yl); /* dest <= xl*yl */
bigint_add_u(&tmp2, &xh, &xl); /* tmp2 <= xh+xl */
bigint_add_u(&tmp, &yh, &yl); /* tmp <= yh+yl */
bigint_mul_u(&m, &tmp2, &tmp); /* m <= tmp2*tmp */
bigint_mul_u(&tmp, &xh, &yh); /* h <= xh*yh */
bigint_sub_u(&m, &m, dest); /* m <= m-dest */
bigint_sub_u(&m, &m, &tmp); /* m <= m-h */
bigint_add_scale_u(dest, &m, n);
bigint_add_scale_u(dest, &tmp, 2*n);
bigint_mul_u(dest, &xl, &yl); /* 1: dest <= xl*yl */
bigint_add_u(&tmp2, &xh, &xl); /* 2: tmp2 <= xh+xl */
bigint_add_u(&tmp, &yh, &yl); /* 3: tmp <= yh+yl */
bigint_mul_u(&m, &tmp2, &tmp); /* 4: m <= tmp2*tmp */
bigint_mul_u(&tmp, &xh, &yh); /* 5: h <= xh*yh */
bigint_sub_u(&m, &m, dest); /* 6: m <= m-dest */
bigint_sub_u(&m, &m, &tmp); /* 7: m <= m-h */
bigint_add_scale_u(dest, &m, n*sizeof(bigint_word_t)); /* 8: dest <= dest+m**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 */
/* (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){
if(a->length_B<=4){
if(a->length_B*sizeof(bigint_word_t)<=4){
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;
memcpy(dest->wordv, &r, 2*a->length_B);
memcpy(dest->wordv, &r, 2*a->length_B*sizeof(bigint_word_t));
SET_POS(dest);
dest->length_B=2*a->length_B;
bigint_adjust(dest);
@ -529,7 +597,7 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
}
if(dest==a){
bigint_t d;
uint8_t d_b[a->length_B*2];
bigint_word_t d_b[a->length_B*2];
d.wordv = d_b;
bigint_square(&d, a);
bigint_copy(dest, &d);
@ -538,79 +606,115 @@ void bigint_square(bigint_t* dest, const bigint_t* a){
uint16_t n;
n=(a->length_B+1)/2;
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.length_B = n;
xh.wordv = a->wordv+n;
xl.info = 0;
xh.wordv = &(a->wordv[n]);
xh.length_B = a->length_B-n;
xh.info = 0;
bigint_adjust(&xl);
bigint_adjust(&xh);
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);
// cli_putstr("\r\nDBG (1): xl**2: "); bigint_print_hex(dest);
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);
// cli_putstr("\r\nDBG (4): xl*xh: "); bigint_print_hex(&tmp);
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){
bigint_t tmp;
uint8_t tmp_b[b->length_B+1];
uint16_t i,j,byteshift=bitscale/8;
uint8_t borrow=0;
int16_t t;
bigint_t tmp, x;
bigint_word_t tmp_b[b->length_B + 1];
const uint16_t word_shift = bitscale / BIGINT_WORD_SIZE;
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);
return;
}
tmp.wordv = 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){
t = a->wordv[i] - tmp.wordv[j] - borrow;
a->wordv[i] = (uint8_t)t;
if(t<0){
borrow = 1;
}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;
}
x.info = a->info;
x.wordv = &(a->wordv[word_shift]);
x.length_B = a->length_B - word_shift;
bigint_sub_u(&x, &x, &tmp);
bigint_adjust(a);
return;
}
/******************************************************************************/
void bigint_reduce(bigint_t* a, const bigint_t* r){
// bigint_adjust(r);
// bigint_adjust((bigint_t*)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){
return;
}
while(a->length_B > r->length_B){
bigint_sub_u_bitscale(a, r, (a->length_B-r->length_B)*8+GET_FBS(a)-rfbs-1);
if((r->length_B*sizeof(bigint_word_t)<=4) && (a->length_B*sizeof(bigint_word_t)<=4)){
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)){
bigint_sub_u_bitscale(a, r, GET_FBS(a)-rfbs-1);
uint16_t shift;
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){
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;
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;
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;
base.wordv = base_b;
bigint_copy(&base, a);
// cli_putstr("\r\npost-copy");
bigint_reduce(&base, r);
res.wordv[0]=1;
res.length_B=1;
res.info = 0;
bigint_adjust(&res);
for(i=0; i+1<exp->length_B; ++i){
t=exp->wordv[i];
for(j=0; j<8; ++j){
if(t&1){
bigint_mul_u(&res, &res, &base);
bigint_reduce(&res, r);
if(exp->length_B == 0){
bigint_copy(dest, &res);
return;
}
uint8_t flag = 0;
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);
bigint_reduce(&base, r);
t>>=1;
if(flag){
bigint_square(&res, &res);
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){
if(t&1){
bigint_mul_u(&res, &res, &base);
bigint_reduce(&res, r);
}
bigint_square(&base, &base);
bigint_reduce(&base, r);
t>>=1;
}
// cli_putc('+');
SET_POS(&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 */
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_;
volatile uint16_t i=0;
uint16_t i=0;
if(x->length_B==0 || y->length_B==0){
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){
++i;
}
uint8_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];
uint8_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 g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i];
bigint_word_t u_b[x->length_B-i], v_b[y->length_B-i];
bigint_word_t a_b[y->length_B+2], c_b[y->length_B+2];
bigint_word_t b_b[x->length_B+2], d_b[x->length_B+2];
g.wordv = g_b;
x_.wordv = x_b;
y_.wordv = y_b;
memset(g_b, 0, i);
memset(g_b, 0, i*sizeof(bigint_word_t));
g_b[i]=1;
g.length_B = i+1;
g.info=0;
x_.info = y_.info = 0;
x_.length_B = x->length_B-i;
y_.length_B = y->length_B-i;
memcpy(x_.wordv, x->wordv+i, x_.length_B);
memcpy(y_.wordv, y->wordv+i, y_.length_B);
memcpy(x_.wordv, x->wordv+i, x_.length_B*sizeof(bigint_word_t));
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){
}
@ -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(&y_, i);
}
u.wordv = u_b;
v.wordv = v_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(&c_);
do{
cli_putstr("\r\nDBG (gcdext) 0");
while((u.wordv[0]&1)==0){
cli_putstr("\r\nDBG (gcdext) 0.1");
bigint_shiftright(&u, 1);
if((a_.wordv[0]&1) || (b_.wordv[0]&1)){
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);
}
while((v.wordv[0]&1)==0){
cli_putstr("\r\nDBG (gcdext) 0.2");
bigint_shiftright(&v, 1);
if((c_.wordv[0]&1) || (d_.wordv[0]&1)){
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){
uint8_t t, *p, *q;
p = a->wordv;
q = p+a->length_B-1;
p = (uint8_t*)(a->wordv);
q = ((uint8_t*)p)+a->length_B*sizeof(bigint_word_t)-1;
while(p<q){
t = *p;
*p = *q;

View File

@ -1,6 +1,6 @@
/* 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)
This program is free software: you can redistribute it and/or modify
@ -30,18 +30,29 @@
#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 */
typedef struct{
uint16_t length_B;
uint8_t info;
uint8_t *wordv; /* word vector, pointing to the LSB */
bigint_word_t *wordv; /* word vector, pointing to the LSB */
}bigint_t;
/******************************************************************************/
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_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);

View File

@ -1,6 +1,6 @@
/* 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)
This program is free software: you can redistribute it and/or modify
@ -20,7 +20,6 @@
#include "cli.h"
#include "hexdigit_tab.h"
#include "bigint.h"
#include <avr/pgmspace.h>
#include <stdlib.h>
#include <string.h>
@ -33,15 +32,37 @@ void bigint_print_hex(const bigint_t* a){
cli_putc('-');
}
// cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */
if(a->wordv[a->length_B-1]<0x10){
cli_putc(pgm_read_byte(hexdigit_tab_uc_P+a->wordv[a->length_B-1]));
/* if(a->wordv[a->length_B-1]<0x10){
cli_putc(hexdigit_tab_uc[a->wordv[a->length_B-1]]);
cli_hexdump_rev(a->wordv, a->length_B-1);
} 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){
if(c>='0' && c <='9'){
@ -76,23 +97,24 @@ static uint16_t read_byte(void){
uint8_t bigint_read_hex_echo(bigint_t* a){
uint16_t allocated=0;
uint8_t shift4=0;
uint16_t t;
uint16_t t, idx = 0;
a->length_B = 0;
a->wordv = NULL;
a->info = 0;
for(;;){
if(allocated-a->length_B < 1){
uint8_t *p;
p = realloc(a->wordv, allocated+=BLOCKSIZE);
if(allocated - idx < 1){
bigint_word_t *p;
p = realloc(a->wordv, allocated += BLOCKSIZE);
if(p==NULL){
cli_putstr_P(PSTR("\r\nERROR: Out of memory!"));
cli_putstr("\r\nERROR: Out of memory!");
free(a->wordv);
return 0xff;
}
memset((uint8_t*)p + allocated - BLOCKSIZE, 0, BLOCKSIZE);
a->wordv=p;
}
t = read_byte();
if(a->length_B==0){
if(idx==0){
if(t&0x0400){
/* got minus */
a->info |= BIGINT_NEG_MASK;
@ -106,11 +128,11 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
}
}
if(t<=0x00ff){
a->wordv[a->length_B++] = (uint8_t)t;
((uint8_t*)(a->wordv))[idx++] = (uint8_t)t;
}else{
if(t&0x0200){
shift4 = 1;
a->wordv[a->length_B++] = (uint8_t)((t&0x0f)<<4);
((uint8_t*)(a->wordv))[idx++] = (uint8_t)((t&0x0f)<<4);
}
break;
}
@ -118,18 +140,18 @@ uint8_t bigint_read_hex_echo(bigint_t* a){
/* we have to reverse the byte array */
uint8_t tmp;
uint8_t *p, *q;
p = a->wordv;
q = a->wordv+a->length_B-1;
a->length_B = (idx + sizeof(bigint_word_t)-1)/sizeof(bigint_word_t);
p = (uint8_t*)(a->wordv);
q = (uint8_t*)a->wordv + a->length_B * sizeof(bigint_word_t) - 1;
while(q>p){
tmp = *p;
*p = *q;
*q = tmp;
p++; q--;
}
bigint_adjust(a);
if(shift4){
bigint_adjust(a);
bigint_shiftright(a, 4);
}
bigint_adjust(a);
return 0;
}

View File

@ -1,6 +1,6 @@
/* 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)
This program is free software: you can redistribute it and/or modify

View File

@ -23,7 +23,7 @@ $debug = false
require 'rubygems'
require 'serialport'
require 'getopt/std'
require 'ftools'
require 'fileutils'
require 'date'
$buffer_size = 0
$conffile_check = Hash.new
@ -37,7 +37,7 @@ def readconfigfile(fname, conf)
return conf if $conffile_check[fname]==1
$conffile_check[fname]=1
section = "default"
if not File.exists?(fname)
if ! File.exists?(fname)
return conf
end
file = File.open(fname, "r")
@ -49,7 +49,7 @@ def readconfigfile(fname, conf)
conf[m[1]] = Hash.new
next
end
next if not /=/.match(line)
next if ! /=/.match(line)
m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
if m[1]=="include"
Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
@ -158,7 +158,7 @@ def wait_for_prompt(prompt)
return false
end
acc += line
end while not m=prompt.match(acc)
end while ! m=prompt.match(acc)
return m
end
@ -187,7 +187,7 @@ def add_test(a,b)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -197,7 +197,7 @@ def add_test(a,b)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
end while ! /[\s]*enter b:[\s]*/.match(line)
$sp.print(b.to_s(16)+" ")
begin
line = $sp.gets()
@ -207,7 +207,7 @@ def add_test(a,b)
puts line
return false
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)
b_ = m[2].to_i(16)
c_ = m[3].to_i(16)
@ -236,7 +236,7 @@ def mul_test(a,b)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -246,7 +246,7 @@ def mul_test(a,b)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
end while ! /[\s]*enter b:[\s]*/.match(line)
$sp.print(b.to_s(16)+" ")
begin
line = $sp.gets()
@ -256,7 +256,7 @@ def mul_test(a,b)
puts line
return false
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)
b_ = m[2].to_i(16)
c_ = m[3].to_i(16)
@ -330,7 +330,7 @@ def square_test(a)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -340,7 +340,7 @@ def square_test(a)
puts line
return false
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)
c_ = m[2].to_i(16)
line.chomp!
@ -368,7 +368,7 @@ def reduce_test(a,b)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -378,7 +378,7 @@ def reduce_test(a,b)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
end while ! /[\s]*enter b:[\s]*/.match(line)
$sp.print(b.to_s(16)+" ")
line=''
begin
@ -390,7 +390,7 @@ def reduce_test(a,b)
puts line
return false
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)
b_ = m[2].to_i(16)
c_ = m[3].to_i(16)
@ -419,7 +419,7 @@ def expmod_test(a,b,c)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -429,7 +429,7 @@ def expmod_test(a,b,c)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
end while ! /[\s]*enter b:[\s]*/.match(line)
$sp.print(b.to_s(16)+" ")
begin
line = $sp.gets()
@ -439,7 +439,7 @@ def expmod_test(a,b,c)
puts line
return false
end
end while not /[\s]*enter c:[\s]*/.match(line)
end while ! /[\s]*enter c:[\s]*/.match(line)
$sp.print(c.to_s(16)+" ")
line=''
begin
@ -451,7 +451,7 @@ def expmod_test(a,b,c)
puts line
return false
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)
b_ = m[2].to_i(16)
c_ = m[3].to_i(16)
@ -481,7 +481,7 @@ def gcdext_test(a,b)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
end while ! /[\s]*enter a:[\s]*/.match(line)
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
@ -491,7 +491,7 @@ def gcdext_test(a,b)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
end while ! /[\s]*enter b:[\s]*/.match(line)
$sp.print(b.to_s(16)+" ")
line=''
begin
@ -504,7 +504,7 @@ def gcdext_test(a,b)
puts line
return false
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)
b_ = m[2].to_i(16)
c_ = m[3].to_i(16)
@ -834,12 +834,16 @@ if File.exists?(logfilename)
i+=1
end while(File.exists?(logfilename))
while(i>2) do
File.move(sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt'),
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt'), true)
n1 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt')
n2 = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt')
File.rename(n1, n2)
printf("%s -> %s\n", n1, n2)
i-=1
end
File.move(sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt'),
sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt'), true)
n1 = sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt')
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'
end
$logfile = File.open(logfilename, 'w')

View File

@ -1,2 +1,3 @@
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

14
mkfiles/rsa_oaep.mk Normal file
View File

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

24
rsa/random_dummy.c Normal file
View File

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

27
rsa/random_dummy.h Normal file
View File

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

161
rsa/rsa_basic.c Normal file
View File

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

48
rsa/rsa_basic.h Normal file
View File

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

247
rsa/rsa_oaep.c Normal file
View File

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

54
rsa/rsa_oaep.h Normal file
View File

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

View File

@ -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){
#define G1 (((uint8_t*)&g)[1])
#define G2 (((uint8_t*)&g)[0])
/* this could also be rolled up */
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
k *= 4;
G1 ^= skipjack_sub_g(G2, k + 0, key);
G2 ^= skipjack_sub_g(G1, k + 1, key);
G1 ^= skipjack_sub_g(G2, k + 2, key);
G2 ^= skipjack_sub_g(G1, k + 3, key);
return g;
}
/*****************************************************************************/
static
uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
// #define G1 (((uint8_t)&g)[1])
// #define G2 (((uint8_t)&g)[0])
/* this could also be rolled up */
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+3)%10]]));
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+2)%10]]));
G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[9-(4*k+1)%10]]));
G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[9-(4*k+0)%10]]));
return g;
k *= 4;
G2 ^= skipjack_sub_g(G1, k + 3, key);
G1 ^= skipjack_sub_g(G2, k + 2, key);
G2 ^= skipjack_sub_g(G1, k + 1, key);
G1 ^= skipjack_sub_g(G2, k + 0, key);
return g;
}
/*****************************************************************************/
static
void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
uint16_t t;
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){
uint16_t t;
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){
uint16_t t;
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){
uint16_t t;
t = w[1];

View File

@ -182,7 +182,7 @@ cli_hexdump_block:
brne 7f
cp WIDTH, LENG_0
breq 6f
brmi 7f
brcs 7f
mov r22, LENG_0
6: inc r4
7:
@ -190,7 +190,7 @@ cli_hexdump_block:
add DATA_0, WIDTH
adc DATA_1, r1
sub LENG_0, WIDTH
sbc LENG_0, r1
sbc LENG_1, r1
tst r4
breq 2b
pop r4

View File

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