Skip to content

Commit

Permalink
Add unit tests for the new functions in bignum_new.c
Browse files Browse the repository at this point in the history
That is, mbedtls_mpi_core_add_if(), mbedtls_mpi_core_sub(), mbedtls_mpi_core_mla()
and mbedtls_mpi_core_montmul().

Also add unit tests for mpi_montg_init() (and rename it with mbedtls_ prefix).

The tests for mbedtls_mpi_core_montmul() are also used to test the existing
mpi_montmul() function (which too is renamed with mbedtls_ prefix). Some of these
are replays of captured invocations during unit test runs. Others are generated.
They use a mixture of primes and odd numbers for N, with four randomly-generated
cases for each N.

The test cases for mbedtls_mpi_core_add_if() and mbedtls_mpi_core_sub() use
the following MPI values.

For mbedtls_mpi_core_add_if() the .data file only includes those (a, b) values
where a <= b, and gives the sum unconditionally; the test code exercises a >= b
and cond == 0 using these values. The .data file gives two values for the carry out,
which are for when sizeof(mbedtls_mpi_uint) == 4 or 8.

For mbedtls_mpi_core_sub() the .data file includes two results, for the cases when
sizeof(mbedtls_mpi_uint) == 4 or 8.

    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

The test cases for mbedtls_mpi_core_mla() use the following MPIs:

    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

Signed-off-by: Tom Cosgrove <[email protected]>
  • Loading branch information
tom-cosgrove-arm committed Aug 5, 2022
1 parent 7be6909 commit d0c1f31
Show file tree
Hide file tree
Showing 4 changed files with 13,896 additions and 40 deletions.
61 changes: 22 additions & 39 deletions library/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,9 +1760,11 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
}

/*
* Fast Montgomery initialization (thanks to Tom St Denis)
* Fast Montgomery initialization (thanks to Tom St Denis).
*
* Would be static, but we want to test it.
*/
static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
void mbedtls_mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
{
mbedtls_mpi_uint x, m0 = N->p[0];
unsigned int i;
Expand All @@ -1776,30 +1778,10 @@ static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
*mm = ~x + 1;
}

/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
*
* \param[in,out] A One of the numbers to multiply.
* It must have at least as many limbs as N
* (A->n >= N->n), and any limbs beyond n are ignored.
* On successful completion, A contains the result of
* the multiplication A * B * R^-1 mod N where
* R = (2^ciL)^n.
* \param[in] B One of the numbers to multiply.
* It must be nonzero and must not have more limbs than N
* (B->n <= N->n).
* \param[in] N The modulo. N must be odd.
* \param mm The value calculated by `mpi_montg_init(&mm, N)`.
* This is -N^-1 mod 2^ciL.
* \param[in,out] T A bignum for temporary storage.
* It must be at least twice the limb size of N plus 1
* (T->n >= 2 * N->n + 1).
* Its initial content is unused and
* its final content is indeterminate.
* Note that unlike the usual convention in the library
* for `const mbedtls_mpi*`, the content of T can change.
*/
static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
const mbedtls_mpi *T )
/* This too would be static, but is tested */
void mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B,
const mbedtls_mpi *N, mbedtls_mpi_uint mm,
const mbedtls_mpi *T )
{
size_t n, m;
mbedtls_mpi_uint *d;
Expand Down Expand Up @@ -1853,7 +1835,8 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
/*
* Montgomery reduction: A = A * R^-1 mod N
*
* See mpi_montmul() regarding constraints and guarantees on the parameters.
* See the doc for mbedtls_mpi_montmul() regarding constraints and guarantees on
* the parameters.
*/
static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Expand All @@ -1864,7 +1847,7 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
U.n = U.s = (int) z;
U.p = &z;

mpi_montmul( A, &U, N, mm, T );
mbedtls_mpi_montmul( A, &U, N, mm, T );
}

/**
Expand Down Expand Up @@ -1929,7 +1912,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
/*
* Init temps and window size
*/
mpi_montg_init( &mm, N );
mbedtls_mpi_montg_init( &mm, N );
mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
mbedtls_mpi_init( &Apos );
mbedtls_mpi_init( &WW );
Expand All @@ -1946,7 +1929,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
#endif

