Add unit tests for the new function mbedtls_mpi_core_mla() in bignum_new.c
The test cases use the following MPI values: 0 1 fffe ffffffff 100000000 20000000000000 ffffffffffffffff 10000000000000000 1234567890abcdef0 fffffffffffffffffefefefefefefefe 100000000000000000000000000000000 1234567890abcdef01234567890abcdef0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0 4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b and the following scalars. The .data files include two sets of results (final accumulator and carry) for the cases sizeof(mbedtls_mpi_uint) == 4 or 8. 0 3 fe ff ffff 10000 ffffffff 100000000 7f7f7f7f7f7f7f7f 8000000000000000 fffffffffffffffe The lines in the .data file were generated by the following script #!/usr/bin/env perl # # mpi-test-core-mla.pl - generate/run MPI tests in Perl for mbedtls_mpi_core_mla() # use strict; use warnings; use Math::BigInt; use sort 'stable'; my @mla_mpis = qw( 0 1 fffe ffffffff 100000000 20000000000000 ffffffffffffffff 10000000000000000 1234567890abcdef0 fffffffffffffffffefefefefefefefe 100000000000000000000000000000000 1234567890abcdef01234567890abcdef0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0 4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b ); my @mla_scalars = qw( 0 3 fe ff ffff 10000 ffffffff 100000000 7f7f7f7f7f7f7f7f 8000000000000000 fffffffffffffffe ); my @mla_full_mpis = qw( 0 1 3 f fe ff 100 ff00 fffe ffff 10000 fffffffe ffffffff 100000000 1f7f7f7f7f7f7f 8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff 10000000000000000 1234567890abcdef0 fffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffe ffffffffffffffffffffffffffffffff 100000000000000000000000000000000 1234567890abcdef01234567890abcdef0 fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 10000000000000000000000000000000000000000000000000000000000000000 1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0 4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b ); my @mla_full_scalars = qw( 0 1 3 f fe ff 100 ff00 fffe ffff 10000 fffffffe ffffffff 100000000 8000000000000000 fefefefefefefefe fffffffffffffffe ffffffffffffffff ); generate_tests(); sub generate_tests { generate_mbedtls_mpi_core_mla(); } sub generate_mbedtls_mpi_core_mla { my $sub_name = (caller(0))[3]; # e.g. main::generate_mbedtls_mpi_sub_mpi my ($ignore, $test_name) = split("main::generate_", $sub_name); my @cases = (); for my $ah (@mla_mpis) { for my $bh (@mla_mpis) { for my $ch (@mla_scalars) { # a += b * c (c is scalar) # a_len >= b_len. need carry out. my $a = Math::BigInt->from_hex($ah); my $b = Math::BigInt->from_hex($bh); my $c = Math::BigInt->from_hex($ch); my $max = ($a > $b) ? $a : $b; my $bound4 = bound_mpi4($max); my $bound8 = bound_mpi8($max); my $r = $a + $b * $c; my ($r4, $cy4) = ($r->copy(), 0); my ($r8, $cy8) = ($r->copy(), 0); ($cy4, $r4) = $r4->bdiv($bound4); ($cy8, $r8) = $r8->bdiv($bound8); my $rh4 = $r4->to_hex(); my $rh8 = $r8->to_hex(); my $cyh4 = $cy4->to_hex(); my $cyh8 = $cy8->to_hex(); # If the scalar c is too big for 1 x 4-byte MPI, we can only run this test on a system with 8-byte MPIs my $depends = mpi4s($c) > 1 ? "MBEDTLS_HAVE_INT64" : ""; my $desc = "$test_name #NUMBER: 0x$ah + 0x$bh * 0x$ch = (0x$rh4, carry 0x$cyh4)/(0x$rh8, carry 0x$cyh8)EXPLAIN"; my $case = output($test_name, str($ah), str($bh), str($ch), str($rh4), str($cyh4), str($rh8), str($cyh8)); push(@cases, [$case, $desc, $depends]); } } } output_cases(" (for when sizeof(mbedtls_mpi_uint) == 4/8)", @cases); } sub output_cases { my ($explain, @cases) = @_; my $count = 1; for my $c (@cases) { my ($case, $desc, $dep) = @$c; $desc =~ s/NUMBER/$count/; $count++; if (defined($explain) && $desc =~ /EXPLAIN/) { $desc =~ s/EXPLAIN/$explain/; $explain = ""; } my $depends = ""; $depends = "depends_on:$dep\n" if defined($dep) && length($dep); print <<EOF; $desc $depends$case EOF } } # The first number (a power of 2) that won't fit in the number of MPIs # needed for the given number sub bound_mpi4 { my $one = Math::BigInt->new(1); # blsft modifies caller return $one->blsft(bits_mpi4($_[0])); } sub bound_mpi8 { my $one = Math::BigInt->new(1); # blsft modifies caller return $one->blsft(bits_mpi8($_[0])); } # How many bits (a multiple of 32) needed to store the specified number # when using 4-byte MPIs sub bits_mpi4 { return 32 * mpi4s($_[0]); } # How many bits (a multiple of 64) needed to store the specified number # when using 8-byte MPIs sub bits_mpi8 { return 64 * mpi8s($_[0]); } # How many 4-byte MPIs needed to store the specified number sub mpi4s { my ($n) = @_; my $h = $n->to_hex(); return int((length($h) + 7) / 8); } # How many 8-byte MPIs needed to store the specified number sub mpi8s { my ($n) = @_; my $h = $n->to_hex(); return int((length($h) + 15) / 16); } sub output { #run_test(@_); return join(":", @_); } sub str { return '"' . $_[0] . '"'; } Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
parent
2a65b85928
commit
659c84add9
File diff suppressed because it is too large
Load Diff
@ -1903,6 +1903,94 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void mbedtls_mpi_core_mla( char * input_d, char * input_s, char * input_b,
|
||||
char * input_X4, char * input_cy4,
|
||||
char * input_X8, char * input_cy8 )
|
||||
{
|
||||
/* We are testing d += s * b; d, s are MPIs, b is a scalar.
|
||||
*
|
||||
* However, we encode b as an MPI in the .data file for ease of handling.
|
||||
*
|
||||
* We also have the different results for sizeof(mbedtls_mpi_uint) == 4 or 8.
|
||||
*/
|
||||
mbedtls_mpi d, s, b, X4, X8, cy4, cy8;
|
||||
mbedtls_mpi_uint *da = NULL;
|
||||
mbedtls_mpi_uint *Xa = NULL;
|
||||
|
||||
mbedtls_mpi_init( &d );
|
||||
mbedtls_mpi_init( &s );
|
||||
mbedtls_mpi_init( &b );
|
||||
mbedtls_mpi_init( &X4 );
|
||||
mbedtls_mpi_init( &X8 );
|
||||
mbedtls_mpi_init( &cy4 );
|
||||
mbedtls_mpi_init( &cy8 );
|
||||
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &d, input_d ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &s, input_s ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &b, input_b ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &X4, input_X4 ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &cy4, input_cy4 ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &X8, input_X8 ), 0 );
|
||||
TEST_EQUAL( mbedtls_test_read_mpi( &cy8, input_cy8 ), 0 );
|
||||
|
||||
/* The MPI encoding of scalar b must be only 1 limb */
|
||||
TEST_EQUAL( b.n, 1 );
|
||||
|
||||
/* We only need to work with X4 or X8, and cy4 or cy8, depending on sizeof(mbedtls_mpi_uint) */
|
||||
mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
|
||||
mbedtls_mpi *cy = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &cy4 : &cy8;
|
||||
|
||||
/* The carry should only have one limb */
|
||||
TEST_EQUAL( cy->n, 1 );
|
||||
|
||||
/* All of the inputs are +ve (or zero) */
|
||||
TEST_EQUAL( d.s, 1 );
|
||||
TEST_EQUAL( s.s, 1 );
|
||||
TEST_EQUAL( b.s, 1 );
|
||||
TEST_EQUAL( X->s, 1 );
|
||||
TEST_EQUAL( cy->s, 1 );
|
||||
|
||||
/* Get the (max) number of limbs we will need */
|
||||
size_t limbs = ( d.n < s.n ) ? s.n : d.n;
|
||||
|
||||
/* The result shouldn't have more limbs than the longest input */
|
||||
TEST_ASSERT( X->n <= limbs );
|
||||
|
||||
/* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
|
||||
da = mbedtls_calloc( limbs, sizeof(mbedtls_mpi_uint) );
|
||||
Xa = mbedtls_calloc( limbs, sizeof(mbedtls_mpi_uint) );
|
||||
|
||||
TEST_ASSERT( da != NULL );
|
||||
TEST_ASSERT( Xa != NULL );
|
||||
|
||||
/* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
|
||||
* processed by mbedtls_mpi_core_add_if()) are little endian, we can just
|
||||
* copy what we have as long as MSBs are 0 (which they are from calloc())
|
||||
*/
|
||||
memcpy( da, d.p, d.n * sizeof(mbedtls_mpi_uint) );
|
||||
memcpy( Xa, X->p, X->n * sizeof(mbedtls_mpi_uint) );
|
||||
|
||||
/* 1a) d += s * b => we should get the correct carry */
|
||||
TEST_EQUAL( mbedtls_mpi_core_mla( da, limbs, s.p, s.n, *b.p ), *cy->p );
|
||||
|
||||
/* 1b) d += s * b => we should get the correct result */
|
||||
TEST_EQUAL( memcmp( da, Xa, limbs * sizeof(mbedtls_mpi_uint) ), 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_free( da );
|
||||
mbedtls_free( Xa );
|
||||
|
||||
mbedtls_mpi_free( &cy4 );
|
||||
mbedtls_mpi_free( &cy8 );
|
||||
mbedtls_mpi_free( &X4 );
|
||||
mbedtls_mpi_free( &X8 );
|
||||
mbedtls_mpi_free( &b );
|
||||
mbedtls_mpi_free( &s );
|
||||
mbedtls_mpi_free( &d );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
|
||||
void mpi_selftest( )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user