bug fix + docu

This commit is contained in:
bg 2011-07-11 00:54:16 +00:00
parent 8fcc613257
commit 6cddae4d0f
7 changed files with 527 additions and 207 deletions

View File

@ -78,10 +78,8 @@ SRC_LEN_0 = 20
SRC_LEN_1 = 21
SCALE_0 = 18
SCALE_1 = 19
DST_CTX_0 = 6
DST_CTX_1 = 7
SRC_CTX_0 = 8
SRC_CTX_1 = 9
DST_CTX_0 = 8
DST_CTX_1 = 9
TMP_0 = 10
TMP_1 = 11
@ -89,7 +87,14 @@ bigint_add_scale_u:
movw r30, r24 /* dest ptr */
movw r26, r22 /* src ptr */
movw r24, r20 /* scale */
/* check if scale is zero */
movw SCALE_0, r24
adiw r24, 0
brne 10f
movw r24, r30
movw r20, r30
rjmp bigint_add_u
10: /* check if src is zero */
ld r24, X+
ld r25, X+
adiw r24, 0
@ -97,9 +102,8 @@ bigint_add_scale_u:
ret
10:
movw SRC_LEN_0, r24
push_range 6, 11
push_range 8, 11
movw DST_CTX_0, r30
movw SRC_CTX_0, r26
/* pad dest with zeros to length of SRC_LENGTH + scale */
adiw r26, 1
@ -126,7 +130,6 @@ bigint_add_scale_u:
rjmp 10b
11:
/* start of copy */
movw r24, SRC_LEN_0
12: /* copy loop */
@ -144,13 +147,12 @@ bigint_add_scale_u:
std Z+1, TMP_1
movw r24, r30
99:
pop_range 6, 11
pop_range 8, 11
rjmp bigint_adjust
40:
/* TODO */
/* Z points at DST_WORDV */
/* X points at SRC_WORDV */
/* r24:r25 contains scale - DST_LEN (negativ) */
/* r24:r25 and TMP contain scale - DST_LEN (negativ) */
/* set T bit if DST_LEN > SCR_LEN + scale */
clt
add r30, SCALE_0
@ -172,36 +174,24 @@ bigint_add_scale_u:
+-------+-------+ SRC + scale
+------------+ DST
*/
com r24 /* negate r24:r25 */
com r24 /* negate r24:r25 ==> DST_LEN - scale */
com r25
adiw r24, 1
breq 50f
44:
inc r25
clc
45:
dec r24
brpl 46f
dec r25
brmi 50f
46: ld TMP_0, X+
ld TMP_1, Z
adc TMP_0, TMP_1
st Z+, TMP_0
rjmp 45b
dec r24
brne 46b
dec r25
brne 46b
50:
/* do the overhaning part */
rol r1
movw r24, r30
movw r30, DST_CTX_0
ldd TMP_0, Z+3
ldd TMP_1, Z+4
movw r30, TMP_0
add r30, DST_LEN_0
adc r31, DST_LEN_1
adiw r30, 1
st Z, r1
movw r30, r24
ror r1
50: ;st Z, r1
brtc 60f
51: brcc 53f
52: ld TMP_0, Z
@ -209,34 +199,42 @@ bigint_add_scale_u:
st Z+, TMP_0
brcs 52b
53:
/* TODO */
/* epilogue */
movw r24, r30
movw r30, DST_CTX_0
ldd TMP_0, Z+3
ldd TMP_1, Z+4
sub r24, TMP_0
sbc r25, TMP_1
cp r24, DST_LEN_0
cpc r25, DST_LEN_1
brmi 54f
std Z+0, r24
std Z+1, r25
movw r24, r30
54: movw r24, r30
rjmp 99b
60: rol r1 /* backup carry */
60: st Z, r1
rol r1 /* backup carry */
movw r24, SRC_LEN_0
add r24, SCALE_0
adc r25, SCALE_1
sub r24, DST_LEN_0
sbc r25, DST_LEN_1
adiw r24, 0
breq 63f
inc r25
ror r1 /* restore carry */
61: dec r24
brpl 62f
dec r25
brmi 63f
61:
62: ld TMP_0, X+
adc TMP_0, r1
st Z+, TMP_0
rjmp 61b
dec r24
brne 62b
dec r25
brne 62b
63:
brcc 53b
ldi r24, 1