j = N->n + 1;
/* All W[i] and X must have at least N->n limbs for the mpi_montmul()
/* All W[i] and X must have at least N->n limbs for the mbedtls_mpi_montmul()
* and mpi_montred() calls later. Here we ensure that W[1] and X are
* large enough, and later we'll grow other W[i] to the same length.
* They must not be shrunk midway through this function!
Expand Down Expand Up @@ -1989,15 +1972,15 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
/* This should be a no-op because W[1] is already that large before
* mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
* in mpi_montmul() below, so let's make sure. */
* in mbedtls_mpi_montmul() below, so let's make sure. */
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
}
else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );

/* Note that this is safe because W[1] always has at least N->n limbs
* (it grew above and was preserved by mbedtls_mpi_copy()). */
mpi_montmul( &W[1], &RR, N, mm, &T );
mbedtls_mpi_montmul( &W[1], &RR, N, mm, &T );

/*
* X = R^2 * R^-1 mod N = R mod N
Expand All @@ -2016,7 +1999,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );

for( i = 0; i < wsize - 1; i++ )
mpi_montmul( &W[j], &W[j], N, mm, &T );
mbedtls_mpi_montmul( &W[j], &W[j], N, mm, &T );

/*
* W[i] = W[i - 1] * W[1]
Expand All @@ -2026,7 +2009,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );

mpi_montmul( &W[i], &W[1], N, mm, &T );
mbedtls_mpi_montmul( &W[i], &W[1], N, mm, &T );
}
}

Expand Down Expand Up @@ -2063,7 +2046,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
/*
* out of window, square X
*/
mpi_montmul( X, X, N, mm, &T );
mbedtls_mpi_montmul( X, X, N, mm, &T );
continue;
}

Expand All @@ -2081,13 +2064,13 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
* X = X^wsize R^-1 mod N
*/
for( i = 0; i < wsize; i++ )
mpi_montmul( X, X, N, mm, &T );
mbedtls_mpi_montmul( X, X, N, mm, &T );

/*
* X = X * W[wbits] R^-1 mod N
*/
MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
mpi_montmul( X, &WW, N, mm, &T );
mbedtls_mpi_montmul( X, &WW, N, mm, &T );

state--;
nbits = 0;
Expand All @@ -2100,12 +2083,12 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
*/
for( i = 0; i < nbits; i++ )
{
mpi_montmul( X, X, N, mm, &T );
mbedtls_mpi_montmul( X, X, N, mm, &T );

wbits <<= 1;

if( ( wbits & ( one << wsize ) ) != 0 )
mpi_montmul( X, &W[1], N, mm, &T );
mbedtls_mpi_montmul( X, &W[1], N, mm, &T );
}

/*
Expand Down
35 changes: 34 additions & 1 deletion library/bignum_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* This must be odd and have exactly \p n limbs.
* \param[in] n The number of limbs in \p X, \p A, \p N.
* \param mm The Montgomery constant for \p N: -N^-1 mod 2^ciL.
* This can be calculated by `mpi_montg_init()`.
* This can be calculated by `mbedtls_mpi_montg_init()`.
* \param[in,out] T Temporary storage of size at least 2*n+1 limbs.
* Its initial content is unused and
* its final content is indeterminate.
Expand Down Expand Up @@ -123,4 +123,37 @@ mbedtls_mpi_uint mbedtls_mpi_core_add_if( mbedtls_mpi_uint *d,
size_t n,
unsigned cond );

/**
* \brief Calculate initialisation value for fast Montgomery modular
* multiplication
*
* \param mm Pointer to an mbedtls_mpi_uint to receive the result.
* \param N Little-endian presentation of the modulus, which must be odd.
*/
void mbedtls_mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N );

/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
*
* \param[in,out] A One of the numbers to multiply.
* It must have at least as many limbs as N
* (A->n >= N->n), and any limbs beyond n are ignored.
* On successful completion, A contains the result of
* the multiplication A * B * R^-1 mod N where
* R = (2^ciL)^n.
* \param[in] B One of the numbers to multiply.
* It must be nonzero and must not have more limbs than N
* (B->n <= N->n).
* \param[in] N The modulo. N must be odd.
* \param mm The value calculated by `mbedtls_mpi_montg_init(&mm, N)`.
* This is -N^-1 mod 2^ciL.
* \param[in,out] T A bignum for temporary storage.
* It must be at least twice the limb size of N plus 1
* (T->n >= 2 * N->n + 1).
* Its initial content is unused and
* its final content is indeterminate.
* Note that unlike the usual convention in the library
* for `const mbedtls_mpi*`, the content of T can change.
*/
void mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T );

#endif /* MBEDTLS_BIGNUM_CORE_H */
Loading

0 comments on commit d0c1f31

Please sign in to comment.