Make a public version of mpi_montg_init() in bignum_new.c and add unit tests

The unit tests were created by capturing runs of the existing function during
execution of existing unit tests.

Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
Tom Cosgrove 2022-08-17 06:17:00 +01:00
parent 659c84add9
commit 79b70f6394
5 changed files with 108 additions and 11 deletions

View File

@ -1550,16 +1550,7 @@ int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_
*/ */
static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
{ {
mbedtls_mpi_uint x, m0 = N->p[0]; *mm = mbedtls_mpi_montg_init( N->p[0] );
unsigned int i;
x = m0;
x += ( ( m0 + 2 ) & 4 ) << 1;
for( i = biL; i >= 8; i /= 2 )
x *= ( 2 - ( m0 * x ) );
*mm = ~x + 1;
} }
/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) /** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)

View File

@ -171,7 +171,7 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A,
* This must be odd and have exactly \p n limbs. * 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[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. * \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. * \param[in,out] T Temporary storage of size at least 2*n+1 limbs.
* Its initial content is unused and * Its initial content is unused and
* its final content is indeterminate. * its final content is indeterminate.
@ -182,6 +182,17 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *N, size_t n, const mbedtls_mpi_uint *N, size_t n,
mbedtls_mpi_uint mm, mbedtls_mpi_uint *T ); mbedtls_mpi_uint mm, mbedtls_mpi_uint *T );
/**
* \brief Calculate initialisation value for fast Montgomery modular
* multiplication
*
* \param m0 The least-significant mbedtls_mpi_uint from the modulus, which
* must be odd
*
* \return The initialisation value for fast Montgomery modular multiplication
*/
mbedtls_mpi_uint mbedtls_mpi_montg_init( mbedtls_mpi_uint m0 );
/** /**
* \brief Perform a known-size multiply accumulate operation: d += b * s * \brief Perform a known-size multiply accumulate operation: d += b * s
* *

View File

@ -56,6 +56,21 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X,
(void) mbedtls_mpi_core_add_if( X, N, n, ( carry < borrow ) ); (void) mbedtls_mpi_core_add_if( X, N, n, ( carry < borrow ) );
} }
/*
* Fast Montgomery initialization (thanks to Tom St Denis).
*/
mbedtls_mpi_uint mbedtls_mpi_montg_init( mbedtls_mpi_uint m0 )
{
mbedtls_mpi_uint x = m0;
x += ( ( m0 + 2 ) & 4 ) << 1;
for( unsigned int i = biL; i >= 8; i /= 2 )
x *= ( 2 - ( m0 * x ) );
return( ~x + 1 );
}
mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *d, size_t d_len, mbedtls_mpi_uint mbedtls_mpi_core_mla( mbedtls_mpi_uint *d, size_t d_len,
const mbedtls_mpi_uint *s, size_t s_len, const mbedtls_mpi_uint *s, size_t s_len,
mbedtls_mpi_uint b ) mbedtls_mpi_uint b )

View File

