From 79b70f63947b0eb6ec09cfca6d130ce5ea9b5648 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 17 Aug 2022 06:17:00 +0100 Subject: [PATCH] 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 --- library/bignum.c | 11 +------ library/bignum_core.h | 13 +++++++- library/bignum_new.c | 15 ++++++++++ tests/suites/test_suite_mpi.data | 45 ++++++++++++++++++++++++++++ tests/suites/test_suite_mpi.function | 35 ++++++++++++++++++++++ 5 files changed, 108 insertions(+), 11 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 931d34df44..98bea731e5 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -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 ) { - mbedtls_mpi_uint x, m0 = 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; + *mm = mbedtls_mpi_montg_init( N->p[0] ); } /** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) diff --git a/library/bignum_core.h b/library/bignum_core.h index 77364670a0..02ac55d1b3 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -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. * \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. @@ -182,6 +182,17 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X, const mbedtls_mpi_uint *N, size_t n, 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 * diff --git a/library/bignum_new.c b/library/bignum_new.c index 024348ad4a..d275fe81f7 100644 --- a/library/bignum_new.c +++ b/library/bignum_new.c @@ -56,6 +56,21 @@ void mbedtls_mpi_core_montmul( mbedtls_mpi_uint *X, (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, const mbedtls_mpi_uint *s, size_t s_len, mbedtls_mpi_uint b ) diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index de7862e282..a7a074f63a 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -15263,6 +15263,51 @@ mbedtls_mpi_core_mla #2475: 0x4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf0 depends_on:MBEDTLS_HAVE_INT64 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 depends_on:MBEDTLS_SELF_TEST mpi_selftest: diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 20cc34465e..26d1553bae 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -1991,6 +1991,41 @@ exit: } /* 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 */ void mpi_selftest( ) {