]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[test] Update big integer tests to use okx()
authorMichael Brown <mcb30@ipxe.org>
Mon, 29 Dec 2025 13:18:10 +0000 (13:18 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 29 Dec 2025 13:18:10 +0000 (13:18 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/tests/bigint_test.c

index 496efdfe2649f3092dc49968d9458a6cab0e8667..4090494ae173a63f9a4efeee7026a14e9a6c161d 100644 (file)
@@ -40,6 +40,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Define inline big integer */
 #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 */
 
 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 expected         Big integer expected result
  * @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 {                \
        static const uint8_t addend_raw[] = addend;                     \
        static const uint8_t value_raw[] = value;                       \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       unsigned int msb = ( 8 * sizeof ( value_raw ) );                \
-       bigint_t ( size ) addend_temp;                                  \
-       bigint_t ( size ) value_temp;                                   \
-       int carry;                                                      \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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 )
+       static struct bigint_test addend_test =                         \
+               { addend_raw, sizeof ( addend_raw ) };                  \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_add_okx ( &addend_test, &value_test, &expected_test,     \
+                        overflow, __FILE__, __LINE__ );                \
+} while ( 0 )
 
 /**
  * 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 expected         Big integer expected result
  * @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,               \
                            underflow ) do {                            \
        static const uint8_t subtrahend_raw[] = subtrahend;             \
        static const uint8_t value_raw[] = value;                       \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) subtrahend_temp;                              \
-       bigint_t ( size ) value_temp;                                   \
-       int borrow;                                                     \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       assert ( bigint_size ( &subtrahend_temp ) ==                    \
-                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 );                                     \
+       static struct bigint_test subtrahend_test =                     \
+               { subtrahend_raw, sizeof ( subtrahend_raw ) };          \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_subtract_okx ( &subtrahend_test, &value_test,            \
+                             &expected_test, underflow,                \
+                             __FILE__, __LINE__ );                     \
        } while ( 0 )
 
 /**
@@ -322,30 +354,39 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v value            Big integer
  * @v expected         Big integer expected result
  * @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 {                     \
        static const uint8_t value_raw[] = value;                       \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       unsigned int msb = ( 8 * sizeof ( value_raw ) );                \
-       bigint_t ( size ) value_temp;                                   \
-       int out;                                                        \
-       {} /* 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 );                                              \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_shl_okx ( &value_test, &expected_test, bit,              \
+                        __FILE__, __LINE__ );                          \
        } while ( 0 )
 
 /**
@@ -354,27 +395,36 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v value            Big integer
  * @v expected         Big integer expected result
  * @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 {                     \
        static const uint8_t value_raw[] = value;                       \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) value_temp;                                   \
-       int out;                                                        \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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 );                                              \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_shr_okx ( &value_test, &expected_test, bit,              \
+                        __FILE__, __LINE__ );                          \
        } while ( 0 )
 
 /**
@@ -382,21 +432,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  *
  * @v value            Big integer
  * @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 {                      \
        static const uint8_t value_raw[] = value;                       \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) value_temp;                                   \
-       int is_zero;                                                    \
-       {} /* 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) ) );                     \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       bigint_is_zero_okx ( &value_test, expected,                     \
+                            __FILE__, __LINE__ );                      \
        } while ( 0 )
 
 /**
@@ -405,29 +461,37 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v value            Big integer
  * @v reference                Reference big integer
  * @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 {            \
        static const uint8_t value_raw[] = value;                       \
        static const uint8_t reference_raw[] = reference;               \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) value_temp;                                   \
-       bigint_t ( size ) reference_temp;                               \
-       int is_geq;                                                     \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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) ) );                      \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       static struct bigint_test reference_test =                      \
+               { reference_raw, sizeof ( reference_raw ) };            \
+       bigint_is_geq_okx ( &value_test, &reference_test, expected,     \
+                           __FILE__, __LINE__ );                       \
        } while ( 0 )
 
 /**
@@ -436,22 +500,28 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v value            Big integer
  * @v bit              Bit to test
  * @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 {              \
        static const uint8_t value_raw[] = value;                       \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) value_temp;                                   \
-       int bit_is_set;                                                 \
-       {} /* 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) ) );                  \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       bigint_bit_is_set_okx ( &value_test, bit, expected,             \
+                               __FILE__, __LINE__ );                   \
        } while ( 0 )
 
 /**
@@ -459,21 +529,27 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  *
  * @v value            Big integer
  * @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 {                  \
        static const uint8_t value_raw[] = value;                       \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( value_raw ) );          \
-       bigint_t ( size ) value_temp;                                   \
-       int max_set_bit;                                                \
-       {} /* 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) );                               \
+       static struct bigint_test value_test =                          \
+               { value_raw, sizeof ( value_raw ) };                    \
+       bigint_max_set_bit_okx ( &value_test, expected,                 \
+                                __FILE__, __LINE__ );                  \
        } 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 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 {                           \
        static const uint8_t first_raw[] = first;                       \
        static const uint8_t second_raw[] = second;                     \
-       uint8_t temp[ sizeof ( first_raw ) ];                           \
-       unsigned int size = bigint_required_size ( sizeof ( temp) );    \
-       bigint_t ( size ) first_temp;                                   \
-       bigint_t ( size ) second_temp;                                  \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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 );       \
+       static struct bigint_test first_test =                          \
+               { first_raw, sizeof ( first_raw ) };                    \
+       static struct bigint_test second_test =                         \
+               { second_raw, sizeof ( second_raw ) };                  \
+       bigint_swap_okx ( &first_test, &second_test,                    \
+                         __FILE__, __LINE__ );                         \
        } while ( 0 )
 
 /**
@@ -518,38 +605,49 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v multiplicand     Big integer to be multiplied
  * @v multiplier       Big integer to be multiplied
  * @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 {  \
        static const uint8_t multiplicand_raw[] = multiplicand;         \
        static const uint8_t multiplier_raw[] = multiplier;             \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int multiplicand_size =                                \
-               bigint_required_size ( sizeof ( multiplicand_raw ) );   \
-       unsigned int multiplier_size =                                  \
-               bigint_required_size ( sizeof ( multiplier_raw ) );     \
-       bigint_t ( multiplicand_size ) multiplicand_temp;               \
-       bigint_t ( multiplier_size ) multiplier_temp;                   \
-       bigint_t ( multiplicand_size + multiplier_size ) result_temp;   \
-       {} /* 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 );                   \
+       static struct bigint_test multiplicand_test =                   \
+               { multiplicand_raw, sizeof ( multiplicand_raw ) };      \
+       static struct bigint_test multiplier_test =                     \
+               { multiplier_raw, sizeof ( multiplier_raw ) };          \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_multiply_okx ( &multiplicand_test, &multiplier_test,     \
+                             &expected_test, __FILE__, __LINE__ );     \
        } while ( 0 )
 
 /**
@@ -557,31 +655,40 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  *
  * @v modulus          Big integer modulus
  * @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 {                     \
        static const uint8_t modulus_raw[] = modulus;                   \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( modulus_raw ) );        \
-       bigint_t ( size ) modulus_temp;                                 \
-       bigint_t ( size ) result_temp;                                  \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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 );                   \
+       static struct bigint_test modulus_test =                        \
+               { modulus_raw, sizeof ( modulus_raw ) };                \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_reduce_okx ( &modulus_test, &expected_test,              \
+                           __FILE__, __LINE__ );                       \
        } while ( 0 )
 
 /**
@@ -589,30 +696,38 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  *
  * @v invertend                Big integer to be inverted
  * @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 {               \
        static const uint8_t invertend_raw[] = invertend;               \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t inverse_raw[ sizeof ( expected_raw ) ];                 \
-       unsigned int invertend_size =                                   \
-               bigint_required_size ( sizeof ( invertend_raw ) );      \
-       unsigned int inverse_size =                                     \
-               bigint_required_size ( sizeof ( inverse_raw ) );        \
-       bigint_t ( invertend_size ) invertend_temp;                     \
-       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 );                  \
+       static struct bigint_test invertend_test =                      \
+               { invertend_raw, sizeof ( invertend_raw ) };            \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_mod_invert_okx ( &invertend_test, &expected_test,        \
+                               __FILE__, __LINE__ );                   \
        } while ( 0 )
 
 /**
@@ -621,34 +736,44 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v modulus          Big integer modulus
  * @v mont             Big integer Montgomery product
  * @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 {           \
        static const uint8_t modulus_raw[] = modulus;                   \
        static const uint8_t mont_raw[] = mont;                         \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( modulus_raw ) );        \
-       bigint_t ( size ) modulus_temp;                                 \
-       bigint_t ( 2 * size ) mont_temp;                                \
-       bigint_t ( size ) result_temp;                                  \
-       {} /* Fix emacs alignment */                                    \
-                                                                       \
-       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 );                   \
+       static struct bigint_test modulus_test =                        \
+               { modulus_raw, sizeof ( modulus_raw ) };                \
+       static struct bigint_test mont_test =                           \
+               { mont_raw, sizeof ( mont_raw ) };                      \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_montgomery_okx ( &modulus_test, &mont_test,              \
+                               &expected_test, __FILE__, __LINE__ );   \
        } while ( 0 )
 
 /**
@@ -658,45 +783,56 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
  * @v modulus          Big integer modulus
  * @v exponent         Big integer exponent
  * @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 {    \
        static const uint8_t base_raw[] = base;                         \
        static const uint8_t modulus_raw[] = modulus;                   \
        static const uint8_t exponent_raw[] = exponent;                 \
        static const uint8_t expected_raw[] = expected;                 \
-       uint8_t result_raw[ sizeof ( expected_raw ) ];                  \
-       unsigned int size =                                             \
-               bigint_required_size ( sizeof ( base_raw ) );           \
-       unsigned int exponent_size =                                    \
-               bigint_required_size ( sizeof ( exponent_raw ) );       \
-       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];                                           \
-       {} /* 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 );                   \
+       static struct bigint_test base_test =                           \
+               { base_raw, sizeof ( base_raw ) };                      \
+       static struct bigint_test modulus_test =                        \
+               { modulus_raw, sizeof ( modulus_raw ) };                \
+       static struct bigint_test exponent_test =                       \
+               { exponent_raw, sizeof ( exponent_raw ) };              \
+       static struct bigint_test expected_test =                       \
+               { expected_raw, sizeof ( expected_raw ) };              \
+       bigint_mod_exp_okx ( &base_test, &modulus_test, &exponent_test, \
+                            &expected_test, __FILE__, __LINE__ );      \
        } while ( 0 )
 
 /**