@ -15263,6 +15263,51 @@ mbedtls_mpi_core_mla #2475: 0x4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf0
depends_on:MBEDTLS_HAVE_INT64 depends_on:MBEDTLS_HAVE_INT64
mbedtls_mpi_core_mla:"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b":"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b":"fffffffffffffffe":"4b71c8d5ebfa2f2e09870fa7894927c74437b32cab898402894ea85396040a2f41773a0aa5fbecf58b7b0751c11416637d469d67bea403f60c717912d8848f999b08b5670e44a96fc36349286249a27f89015f8750f0a073902e9eae744ed40ca8eed71f249ab99c19747e10bf625cfda5d90e33a22f8d96a6fe13fdaf894ed5":"4df72d07b":"4b71c8d5ebfa2f2e09870fa7894927c74437b32cab898402894ea85396040a2f41773a0aa5fbecf58b7b0751c11416637d469d67bea403f60c717912d8848f999b08b5670e44a96fc36349286249a27f89015f8750f0a073902e9eae744ed40ca8eed71f249ab99c19747e10bf625cfda5d90e33a22f8d96a6fe13fdaf894ed5":"4df72d07b" mbedtls_mpi_core_mla:"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b":"4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b":"fffffffffffffffe":"4b71c8d5ebfa2f2e09870fa7894927c74437b32cab898402894ea85396040a2f41773a0aa5fbecf58b7b0751c11416637d469d67bea403f60c717912d8848f999b08b5670e44a96fc36349286249a27f89015f8750f0a073902e9eae744ed40ca8eed71f249ab99c19747e10bf625cfda5d90e33a22f8d96a6fe13fdaf894ed5":"4df72d07b":"4b71c8d5ebfa2f2e09870fa7894927c74437b32cab898402894ea85396040a2f41773a0aa5fbecf58b7b0751c11416637d469d67bea403f60c717912d8848f999b08b5670e44a96fc36349286249a27f89015f8750f0a073902e9eae744ed40ca8eed71f249ab99c19747e10bf625cfda5d90e33a22f8d96a6fe13fdaf894ed5":"4df72d07b"
mbedtls_mpi_montg_init #1
mbedtls_mpi_montg_init:"000000000000001d":"cb08d3dcb08d3dcb"
mbedtls_mpi_montg_init #2
mbedtls_mpi_montg_init:"0000000000000009":"71c71c71c71c71c7"
mbedtls_mpi_montg_init #3
mbedtls_mpi_montg_init:"000000000001869f":"34d76bc8e5e3eaa1"
mbedtls_mpi_montg_init #4
mbedtls_mpi_montg_init:"00000000000080000000000000000001":"ffffffffffffffff"
mbedtls_mpi_montg_init #5
mbedtls_mpi_montg_init:"0000000000a1ffffffffffffffffffff":"0000000000000001"
mbedtls_mpi_montg_init #6
mbedtls_mpi_montg_init:"00000000000257ffffffffffffffffff":"0000000000000001"
mbedtls_mpi_montg_init #7
mbedtls_mpi_montg_init:"b91ba63180c726fbd57786f27f1ede97a3b40c59a7fcfb5898f076e9af57028d":"32edc7e1ac2e6fbb"
mbedtls_mpi_montg_init #8
mbedtls_mpi_montg_init:"b3a119602ee213cde28581ecd892e0f592a338655dce4ca88054b3d124d0e561":"e41cfb909805815f"
mbedtls_mpi_montg_init #9
mbedtls_mpi_montg_init:"0284139ea19c139ebe09a8111926aaa39a2c2be12ed487a809d3cb5bc55854725b4cdcb5734c58f90b2f60d99cc1950cdbc8d651793e93c9c6f0ead752500a32c56c62082912b66132b2a6aa42ada923e1ad22ceb7ba0123":"c02e2164b293c975"
mbedtls_mpi_montg_init #10
mbedtls_mpi_montg_init:"00000000000000011a9351d2d32ccd568e75bf8b4ebbb2a36be691b55832edac662ff79803df8af525fba453068be16ac3920bcc1b468f8f7fe786e0fa4ecbabcad31e5e3b05def802eb8600deaf11ef452487db878df20a80606e4bb6a163b83895d034cc8b53dbcd005be42ffdd2ce99bed06089a0b79d":"ffec8978c055794b"
mbedtls_mpi_montg_init #11
mbedtls_mpi_montg_init:"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":"7b07a0b0379b9135"
mbedtls_mpi_montg_init #12
mbedtls_mpi_montg_init:"00000007a364ab3de755f924642bd5273524234f78395da1ed9098f39af4fe248288b0cb7f1c27214588969479d7dc9f0d327b5544dd4c095aa1fa271df421fe9ee460855cc8423d223e2c85dc793f6babdca7fc804ea1f408f867db053bfd98c45085ea5d805c78d2863bacdfcaf4c6147ebb74a9056045074785714c0b84ed":"8f54b233c070871b"
mbedtls_mpi_montg_init #13
mbedtls_mpi_montg_init:"e2df85c83ee8463b3af26805791cc0b1ba1af89564e887a63d5ba18ea72fb593b664cf8ace78241ea3109b7644510e02324a5c1e9a85daada3c383759d7678ce8d8886b51a3237dc84b543de4f843c77fc77ba08ef90e7e96ba622478f6b96daa3e9b8511f36279fb0120ef93bad2090e7878346fe4ae29ad61be48b6835e8407d0849422e05c7a4d1e02322f2675056d73d4c5a1ab376bfaccfd61ff7d64b715c9525a7ed8dcda1144f8722c30d12ba3d95221d897edc825a1598a645e2c457":"b777a905d9239899"
mbedtls_mpi_montg_init #14
mbedtls_mpi_montg_init:"baea2d65939296fc2536f18f2a4042a741f33088ecd5000e76c67a466e7a1e696f8ee9a15497168b3a2b597799dc9475909ebbc64b96f233430c6aa3e4a86e9352b0230081502da09ef41dc0a164a1c6a31bd1338e359a28c78ef50c89f06a46b46a27d7245bba7468334625687201d62ef084de4c5190dfe70c14a318204492de6edd138e14e9337fda739dcadd0212302db7770de28d8c5c79b6a6b5f927e656e157cd7e41204ec39731fe3608ecd4b885a194647fe7f02b74639cc76cdf03":"827ef0810f71fc55"
mbedtls_mpi_montg_init #15
mbedtls_mpi_montg_init:"bf741f75e28a44e271cf43e68dbadd23c72d2f2e1fc78a6d6aaaadf2ccbf26c9a232aff5b3f3f29323b114f3018144ed9438943e07820e222137d3bb229b61671e61f75f6021a26436df9e669929fa392df021f105d2fce0717468a522018721ccde541b9a7b558128419f457ef33a5753f00c20c2d709727eef6278c55b278b10abe1d13e538514128b5dcb7bfd015e0fdcb081555071813974135d5ab5000630a94f5b0f4021a504ab4f3df2403e6140b9939f8bbe714635f5cff10744be03":"aab901da57bba355"
MPI Selftest MPI Selftest
depends_on:MBEDTLS_SELF_TEST depends_on:MBEDTLS_SELF_TEST
mpi_selftest: mpi_selftest:

View File

@ -1991,6 +1991,41 @@ exit:
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */
void mbedtls_mpi_montg_init( char * input_N, char * input_mm )
{
mbedtls_mpi N, mm;
mbedtls_mpi_init( &N );
mbedtls_mpi_init( &mm );
TEST_EQUAL( mbedtls_test_read_mpi( &N, input_N ), 0 );
TEST_EQUAL( mbedtls_test_read_mpi( &mm, input_mm ), 0 );
/* The MPI encoding of mm should be 1 limb (sizeof(mbedtls_mpi_uint) == 8) or
* 2 limbs (sizeof(mbedtls_mpi_uint) == 4).
*
* The data file contains the expected result for sizeof(mbedtls_mpi_uint) == 8;
* for sizeof(mbedtls_mpi_uint) == 4 it's just the LSW of this.
*/
TEST_ASSERT( mm.n == 1 || mm.n == 2);
/* All of the inputs are +ve (or zero) */
TEST_EQUAL( N.s, 1 );
TEST_EQUAL( mm.s, 1 );
/* mbedtls_mpi_montg_init() only returns a result, no error possible */
mbedtls_mpi_uint result = mbedtls_mpi_montg_init( N.p[0] );
/* Check we got the correct result */
TEST_EQUAL( result, mm.p[0] );
exit:
mbedtls_mpi_free( &N );
mbedtls_mpi_free( &mm );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void mpi_selftest( ) void mpi_selftest( )
{ {