View File

@ -30,8 +30,117 @@ of documenting the structure of the API so you know what to do when you want
to use the library.
@chapter Generic stuff
@section Requirements
You should have the following software tools to build the library, the version
mentioned is the version used on the test system, older or newer versions may
or may not work):
@table @asis
@item a recent toolchain
for AVR targets:
@table @asis
@item gcc for AVR (avr-gcc)
4.3.5
@item GNU binutils for AVR
2.21
@item avr-libc
1.6.8-2
@end table
for ARM targets:
@table @asis
@item gcc for ARM (arm-elf-gcc)
@item GNU binutils for ARM
@item newlib with enabled malloc()
@end table
@item a flash tool to program your device
for AVR targets:
@table @asis
@item avrdude
5.10
@end table
for ARM targets:
@table @asis
@item openocd
0.4.0
@end table
@item GNU make
3.81
@item ruby (for the testing system)
1.8.7.302-2
@table @asis
@item rubygems
1.3.7
@item serialport
1.0.4
@item getopt
1.4.0
@end table
@end table
@section File organisation
@section Build process
The build process is managed by a large relative complex @file{Makefile} and
a bunch of more specific Makefile-stubs (@file{*.mk} in the @file{mkfiles}
directory).
@subsection make-stubs
All stubs are included by the main Makefile automatically, so the addition of
algorithms should not require modifications to the Makefile.
Because all stubs are included by the main Makefile you can use all features
of your make system when writing them. Currently we use GNU make and we
recommend using GNU make when building the crypto library.
Each algorithm implementation has its own stub. A stub looks like the following:
@verbatim
# Makefile for AES
ALGO_NAME := AES128_C
# comment out the following line for removement of AES from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
$(ALGO_NAME)_DIR := aes/
$(ALGO_NAME)_INCDIR := gf256mul/ bcal/
$(ALGO_NAME)_OBJ := aes_enc.o aes_dec.o aes_sbox.o aes_invsbox.o \
aes_keyschedule.o gf256mul.o aes128_enc.o aes128_dec.o
$(ALGO_NAME)_TEST_BIN := main-aes128-test.o $(CLI_STD) $(BCAL_STD) \
bcal_aes128.o
$(ALGO_NAME)_NESSIE_TEST := test nessie
$(ALGO_NAME)_PERFORMANCE_TEST := performance
@end verbatim
The most important thing is defining an unambiguous name for the implementation,
in this case it is AES128_C.
The next step is chaining the implementation into a category. Uncategorized
implementations will be ignored. So if you want to exclude an implementation
from the build process you can simply comment out the line which chains it into
a category.
The following lines declare ''Attributes'' of the implementation.
@table @var
@item _DIR
defines the directory where the implementation resides
@item _INCDIR
defines directorys to search for additional files
@item _OBJ
defines the names of the objects which shoud be considered the implementations
core
@item _TESTBIN
defines the names of the objects required to build the test suit
@item _NESSIE_TEST
(currently unused) defines the string which should be send to the test system
to perform nessie standard tests
@item _NESSIE_TEST
(currently unused) defines the string which should be send to the test system
to perform a performance tests
@item _DEF
defines macros to use while compiling
@end table
@section Testing system
@section Sizes in bits and bytes
Working with cryptographic functions involves working with different
@ -42,7 +151,7 @@ to use the library.
_b means in bits and _B means in bytes (big b big word) and _w meaning words.
@chapter Symmetric primitives
@include acl_keysizes.texi
@include acl_blockciphers.texi
@section Modes of operation

View File

