[test] Update big integer tests to use okx()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-12-29 13:18:10 +00:00
parent 3832147944
commit 01038893a3

View File

@@ -40,6 +40,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** Define inline big integer */ /** Define inline big integer */
#define BIGINT(...) { __VA_ARGS__ } #define BIGINT(...) { __VA_ARGS__ }
/** A big integer test value */
struct bigint_test {
/** Raw value */
const uint8_t *raw;
/** Length of raw value */
size_t len;
};
/* Provide global functions to allow inspection of generated assembly code */ /* Provide global functions to allow inspection of generated assembly code */
void bigint_init_sample ( bigint_element_t *value0, unsigned int size, void bigint_init_sample ( bigint_element_t *value0, unsigned int size,
@@ -245,38 +253,49 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer to be added to * @v value Big integer to be added to
* @v expected Big integer expected result * @v expected Big integer expected result
* @v overflow Expected result overflows range * @v overflow Expected result overflows range
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_add_okx ( struct bigint_test *addend,
struct bigint_test *value,
struct bigint_test *expected, int overflow,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( value->len );
unsigned int msb = ( 8 * value->len );
bigint_t ( size ) addend_temp;
bigint_t ( size ) value_temp;
int carry;
assert ( bigint_size ( &addend_temp ) == bigint_size ( &value_temp ) );
bigint_init ( &value_temp, value->raw, value->len );
bigint_init ( &addend_temp, addend->raw, addend->len );
DBG ( "Add: 0x%s", bigint_ntoa ( &addend_temp ) );
DBG ( " + 0x%s", bigint_ntoa ( &value_temp ) );
carry = bigint_add ( &addend_temp, &value_temp );
DBG ( " = 0x%s%s\n", bigint_ntoa ( &value_temp ),
( carry ? " (carry)" : "" ) );
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
if ( sizeof ( result_raw ) < sizeof ( value_temp ) )
carry += bigint_bit_is_set ( &value_temp, msb );
okx ( carry == overflow, file, line );
}
#define bigint_add_ok( addend, value, expected, overflow ) do { \ #define bigint_add_ok( addend, value, expected, overflow ) do { \
static const uint8_t addend_raw[] = addend; \ static const uint8_t addend_raw[] = addend; \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test addend_test = \
unsigned int size = \ { addend_raw, sizeof ( addend_raw ) }; \
bigint_required_size ( sizeof ( value_raw ) ); \ static struct bigint_test value_test = \
unsigned int msb = ( 8 * sizeof ( value_raw ) ); \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) addend_temp; \ static struct bigint_test expected_test = \
bigint_t ( size ) value_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
int carry; \ bigint_add_okx ( &addend_test, &value_test, &expected_test, \
{} /* Fix emacs alignment */ \ overflow, __FILE__, __LINE__ ); \
\ } while ( 0 )
assert ( bigint_size ( &addend_temp ) == \
bigint_size ( &value_temp ) ); \
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
bigint_init ( &addend_temp, addend_raw, \
sizeof ( addend_raw ) ); \
DBG ( "Add:\n" ); \
DBG_HDA ( 0, &addend_temp, sizeof ( addend_temp ) ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
carry = bigint_add ( &addend_temp, &value_temp ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
if ( sizeof ( result_raw ) < sizeof ( value_temp ) ) \
carry += bigint_bit_is_set ( &value_temp, msb ); \
ok ( carry == overflow ); \
} while ( 0 )
/** /**
* Report result of big integer subtraction test * Report result of big integer subtraction test
@@ -285,35 +304,48 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer to be subtracted from * @v value Big integer to be subtracted from
* @v expected Big integer expected result * @v expected Big integer expected result
* @v underflow Expected result underflows range * @v underflow Expected result underflows range
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_subtract_okx ( struct bigint_test *subtrahend,
struct bigint_test *value,
struct bigint_test *expected, int underflow,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) subtrahend_temp;
bigint_t ( size ) value_temp;
int borrow;
assert ( bigint_size ( &subtrahend_temp ) ==
bigint_size ( &value_temp ) );
bigint_init ( &value_temp, value->raw, value->len );
bigint_init ( &subtrahend_temp, subtrahend->raw, subtrahend->len );
DBG ( "Subtract: 0x%s", bigint_ntoa ( &value_temp ) );
DBG ( " - 0x%s", bigint_ntoa ( &subtrahend_temp ) );
borrow = bigint_subtract ( &subtrahend_temp, &value_temp );
DBG ( " = 0x%s%s\n", bigint_ntoa ( &value_temp ),
( borrow ? " (borrow)" : "" ) );
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
okx ( borrow == underflow, file, line );
}
#define bigint_subtract_ok( subtrahend, value, expected, \ #define bigint_subtract_ok( subtrahend, value, expected, \
underflow ) do { \ underflow ) do { \
static const uint8_t subtrahend_raw[] = subtrahend; \ static const uint8_t subtrahend_raw[] = subtrahend; \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test subtrahend_test = \
unsigned int size = \ { subtrahend_raw, sizeof ( subtrahend_raw ) }; \
bigint_required_size ( sizeof ( value_raw ) ); \ static struct bigint_test value_test = \
bigint_t ( size ) subtrahend_temp; \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) value_temp; \ static struct bigint_test expected_test = \
int borrow; \ { expected_raw, sizeof ( expected_raw ) }; \
{} /* Fix emacs alignment */ \ bigint_subtract_okx ( &subtrahend_test, &value_test, \
\ &expected_test, underflow, \
assert ( bigint_size ( &subtrahend_temp ) == \ __FILE__, __LINE__ ); \
bigint_size ( &value_temp ) ); \
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
bigint_init ( &subtrahend_temp, subtrahend_raw, \
sizeof ( subtrahend_raw ) ); \
DBG ( "Subtract:\n" ); \
DBG_HDA ( 0, &subtrahend_temp, sizeof ( subtrahend_temp ) ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
borrow = bigint_subtract ( &subtrahend_temp, &value_temp ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
ok ( borrow == underflow ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -322,30 +354,39 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer * @v value Big integer
* @v expected Big integer expected result * @v expected Big integer expected result
* @v bit Expected bit shifted out * @v bit Expected bit shifted out
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_shl_okx ( struct bigint_test *value,
struct bigint_test *expected, int bit,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( value->len );
unsigned int msb = ( 8 * value->len );
bigint_t ( size ) value_temp;
int out;
bigint_init ( &value_temp, value->raw, value->len );
DBG ( "Shift left 0x%s << 1", bigint_ntoa ( &value_temp ) );
out = bigint_shl ( &value_temp );
DBG ( " = 0x%s (%d)\n", bigint_ntoa ( &value_temp ), out );
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
if ( sizeof ( result_raw ) < sizeof ( value_temp ) )
out += bigint_bit_is_set ( &value_temp, msb );
okx ( out == bit, file, line );
}
#define bigint_shl_ok( value, expected, bit ) do { \ #define bigint_shl_ok( value, expected, bit ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test value_test = \
unsigned int size = \ { value_raw, sizeof ( value_raw ) }; \
bigint_required_size ( sizeof ( value_raw ) ); \ static struct bigint_test expected_test = \
unsigned int msb = ( 8 * sizeof ( value_raw ) ); \ { expected_raw, sizeof ( expected_raw ) }; \
bigint_t ( size ) value_temp; \ bigint_shl_okx ( &value_test, &expected_test, bit, \
int out; \ __FILE__, __LINE__ ); \
{} /* Fix emacs alignment */ \
\
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
DBG ( "Shift left:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
out = bigint_shl ( &value_temp ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
if ( sizeof ( result_raw ) < sizeof ( value_temp ) ) \
out += bigint_bit_is_set ( &value_temp, msb ); \
ok ( out == bit ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -354,27 +395,36 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer * @v value Big integer
* @v expected Big integer expected result * @v expected Big integer expected result
* @v bit Expected bit shifted out * @v bit Expected bit shifted out
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_shr_okx ( struct bigint_test *value,
struct bigint_test *expected, int bit,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) value_temp;
int out;
bigint_init ( &value_temp, value->raw, value->len );
DBG ( "Shift right 0x%s >> 1", bigint_ntoa ( &value_temp ) );
out = bigint_shr ( &value_temp );
DBG ( " = 0x%s (%d)\n", bigint_ntoa ( &value_temp ), out );
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
okx ( out == bit, file, line );
}
#define bigint_shr_ok( value, expected, bit ) do { \ #define bigint_shr_ok( value, expected, bit ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test value_test = \
unsigned int size = \ { value_raw, sizeof ( value_raw ) }; \
bigint_required_size ( sizeof ( value_raw ) ); \ static struct bigint_test expected_test = \
bigint_t ( size ) value_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
int out; \ bigint_shr_okx ( &value_test, &expected_test, bit, \
{} /* Fix emacs alignment */ \ __FILE__, __LINE__ ); \
\
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
DBG ( "Shift right:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
out = bigint_shr ( &value_temp ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
bigint_done ( &value_temp, result_raw, sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
ok ( out == bit ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -382,21 +432,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* *
* @v value Big integer * @v value Big integer
* @v expected Expected result * @v expected Expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_is_zero_okx ( struct bigint_test *value, int expected,
const char *file, unsigned int line ) {
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) value_temp;
int is_zero;
bigint_init ( &value_temp, value->raw, value->len );
DBG ( "Zero comparison: 0x%s", bigint_ntoa ( &value_temp ) );
is_zero = bigint_is_zero ( &value_temp );
DBG ( " %s 0\n", ( is_zero ? "==" : "!=" ) );
okx ( ( !! is_zero ) == ( !! (expected) ), file, line );
}
#define bigint_is_zero_ok( value, expected ) do { \ #define bigint_is_zero_ok( value, expected ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
unsigned int size = \ static struct bigint_test value_test = \
bigint_required_size ( sizeof ( value_raw ) ); \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) value_temp; \ bigint_is_zero_okx ( &value_test, expected, \
int is_zero; \ __FILE__, __LINE__ ); \
{} /* Fix emacs alignment */ \
\
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
DBG ( "Zero comparison:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
is_zero = bigint_is_zero ( &value_temp ); \
DBG ( "...is %szero\n", ( is_zero ? "" : "not " ) ); \
ok ( ( !! is_zero ) == ( !! (expected) ) ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -405,29 +461,37 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer * @v value Big integer
* @v reference Reference big integer * @v reference Reference big integer
* @v expected Expected result * @v expected Expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_is_geq_okx ( struct bigint_test *value,
struct bigint_test *reference, int expected,
const char *file, unsigned int line ) {
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) value_temp;
bigint_t ( size ) reference_temp;
int is_geq;
assert ( bigint_size ( &reference_temp ) ==
bigint_size ( &value_temp ) );
bigint_init ( &value_temp, value->raw, value->len );
bigint_init ( &reference_temp, reference->raw, reference->len );
DBG ( "Greater-than-or-equal comparison: 0x%s",
bigint_ntoa ( &value_temp ) );
is_geq = bigint_is_geq ( &value_temp, &reference_temp );
DBG ( " %s 0x%s\n", ( is_geq ? ">=" : "<" ),
bigint_ntoa ( &reference_temp ) );
okx ( ( !! is_geq ) == ( !! (expected) ), file, line );
}
#define bigint_is_geq_ok( value, reference, expected ) do { \ #define bigint_is_geq_ok( value, reference, expected ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
static const uint8_t reference_raw[] = reference; \ static const uint8_t reference_raw[] = reference; \
unsigned int size = \ static struct bigint_test value_test = \
bigint_required_size ( sizeof ( value_raw ) ); \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) value_temp; \ static struct bigint_test reference_test = \
bigint_t ( size ) reference_temp; \ { reference_raw, sizeof ( reference_raw ) }; \
int is_geq; \ bigint_is_geq_okx ( &value_test, &reference_test, expected, \
{} /* Fix emacs alignment */ \ __FILE__, __LINE__ ); \
\
assert ( bigint_size ( &reference_temp ) == \
bigint_size ( &value_temp ) ); \
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
bigint_init ( &reference_temp, reference_raw, \
sizeof ( reference_raw ) ); \
DBG ( "Greater-than-or-equal comparison:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
DBG_HDA ( 0, &reference_temp, sizeof ( reference_temp ) ); \
is_geq = bigint_is_geq ( &value_temp, &reference_temp ); \
DBG ( "...is %sgreater than or equal\n", \
( is_geq ? "" : "not " ) ); \
ok ( ( !! is_geq ) == ( !! (expected) ) ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -436,22 +500,28 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v value Big integer * @v value Big integer
* @v bit Bit to test * @v bit Bit to test
* @v expected Expected result * @v expected Expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_bit_is_set_okx ( struct bigint_test *value,
unsigned int bit, int expected,
const char *file, unsigned int line ) {
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) value_temp;
int bit_is_set;
bigint_init ( &value_temp, value->raw, value->len );
DBG ( "Bit set: 0x%s bit %d", bigint_ntoa ( &value_temp ), bit );
bit_is_set = bigint_bit_is_set ( &value_temp, bit );
DBG ( " is %sset\n", ( bit_is_set ? "" : "not " ) );
okx ( ( !! bit_is_set ) == ( !! (expected) ), file, line );
}
#define bigint_bit_is_set_ok( value, bit, expected ) do { \ #define bigint_bit_is_set_ok( value, bit, expected ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
unsigned int size = \ static struct bigint_test value_test = \
bigint_required_size ( sizeof ( value_raw ) ); \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) value_temp; \ bigint_bit_is_set_okx ( &value_test, bit, expected, \
int bit_is_set; \ __FILE__, __LINE__ ); \
{} /* Fix emacs alignment */ \
\
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
DBG ( "Bit set:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
bit_is_set = bigint_bit_is_set ( &value_temp, bit ); \
DBG ( "...bit %d is %sset\n", bit, \
( bit_is_set ? "" : "not " ) ); \
ok ( ( !! bit_is_set ) == ( !! (expected) ) ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -459,21 +529,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* *
* @v value Big integer * @v value Big integer
* @v expected Expected result * @v expected Expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_max_set_bit_okx ( struct bigint_test *value, int expected,
const char *file, unsigned int line ) {
unsigned int size = bigint_required_size ( value->len );
bigint_t ( size ) value_temp;
int max_set_bit;
bigint_init ( &value_temp, value->raw, value->len );
DBG ( "Maximum set bit: 0x%s", bigint_ntoa ( &value_temp ) );
max_set_bit = bigint_max_set_bit ( &value_temp );
DBG ( " MSB is bit %d\n", ( max_set_bit - 1 ) );
okx ( max_set_bit == expected, file, line );
}
#define bigint_max_set_bit_ok( value, expected ) do { \ #define bigint_max_set_bit_ok( value, expected ) do { \
static const uint8_t value_raw[] = value; \ static const uint8_t value_raw[] = value; \
unsigned int size = \ static struct bigint_test value_test = \
bigint_required_size ( sizeof ( value_raw ) ); \ { value_raw, sizeof ( value_raw ) }; \
bigint_t ( size ) value_temp; \ bigint_max_set_bit_okx ( &value_test, expected, \
int max_set_bit; \ __FILE__, __LINE__ ); \
{} /* Fix emacs alignment */ \
\
bigint_init ( &value_temp, value_raw, sizeof ( value_raw ) ); \
DBG ( "Maximum set bit:\n" ); \
DBG_HDA ( 0, &value_temp, sizeof ( value_temp ) ); \
max_set_bit = bigint_max_set_bit ( &value_temp ); \
DBG ( "...maximum set bit is bit %d\n", ( max_set_bit - 1 ) ); \
ok ( max_set_bit == (expected) ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -481,35 +557,46 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* *
* @v first Big integer to be conditionally swapped * @v first Big integer to be conditionally swapped
* @v second Big integer to be conditionally swapped * @v second Big integer to be conditionally swapped
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_swap_okx ( struct bigint_test *first,
struct bigint_test *second,
const char *file, unsigned int line ) {
uint8_t temp[ first->len ];
unsigned int size = bigint_required_size ( sizeof ( temp) );
bigint_t ( size ) first_temp;
bigint_t ( size ) second_temp;
assert ( first->len == sizeof ( temp ) );
assert ( second->len == sizeof ( temp ) );
bigint_init ( &first_temp, first->raw, first->len );
bigint_init ( &second_temp, second->raw, second->len );
bigint_swap ( &first_temp, &second_temp, 0 );
bigint_done ( &first_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line );
bigint_done ( &second_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line );
bigint_swap ( &first_temp, &second_temp, 1 );
bigint_done ( &first_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line );
bigint_done ( &second_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line );
bigint_swap ( &first_temp, &second_temp, 1 );
bigint_done ( &first_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, first->raw, sizeof ( temp ) ) == 0, file, line );
bigint_done ( &second_temp, temp, sizeof ( temp ) );
okx ( memcmp ( temp, second->raw, sizeof ( temp ) ) == 0, file, line );
}
#define bigint_swap_ok( first, second ) do { \ #define bigint_swap_ok( first, second ) do { \
static const uint8_t first_raw[] = first; \ static const uint8_t first_raw[] = first; \
static const uint8_t second_raw[] = second; \ static const uint8_t second_raw[] = second; \
uint8_t temp[ sizeof ( first_raw ) ]; \ static struct bigint_test first_test = \
unsigned int size = bigint_required_size ( sizeof ( temp) ); \ { first_raw, sizeof ( first_raw ) }; \
bigint_t ( size ) first_temp; \ static struct bigint_test second_test = \
bigint_t ( size ) second_temp; \ { second_raw, sizeof ( second_raw ) }; \
{} /* Fix emacs alignment */ \ bigint_swap_okx ( &first_test, &second_test, \
\ __FILE__, __LINE__ ); \
assert ( sizeof ( first_raw ) == sizeof ( temp ) ); \
assert ( sizeof ( second_raw ) == sizeof ( temp ) ); \
bigint_init ( &first_temp, first_raw, sizeof ( first_raw ) ); \
bigint_init ( &second_temp, second_raw, sizeof ( second_raw ) );\
bigint_swap ( &first_temp, &second_temp, 0 ); \
bigint_done ( &first_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \
bigint_done ( &second_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \
bigint_swap ( &first_temp, &second_temp, 1 ); \
bigint_done ( &first_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \
bigint_done ( &second_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \
bigint_swap ( &first_temp, &second_temp, 1 ); \
bigint_done ( &first_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, first_raw, sizeof ( temp ) ) == 0 ); \
bigint_done ( &second_temp, temp, sizeof ( temp ) ); \
ok ( memcmp ( temp, second_raw, sizeof ( temp ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -518,38 +605,49 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v multiplicand Big integer to be multiplied * @v multiplicand Big integer to be multiplied
* @v multiplier Big integer to be multiplied * @v multiplier Big integer to be multiplied
* @v expected Big integer expected result * @v expected Big integer expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_multiply_okx ( struct bigint_test *multiplicand,
struct bigint_test *multiplier,
struct bigint_test *expected,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int multiplicand_size =
bigint_required_size ( multiplicand->len );
unsigned int multiplier_size =
bigint_required_size ( multiplier->len );
bigint_t ( multiplicand_size ) multiplicand_temp;
bigint_t ( multiplier_size ) multiplier_temp;
bigint_t ( multiplicand_size + multiplier_size ) result_temp;
assert ( bigint_size ( &result_temp ) ==
( bigint_size ( &multiplicand_temp ) +
bigint_size ( &multiplier_temp ) ) );
bigint_init ( &multiplicand_temp, multiplicand->raw,
multiplicand->len );
bigint_init ( &multiplier_temp, multiplier->raw, multiplier->len );
DBG ( "Multiply 0x%s", bigint_ntoa ( &multiplicand_temp ) );
DBG ( " * 0x%s", bigint_ntoa ( &multiplier_temp ) );
bigint_multiply ( &multiplicand_temp, &multiplier_temp, &result_temp );
DBG ( " = 0x%s\n", bigint_ntoa ( &result_temp ) );
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
}
#define bigint_multiply_ok( multiplicand, multiplier, expected ) do { \ #define bigint_multiply_ok( multiplicand, multiplier, expected ) do { \
static const uint8_t multiplicand_raw[] = multiplicand; \ static const uint8_t multiplicand_raw[] = multiplicand; \
static const uint8_t multiplier_raw[] = multiplier; \ static const uint8_t multiplier_raw[] = multiplier; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test multiplicand_test = \
unsigned int multiplicand_size = \ { multiplicand_raw, sizeof ( multiplicand_raw ) }; \
bigint_required_size ( sizeof ( multiplicand_raw ) ); \ static struct bigint_test multiplier_test = \
unsigned int multiplier_size = \ { multiplier_raw, sizeof ( multiplier_raw ) }; \
bigint_required_size ( sizeof ( multiplier_raw ) ); \ static struct bigint_test expected_test = \
bigint_t ( multiplicand_size ) multiplicand_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
bigint_t ( multiplier_size ) multiplier_temp; \ bigint_multiply_okx ( &multiplicand_test, &multiplier_test, \
bigint_t ( multiplicand_size + multiplier_size ) result_temp; \ &expected_test, __FILE__, __LINE__ ); \
{} /* Fix emacs alignment */ \
\
assert ( bigint_size ( &result_temp ) == \
( bigint_size ( &multiplicand_temp ) + \
bigint_size ( &multiplier_temp ) ) ); \
bigint_init ( &multiplicand_temp, multiplicand_raw, \
sizeof ( multiplicand_raw ) ); \
bigint_init ( &multiplier_temp, multiplier_raw, \
sizeof ( multiplier_raw ) ); \
DBG ( "Multiply:\n" ); \
DBG_HDA ( 0, &multiplicand_temp, sizeof ( multiplicand_temp ) );\
DBG_HDA ( 0, &multiplier_temp, sizeof ( multiplier_temp ) ); \
bigint_multiply ( &multiplicand_temp, &multiplier_temp, \
&result_temp ); \
DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -557,31 +655,40 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* *
* @v modulus Big integer modulus * @v modulus Big integer modulus
* @v expected Big integer expected result * @v expected Big integer expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_reduce_okx ( struct bigint_test *modulus,
struct bigint_test *expected,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( modulus->len );
bigint_t ( size ) modulus_temp;
bigint_t ( size ) result_temp;
assert ( bigint_size ( &modulus_temp ) ==
bigint_size ( &result_temp ) );
assert ( sizeof ( result_temp ) == sizeof ( result_raw ) );
bigint_init ( &modulus_temp, modulus->raw, modulus->len );
DBG ( "Modular reduce (2^%zd)", ( 2 * 8 * sizeof ( modulus_temp ) ) );
bigint_reduce ( &modulus_temp, &result_temp );
DBG ( " = 0x%s", bigint_ntoa ( &result_temp ) );
DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) );
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
}
#define bigint_reduce_ok( modulus, expected ) do { \ #define bigint_reduce_ok( modulus, expected ) do { \
static const uint8_t modulus_raw[] = modulus; \ static const uint8_t modulus_raw[] = modulus; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test modulus_test = \
unsigned int size = \ { modulus_raw, sizeof ( modulus_raw ) }; \
bigint_required_size ( sizeof ( modulus_raw ) ); \ static struct bigint_test expected_test = \
bigint_t ( size ) modulus_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
bigint_t ( size ) result_temp; \ bigint_reduce_okx ( &modulus_test, &expected_test, \
{} /* Fix emacs alignment */ \ __FILE__, __LINE__ ); \
\
assert ( bigint_size ( &modulus_temp ) == \
bigint_size ( &result_temp ) ); \
assert ( sizeof ( result_temp ) == sizeof ( result_raw ) ); \
bigint_init ( &modulus_temp, modulus_raw, \
sizeof ( modulus_raw ) ); \
DBG ( "Modular reduce R^2:\n" ); \
DBG_HDA ( 0, &modulus_temp, sizeof ( modulus_temp ) ); \
bigint_reduce ( &modulus_temp, &result_temp ); \
DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \
bigint_done ( &result_temp, result_raw, \
sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -589,30 +696,38 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* *
* @v invertend Big integer to be inverted * @v invertend Big integer to be inverted
* @v expected Big integer expected result * @v expected Big integer expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_mod_invert_okx ( struct bigint_test *invertend,
struct bigint_test *expected,
const char *file, unsigned int line ) {
uint8_t inverse_raw[ expected->len ];
unsigned int invertend_size = bigint_required_size ( invertend->len );
unsigned int inverse_size =
bigint_required_size ( sizeof ( inverse_raw ) );
bigint_t ( invertend_size ) invertend_temp;
bigint_t ( inverse_size ) inverse_temp;
bigint_init ( &invertend_temp, invertend->raw, invertend->len );
DBG ( "Modular invert: 0x%s", bigint_ntoa ( &invertend_temp ) );
bigint_mod_invert ( &invertend_temp, &inverse_temp );
DBG ( " * 0x%s = 1 (mod 2^%zd)\n", bigint_ntoa ( &inverse_temp ),
( 8 * sizeof ( inverse_raw ) ) );
bigint_done ( &inverse_temp, inverse_raw, sizeof ( inverse_raw ) );
okx ( memcmp ( inverse_raw, expected->raw,
sizeof ( inverse_raw ) ) == 0, file, line );
}
#define bigint_mod_invert_ok( invertend, expected ) do { \ #define bigint_mod_invert_ok( invertend, expected ) do { \
static const uint8_t invertend_raw[] = invertend; \ static const uint8_t invertend_raw[] = invertend; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t inverse_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test invertend_test = \
unsigned int invertend_size = \ { invertend_raw, sizeof ( invertend_raw ) }; \
bigint_required_size ( sizeof ( invertend_raw ) ); \ static struct bigint_test expected_test = \
unsigned int inverse_size = \ { expected_raw, sizeof ( expected_raw ) }; \
bigint_required_size ( sizeof ( inverse_raw ) ); \ bigint_mod_invert_okx ( &invertend_test, &expected_test, \
bigint_t ( invertend_size ) invertend_temp; \ __FILE__, __LINE__ ); \
bigint_t ( inverse_size ) inverse_temp; \
{} /* Fix emacs alignment */ \
\
bigint_init ( &invertend_temp, invertend_raw, \
sizeof ( invertend_raw ) ); \
DBG ( "Modular invert:\n" ); \
DBG_HDA ( 0, &invertend_temp, sizeof ( invertend_temp ) ); \
bigint_mod_invert ( &invertend_temp, &inverse_temp ); \
DBG_HDA ( 0, &inverse_temp, sizeof ( inverse_temp ) ); \
bigint_done ( &inverse_temp, inverse_raw, \
sizeof ( inverse_raw ) ); \
\
ok ( memcmp ( inverse_raw, expected_raw, \
sizeof ( inverse_raw ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -621,34 +736,44 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v modulus Big integer modulus * @v modulus Big integer modulus
* @v mont Big integer Montgomery product * @v mont Big integer Montgomery product
* @v expected Big integer expected result * @v expected Big integer expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_montgomery_okx ( struct bigint_test *modulus,
struct bigint_test *mont,
struct bigint_test *expected,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( modulus->len );
bigint_t ( size ) modulus_temp;
bigint_t ( 2 * size ) mont_temp;
bigint_t ( size ) result_temp;
assert ( ( modulus->len % sizeof ( bigint_element_t ) ) == 0 );
bigint_init ( &modulus_temp, modulus->raw, modulus->len );
bigint_init ( &mont_temp, mont->raw, mont->len );
DBG ( "Montgomery 0x%s", bigint_ntoa ( &mont_temp ) );
bigint_montgomery ( &modulus_temp, &mont_temp, &result_temp );
DBG ( " = 0x%s * (2 ^ %zd)", bigint_ntoa ( &result_temp ),
( 8 * sizeof ( modulus_temp ) ) );
DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) );
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
}
#define bigint_montgomery_ok( modulus, mont, expected ) do { \ #define bigint_montgomery_ok( modulus, mont, expected ) do { \
static const uint8_t modulus_raw[] = modulus; \ static const uint8_t modulus_raw[] = modulus; \
static const uint8_t mont_raw[] = mont; \ static const uint8_t mont_raw[] = mont; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test modulus_test = \
unsigned int size = \ { modulus_raw, sizeof ( modulus_raw ) }; \
bigint_required_size ( sizeof ( modulus_raw ) ); \ static struct bigint_test mont_test = \
bigint_t ( size ) modulus_temp; \ { mont_raw, sizeof ( mont_raw ) }; \
bigint_t ( 2 * size ) mont_temp; \ static struct bigint_test expected_test = \
bigint_t ( size ) result_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
{} /* Fix emacs alignment */ \ bigint_montgomery_okx ( &modulus_test, &mont_test, \
\ &expected_test, __FILE__, __LINE__ ); \
assert ( ( sizeof ( modulus_raw ) % \
sizeof ( bigint_element_t ) ) == 0 ); \
bigint_init ( &modulus_temp, modulus_raw, \
sizeof ( modulus_raw ) ); \
bigint_init ( &mont_temp, mont_raw, sizeof ( mont_raw ) ); \
DBG ( "Montgomery:\n" ); \
DBG_HDA ( 0, &modulus_temp, sizeof ( modulus_temp ) ); \
DBG_HDA ( 0, &mont_temp, sizeof ( mont_temp ) ); \
bigint_montgomery ( &modulus_temp, &mont_temp, &result_temp ); \
DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \
bigint_done ( &result_temp, result_raw, \
sizeof ( result_raw ) ); \
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**
@@ -658,45 +783,56 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
* @v modulus Big integer modulus * @v modulus Big integer modulus
* @v exponent Big integer exponent * @v exponent Big integer exponent
* @v expected Big integer expected result * @v expected Big integer expected result
* @v file Test code file
* @v line Test code line
*/ */
static void bigint_mod_exp_okx ( struct bigint_test *base,
struct bigint_test *modulus,
struct bigint_test *exponent,
struct bigint_test *expected,
const char *file, unsigned int line ) {
uint8_t result_raw[ expected->len ];
unsigned int size = bigint_required_size ( base->len );
unsigned int exponent_size = bigint_required_size ( exponent->len );
bigint_t ( size ) base_temp;
bigint_t ( size ) modulus_temp;
bigint_t ( exponent_size ) exponent_temp;
bigint_t ( size ) result_temp;
size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp );
uint8_t tmp[tmp_len];
assert ( bigint_size ( &modulus_temp ) == bigint_size ( &base_temp ) );
assert ( bigint_size ( &modulus_temp ) ==
bigint_size ( &result_temp ) );
bigint_init ( &base_temp, base->raw, base->len );
bigint_init ( &modulus_temp, modulus->raw, modulus->len );
bigint_init ( &exponent_temp, exponent->raw, exponent->len );
DBG ( "Modular exponentiation: 0x%s", bigint_ntoa ( &base_temp ) );
DBG ( " ^ 0x%s", bigint_ntoa ( &exponent_temp ) );
bigint_mod_exp ( &base_temp, &modulus_temp, &exponent_temp,
&result_temp, tmp );
DBG ( " = 0x%s", bigint_ntoa ( &result_temp ) );
DBG ( " (mod 0x%s)\n", bigint_ntoa ( &modulus_temp ) );
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );
okx ( memcmp ( result_raw, expected->raw, sizeof ( result_raw ) ) == 0,
file, line );
}
#define bigint_mod_exp_ok( base, modulus, exponent, expected ) do { \ #define bigint_mod_exp_ok( base, modulus, exponent, expected ) do { \
static const uint8_t base_raw[] = base; \ static const uint8_t base_raw[] = base; \
static const uint8_t modulus_raw[] = modulus; \ static const uint8_t modulus_raw[] = modulus; \
static const uint8_t exponent_raw[] = exponent; \ static const uint8_t exponent_raw[] = exponent; \
static const uint8_t expected_raw[] = expected; \ static const uint8_t expected_raw[] = expected; \
uint8_t result_raw[ sizeof ( expected_raw ) ]; \ static struct bigint_test base_test = \
unsigned int size = \ { base_raw, sizeof ( base_raw ) }; \
bigint_required_size ( sizeof ( base_raw ) ); \ static struct bigint_test modulus_test = \
unsigned int exponent_size = \ { modulus_raw, sizeof ( modulus_raw ) }; \
bigint_required_size ( sizeof ( exponent_raw ) ); \ static struct bigint_test exponent_test = \
bigint_t ( size ) base_temp; \ { exponent_raw, sizeof ( exponent_raw ) }; \
bigint_t ( size ) modulus_temp; \ static struct bigint_test expected_test = \
bigint_t ( exponent_size ) exponent_temp; \ { expected_raw, sizeof ( expected_raw ) }; \
bigint_t ( size ) result_temp; \ bigint_mod_exp_okx ( &base_test, &modulus_test, &exponent_test, \
size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp ); \ &expected_test, __FILE__, __LINE__ ); \
uint8_t tmp[tmp_len]; \
{} /* Fix emacs alignment */ \
\
assert ( bigint_size ( &modulus_temp ) == \
bigint_size ( &base_temp ) ); \
assert ( bigint_size ( &modulus_temp ) == \
bigint_size ( &result_temp ) ); \
bigint_init ( &base_temp, base_raw, sizeof ( base_raw ) ); \
bigint_init ( &modulus_temp, modulus_raw, \
sizeof ( modulus_raw ) ); \
bigint_init ( &exponent_temp, exponent_raw, \
sizeof ( exponent_raw ) ); \
DBG ( "Modular exponentiation:\n" ); \
DBG_HDA ( 0, &base_temp, sizeof ( base_temp ) ); \
DBG_HDA ( 0, &modulus_temp, sizeof ( modulus_temp ) ); \
DBG_HDA ( 0, &exponent_temp, sizeof ( exponent_temp ) ); \
bigint_mod_exp ( &base_temp, &modulus_temp, &exponent_temp, \
&result_temp, tmp ); \
DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) ); \
bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\
\
ok ( memcmp ( result_raw, expected_raw, \
sizeof ( result_raw ) ) == 0 ); \
} while ( 0 ) } while ( 0 )
/** /**