@ -135,7 +135,7 @@ The BCAL is split up in different parts:
@item BCAL basic functions
@end itemize
@subsubsection BCAL declaration for BCAL decriptors
@subsection BCAL declaration for BCAL decriptors
The BCAL descriptor is a structure which is usually placed in FLASH or ROM since
modification is unnecessary. It contains all information required to use the
according block cipher.
@ -220,7 +220,7 @@ typedef struct {
that the chosen keysize is valid
@end table
@subsubsection BCAL-Basic context
@subsection BCAL-Basic context
Besides the context types for individual ciphers there is a generic context
type for BCAL. This is the context to use when using BCAL based functions.
The BCAL context has the following structure:
@ -242,14 +242,13 @@ pointer to the cipher specific context
@subsubsection BCAL-Basic
@subsection BCAL-Basic
BCAL-Basic provides the basic features of an block cipher on top of the
BCAL. To use it you simply have to include the algorithms you want to use,
the BCAL descriptor file and of course the BCAL-Basic implementation.
The following functions are provided:
@table @code
@item bcal_cipher_init
@subsubsection @code{bcal_cipher_init}
@code{uint8_t bcal_cipher_init(const bcdesc_t* cipher_descriptor, const void* key, uint16_t keysize_b, bcgen_ctx_t* ctx)}
this function initializes a BCAL context based on the given BCAL descriptor
pointer (first parameter) with a given key (second parameter) of a given length
@ -270,109 +269,29 @@ The following functions are provided:
for the selected cipher.
@end table
@item bcal_cipher_free
@subsubsection @code{bcal_cipher_free}
@code{void bcal_cipher_free(bcgen_ctx_t* ctx)} this function frees the memory
allocated by the init function and should be called whenever you are finished
with BCAL context. It automatically also calls the @code{free} function if
necessary.
@item bcal_cipher_enc
@subsubsection @code{bcal_cipher_enc}
@code{void bcal_cipher_enc(void* block, const bcgen_ctx_t* ctx)}
this function encrypts a block in-place using a given BCAL contex.
@item bcal_cipher_dec
@subsubsection @code{bcal_cipher_dec}
@code{void bcal_cipher_dec(void* block, const bcgen_ctx_t* ctx)}
this function decrypts a block in-place using a given BCAL contex.
@item bcal_cipher_getBlocksize_b
@subsubsection @code{bcal_cipher_getBlocksize_b}
@code{uint16_t bcal_cipher_getBlocksize_b(const bcdesc_t* desc)}
this function returns the block size of a given cipher by using the BCAL
descriptor (to which a pointer must be passed).
@item bcal_cipher_getKeysizeDesc
@subsubsection @code{bcal_cipher_getKeysizeDesc}
@code{PGM_VOID_P bcal_cipher_getKeysizeDesc(const bcdesc_t* desc)}
this function returns a pointer to the keysize descriptor of a given cipher by
using the BCAL descriptor (to which a pointer must be passed).
@end table
@subsection Keysize descriptors
There are a lot of different block ciphers or cryptographic algorithms in
general which put several constrains to the number of bits which can be used
as key.
Our approach is to find a simple and compact way do specify which lengths are
valid and which are not. The system is quite simple, we use a list of patterns
(with parameters) and if any matches the keysize is valid, if none matches the
keysize is unsupported.
The patterns are:
@itemize @bullet
@item simple list of valid keysizes
@item range of keysizes
@item augmented range of keysizes
@end itemize
@subsubsection simple list of valid keysizes
The simple keysize list has the following structure:
@verbatim
typedef struct{ /* keysize is valid if listed in items */
uint8_t n_items; /* number of items (value 0 is reserved) */
uint16_t items[]; /* list of valid lengths */
}keysize_desc_list_t;
@end verbatim
First we specify how many keysizes we want to declare valid (this is limited to
255 keysizes but that should not impose any real world constrains). And follow
it by the keysizes as 16bit unsigned values.
If you want to declare a lot of keys please check first the other methods since
they may give a more compact definition.
@subsubsection range of keysizes
This method specifies an entire range of keys a valid using the following
structure:
@verbatim
typedef struct{ /* keysize is valid if min<=keysize<=max */
uint16_t min;
uint16_t max;
}keysize_desc_range_t;
@end verbatim
So all keysizes between @code{min} and @code{max} (including @code{min} and
@code{max}) are valid. Please note that in most cases also keysizes which
are not a multiple of 8 (so are not full bytes) are also matched.
If you want to avoid this see the augmented range of keysizes.
@subsubsection augmented range of keysizes
The augmented range of keysizes uses the following structure:
@verbatim
typedef struct{ /* keysize is valid if min<=keysize<=max and if keysize mod distance == offset */
uint16_t min;
uint16_t max;
uint16_t distance;
uint16_t offset;
}keysize_desc_arg_range_t;
@end verbatim
The restriction to a range is the same as with the simpler range of keysizes,
but also another restriction is imposed. A valid keysize must have a reminder
of @code{offset} when divided by @code{distance}. So you can limit a keysize
to full bytes by simply setting @code{distance} to @samp{8} and @code{offset}
to @samp{0}.
@subsubsection the actual descriptor
The keysize descriptor is a list of the former patterns. Each pattern is
preceded by byte designating the type of pattern and the list is terminated
by a @code{NULL} byte.
The designator byte can have one of the following values:
@table @samp
@item 0x00
Terminator byte, signals the end of the list
@item 0x01
simple list of keysizes
@item 0x02
simple range of keysizes
@item 0x03
augmented range of keysizes
@end table

View File

@ -83,5 +83,172 @@
@subsection Hash function abstraction layer (HFAL)
The HashFunctionAbstractionLayer (BCAL) is an abstraction layer which allows
usage of all implemented hash functions in a simple way. It abstracts specific
function details and is suitable for implementations which want to be flexible
in the choosing of specific hash functions. Another important aspect is that this
abstraction layer enables the implementation of hash function operating modes
independently from concrete hash function. It is very simple to use and reassembles
the API used to implement individual hash functions.
The main component is a hash function descriptor which contains the details of
the individual hash functions.
@subsection Parts of HFAL
The HFAL is split up in different parts:
@itemize @bullet
@item HFAL declaration for HFAL decriptors
@item algorithm specific definitions of HFAL decriptors
@item HFAL basic context type
@item HFAL basic functions
@end itemize
@subsection HFAL declaration for HFAL decriptors
The HFAL descriptor is a structure which is usually placed in FLASH or ROM since
modification is unnecessary. It contains all information required to use the
according hash function.
@verbatim
typedef struct {
uint8_t type; /* 2 == hashfunction */
uint8_t flags;
PGM_P name;
uint16_t ctxsize_B;
uint16_t blocksize_b;
uint16_t hashsize_b;
hf_init_fpt init;
hf_nextBlock_fpt nextBlock;
hf_lastBlock_fpt lastBlock;
hf_ctx2hash_fpt ctx2hash;
hf_free_fpt free;
hf_mem_fpt mem;
} hfdesc_t; /* hashfunction descriptor type */
@end verbatim
@table @var
@item type
should be set to @samp{2} to indicate that this descriptor is for a
hash function.
@item flags
currently unused, should be set to zero.
@item name
is a pointer to a zero terminated ASCII string giving the name of the
implemented primitive. On targets with Harvard-architecture the string resides
in code memory (FLASH, ROM, ...).
@item ctxsize_B
is the number of bytes which should be allocated for the context variable.
@item blocksize_b
is the number of bits on which are hashed by one iteration of the nextBlock
function.
@item hashsize_b
is the number of bits on which are outputed as final hash value.
@item init
is a pointer to the init function.
@item nextBlock
is a pointer to the algorithm specific nextBlock function.
@item lastBlock
is a pointer to the algorithm specific lastBlock function.
@item ctx2hash
is a pointer to the algorithm specific ctx2hash function.
@item free
is a pointer to the free function or NULL if there is no free function.
@item mem
is a pointer to the algorithm specific mem function. This function hashes
a complete message which has to reside entirely in RAM. This value may be
NULL if there is no such function.
@end table
@subsection HFAL-Basic context
Besides the context types for individual hash functions there is a generic context
type for HFAL. This is the context to use when using HFAL based functions.
The HFAL context has the following structure:
@verbatim
typedef struct{
hfdesc_t* desc_ptr;
void* ctx;
} hfgen_ctx_t;
@end verbatim
@table @code
@item desc_ptr
a pointer to the HFAL descriptor
@item ctx
pointer to the hash function specific context
@end table
@subsection HFAL-Basic
HFAL-Basic provides the basic features of an hash function on top of the
HFAL. To use it you simply have to include the algorithms you want to use,
the HFAL descriptor file and of course the HFAL-Basic implementation.
The following functions are provided:
@subsubsection @code{hfal_hash_init}
@code{uint8_t hfal_hash_init(const hfdesc_t* hash_descriptor, hfgen_ctx_t* ctx)}
this function initializes a HFAL context based on the given HFAL descriptor
pointer (first parameter). The context to initialize is designated by the
pointer passed as second parameter.
If everything works fine @samp{0} is returned. In the case something fails
the following codes are returned:
@table @samp
@item 3
It was not possible to allocate enough memory to hold the context variable
for the selected hash function.
@end table
@subsubsection @code{hfal_hash_nextBlock}
@code{ void hfal_hash_nextBlock(hfgen_ctx_t* ctx, const void* block)}
this function hashes a block of memory (of algorithm specific length) and
updates the context accordingly.
@subsubsection @code{hfal_hash_lastBlock}
@code{ void hfal_hash_lastBlock(hfgen_ctx_t* ctx, const void* block, uint16_t length_b)}
this function is used to hash the last block of a message. Since messages are
not required to consist of full blocks (or even full bytes) the length of the
block must be given in bits. The context is updated accordingly. This function
already performs padding and related stuff.
@subsubsection @code{hfal_hash_ctx2hash}
@code{ void hfal_hash_ctx2hash(void* dest, hfgen_ctx_t* ctx)}
this function converts a context into an actual hash value which is stored in
@code{dest}. The application is responsible for allocating enough room.
@subsubsection @code{hfal_hash_free}
@code{ void hfal_hash_free(hfgen_ctx_t* ctx)}
this function differs from the individual hash functions @code{free} function
in that it is allways provided and must be called to avoid memory holes.
This function also automatically calls the implementation specific @code{free}
function if one is provided.
@subsubsection @code{hfal_hash_mem}
@code{ void hfal_hash_mem(const hfdesc_t* hash_descriptor, void* dest, const void* msg, uint32_t length_b)}
this function is allways provided (even if the actual algorithm does not
specify a @code{mem} function. It hashes an entire message which resides in
RAM and stores the hash value in @code{dest}. @code{msg} is the pointer to the
message and @code{length_b} is the message length in bits.
@subsubsection @code{hfal_hash_getBlocksize}
@code{ uint16_t hfal_hash_getBlocksize(const hfdesc_t* hash_descriptor)}
returns the blocksize of the described (@code{hash_descriptor}) hash function.
@subsubsection @code{hfal_hash_getHashsize}
@code{ uint16_t hfal_hash_getHashsize(const hfdesc_t* hash_descriptor)}
returns the hash value size of the described (@code{hash_descriptor}) hash function.
@subsubsection @code{hfal_hash_getCtxsize}
@code{ uint16_t hfal_hash_getCtxsize_B(const hfdesc_t* hash_descriptor)}
returns the size of a context variable of the described (@code{hash_descriptor}) hash function.

82
doc/acl_keysizes.texi Normal file
View File

@ -0,0 +1,82 @@
@c acl_keysizes.texi
@section Keysize descriptors
There are a lot of different block ciphers or cryptographic algorithms in
general which put several constrains to the number of bits which can be used
as key.
Our approach is to find a simple and compact way do specify which lengths are
valid and which are not. The system is quite simple, we use a list of patterns
(with parameters) and if any matches the keysize is valid, if none matches the
keysize is unsupported.
The patterns are:
@itemize @bullet
@item simple list of valid keysizes
@item range of keysizes
@item augmented range of keysizes
@end itemize
@subsection simple list of valid keysizes
The simple keysize list has the following structure:
@verbatim
typedef struct{ /* keysize is valid if listed in items */
uint8_t n_items; /* number of items (value 0 is reserved) */
uint16_t items[]; /* list of valid lengths */
}keysize_desc_list_t;
@end verbatim
First we specify how many keysizes we want to declare valid (this is limited to
255 keysizes but that should not impose any real world constrains). And follow
it by the keysizes as 16bit unsigned values.
If you want to declare a lot of keys please check first the other methods since
they may give a more compact definition.
@subsection range of keysizes
This method specifies an entire range of keys a valid using the following
structure:
@verbatim
typedef struct{ /* keysize is valid if min<=keysize<=max */
uint16_t min;
uint16_t max;
}keysize_desc_range_t;
@end verbatim
So all keysizes between @code{min} and @code{max} (including @code{min} and
@code{max}) are valid. Please note that in most cases also keysizes which
are not a multiple of 8 (so are not full bytes) are also matched.
If you want to avoid this see the augmented range of keysizes.
@subsection augmented range of keysizes
The augmented range of keysizes uses the following structure:
@verbatim
typedef struct{ /* keysize is valid if min<=keysize<=max and if keysize mod distance == offset */
uint16_t min;
uint16_t max;
uint16_t distance;
uint16_t offset;
}keysize_desc_arg_range_t;
@end verbatim
The restriction to a range is the same as with the simpler range of keysizes,
but also another restriction is imposed. A valid keysize must have a reminder
of @code{offset} when divided by @code{distance}. So you can limit a keysize
to full bytes by simply setting @code{distance} to @samp{8} and @code{offset}
to @samp{0}.
@subsection the actual descriptor
The keysize descriptor is a list of the former patterns. Each pattern is
preceded by byte designating the type of pattern and the list is terminated
by a @code{NULL} byte.
The designator byte can have one of the following values:
@table @samp
@item 0x00
Terminator byte, signals the end of the list
@item 0x01
simple list of keysizes
@item 0x02
simple range of keysizes
@item 0x03
augmented range of keysizes
@end table

View File

@ -127,6 +127,9 @@ end
################################################################################
def init_system(test_prog)
begin
line = $sp.gets()
end while line!=nil
$sp.print("echo off \r")
print("DBG i: " + "echo off \r"+"\n") if $debug
sleep 0.1
@ -135,6 +138,27 @@ def init_system(test_prog)
sleep 1
end
################################################################################
# wait_for_prompt #
################################################################################
def wait_for_prompt(prompt)
prompt = /[\s]*#{prompt}[\s]*/ if(prompt.class == String)
start_time = Time.now.to_i
begin
line = $sp.gets()
puts("DBG got (#{__LINE__}): "+line) if $debug && line
line = "" if line==nil
if /^(Error:|Crypto-VS).*/.match(line)
puts line
return false
end
if (Time.now.to_i- start_time) > $max_timeout
return false
end
end while not m=prompt.match(line)
return m
end
################################################################################
# screen_progress #
@ -249,59 +273,42 @@ end
################################################################################
# add_scale_test #
################################################################################
def add_scale_test_dummy(a, b, scale)
should = a + (b<<(8*scale))
printf("[dummy] %s + %s <<8*%04x = %s\n",a.to_s(16), b.to_s(16), scale, should.to_s(16))
end
def add_scale_test(a, b, scale)
begin
line = $sp.gets()
line = "" if line==nil
puts("DBG got (#{__LINE__}): "+line) if $debug
if /^Error:.*/.match(line)
puts line
return false
end
end while not /[\s]*enter a:[\s]*/.match(line)
m = wait_for_prompt("enter a:")
return false if !m
puts("DBG put (#{__LINE__}): "+a.to_s(16)+" ") if $debug
$sp.print(a.to_s(16)+" ")
begin
line = $sp.gets()
line = "" if line==nil
puts("DBG got (#{__LINE__}): "+line) if $debug
if /^Error:.*/.match(line)
puts line
return false
end
end while not /[\s]*enter b:[\s]*/.match(line)
m = wait_for_prompt("enter b:")
return false if !m
puts("DBG put (#{__LINE__}): "+b.to_s(16)+" ") if $debug
$sp.print(b.to_s(16)+" ")
begin
line = $sp.gets()
line = "" if line==nil
puts("DBG got (#{__LINE__}): "+line) if $debug
if /^Error:.*/.match(line)
puts line
return false
end
end while not /[\s]*enter scale:[\s]*/.match(line)
m = wait_for_prompt("enter scale:")
return false if !m
puts("DBG put (#{__LINE__}): "+scale.to_s(10)+" ") if $debug
$sp.print(scale.to_s(10)+"\r")
begin
line = $sp.gets()
line = "" if line==nil
puts("DBG got (#{__LINE__}): "+line) if $debug
if /^Error:.*/.match(line)
puts line
return false
end
end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*<<8\*[\s]*([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
should = a + (b<<(8*scale))
m = wait_for_prompt(/[\s]*([-]?[0-9a-fA-F]+)[\s]+\+[\s]+([+-]?[0-9a-fA-F]+)[\s]*<<8\*[\s]*([+-]?[0-9a-fA-F]+)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/)
if !m
$logfile.printf("[fail (CRASH)]:")
$logfile.printf(" ; should %s + %s << 8*%s = %s\n", a.to_s(16), b.to_s(16), scale.to_s(16), should.to_s(16))
return false
end
line = m[0]
a_ = m[1].to_i(16)
b_ = m[2].to_i(16)
s_ = m[3].to_i(16)
c_ = m[4].to_i(16)
line.chomp!
should = a + (b<<(8*scale))
if(a_== a && b_ == b && s_ == scale && c_ == should )
$logfile.printf("[pass]: %s\n", line)
return true
else
$logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (scale==s_)?"":"s",(c_==should)?"":"c",line)
$logfile.printf("[fail (%s%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (scale==s_)?"":"s",(c_==should)?"":"c",line)
$logfile.printf(" ; should %s + %s << 8*%s = %s\n", a.to_s(16), b.to_s(16), scale.to_s(16), should.to_s(16))
return false
end
@ -563,7 +570,7 @@ def run_test_add_scale(skip=0)
length_b_B = skip+1
begin
$size = length_a_B
(0..16).each do |i|
(0..4).each do |i|
scales = [0, 300]
16.times { scales << rand(301) }
scales.sort!
@ -576,7 +583,42 @@ def run_test_add_scale(skip=0)
screen_progress(v)
end
end
(0..16).each do |i|
(0..4).each do |i|
scales = [0, 300]
16.times { scales << rand(301) }
scales.sort!
scales.each do |scale|
b_size = rand(length_b_B+1)+1
a = rand(256**length_a_B)
b = rand(256**b_size)
v = add_scale_test(a, b, scale)
screen_progress(v)
v = add_scale_test(b, a, scale)
screen_progress(v)
end
end
length_a_B += 10
length_b_B += 10
end while length_a_B<4096/8
end
def run_test_add_scale_dummy(skip=0)
length_a_B = skip+1
length_b_B = skip+1
begin
$size = length_a_B
(0..4).each do |i|
scales = [0, 300]
16.times { scales << rand(301) }
scales.sort!
scales.each do |scale|
a = rand(256**length_a_B)
b = rand(256**length_a_B)
v = add_scale_test_dummy(a, b, scale)
v = add_scale_test_dummy(b, a, scale)
end
end
(0..4).each do |i|
scales = [0, 300]
16.times { scales << rand(301) }
scales.sort!
@ -584,10 +626,8 @@ def run_test_add_scale(skip=0)
b_size = rand(length_b_B+1)
a = rand(256**length_a_B)
b = rand(256**b_size)
v = add_scale_test(a, b, scale)
screen_progress(v)
v = add_scale_test(b, a, scale)
screen_progress(v)
v = add_scale_test_dummy(a, b, scale)
v = add_scale_test_dummy(b, a, scale)
end
end
length_a_B += 10
@ -733,6 +773,36 @@ def run_test_gcdext(skip=0)
end while length_a_B<4096/8
end
def init_serialport(conf)
puts("serial port interface version: " + SerialPort::VERSION);
$linewidth = 64
$linepos = 0
$testno = 0
params = { "baud" => conf["PORT"]["baud"].to_i,
"data_bits" => conf["PORT"]["databits"].to_i,
"stop_bits" => conf["PORT"]["stopbits"].to_i,
"parity" => SerialPort::NONE }
params["paraty"] = SerialPort::ODD if conf["PORT"]["paraty"].downcase == "odd"
params["paraty"] = SerialPort::EVEN if conf["PORT"]["paraty"].downcase == "even"
params["paraty"] = SerialPort::MARK if conf["PORT"]["paraty"].downcase == "mark"
params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
puts("\nPort: "+conf["PORT"]["port"]+"@" +
params["baud"].to_s +
" " +
params["data_bits"].to_s +
conf["PORT"]["paraty"][0,1].upcase +
params["stop_bits"].to_s +
"\n")
$sp = SerialPort.new(conf["PORT"]["port"], params)
$sp.read_timeout=1000; # 5 minutes
$sp.flow_control = SerialPort::SOFT
reset_system()
end
################################################################################
# MAIN #
################################################################################
@ -746,34 +816,9 @@ conf = readconfigfile("testport.conf", conf)
conf = readconfigfile(opts["f"], conf) if opts["f"]
#puts conf.inspect
init_serialport(conf)
puts("serial port interface version: " + SerialPort::VERSION);
$linewidth = 64
$linepos = 0
$testno = 0
params = { "baud" => conf["PORT"]["baud"].to_i,
"data_bits" => conf["PORT"]["databits"].to_i,
"stop_bits" => conf["PORT"]["stopbits"].to_i,
"parity" => SerialPort::NONE }
params["paraty"] = SerialPort::ODD if conf["PORT"]["paraty"].downcase == "odd"
params["paraty"] = SerialPort::EVEN if conf["PORT"]["paraty"].downcase == "even"
params["paraty"] = SerialPort::MARK if conf["PORT"]["paraty"].downcase == "mark"
params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
puts("\nPort: "+conf["PORT"]["port"]+"@" +
params["baud"].to_s +
" " +
params["data_bits"].to_s +
conf["PORT"]["paraty"][0,1].upcase +
params["stop_bits"].to_s +
"\n")
$sp = SerialPort.new(conf["PORT"]["port"], params)
$sp.read_timeout=1000; # 5 minutes
$sp.flow_control = SerialPort::SOFT
reset_system()
$max_timeout = 2 * 60
if opts['d']
$debug = true

View File

@ -125,13 +125,6 @@ void test_add_scale_bigint(void){
return;
}
*/
cli_putstr_P(PSTR("\r\n "));
bigint_print_hex(&a);
cli_putstr_P(PSTR(" + "));
bigint_print_hex(&b);
cli_putstr_P(PSTR("<<8*"));
cli_hexdump_rev(&scale, 2);
cli_putstr_P(PSTR(" = "));
uint8_t *c_b;
c_b = malloc(((a.length_B>(b.length_B+scale))?a.length_B:(b.length_B+scale))+2);
if(c_b==NULL){
@ -143,6 +136,13 @@ void test_add_scale_bigint(void){
c.wordv = c_b;
bigint_copy(&c, &a);
bigint_add_scale_u(&c, &b, scale);
cli_putstr_P(PSTR("\r\n "));
bigint_print_hex(&a);
cli_putstr_P(PSTR(" + "));
bigint_print_hex(&b);
cli_putstr_P(PSTR("<<8*"));
cli_hexdump_rev(&scale, 2);
cli_putstr_P(PSTR(" = "));
bigint_print_hex(&c);
cli_putstr_P(PSTR("\r\n"));
free(a.wordv);