Merge pull request #6407 from minosgalanakis/minos/6017_add_montgomery_constant_squared

Bignum: Added pre-calculation of Montgomery constants
diff --git a/library/bignum_core.c b/library/bignum_core.c
index 0083729..963af5b 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -511,4 +511,18 @@
     mbedtls_ct_mpi_uint_cond_assign( AN_limbs, X, T, (unsigned char) ( carry ^ borrow ) );
 }
 
+int mbedtls_mpi_core_get_mont_r2_unsafe( mbedtls_mpi *X,
+                                         const mbedtls_mpi *N )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, N->n * 2 * biL ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( X, X, N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( X, N->n ) );
+
+cleanup:
+    return( ret );
+}
+
 #endif /* MBEDTLS_BIGNUM_C */
diff --git a/library/bignum_core.h b/library/bignum_core.h
index 56a3bf8..503bc1d 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -412,4 +412,22 @@
                                const mbedtls_mpi_uint *N, size_t AN_limbs,
                                mbedtls_mpi_uint mm, mbedtls_mpi_uint *T );
 
+/**
+ * \brief Calculate the square of the Montgomery constant. (Needed
+ *        for conversion and operations in Montgomery form.)
+ *
+ * \param[out] X  A pointer to the result of the calculation of
+ *                the square of the Montgomery constant:
+ *                2^{2*n*biL} mod N.
+ * \param[in]  N  Little-endian presentation of the modulus, which must be odd.
+ *
+ * \return        0 if successful.
+ * \return        #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space
+ *                to store the value of Montgomery constant squared.
+ * \return        #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero.
+ * \return        #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative.
+ */
+int mbedtls_mpi_core_get_mont_r2_unsafe( mbedtls_mpi *X,
+                                         const mbedtls_mpi *N );
+
 #endif /* MBEDTLS_BIGNUM_CORE_H */
diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function
index fb5fe3a..74ee27a 100644
--- a/tests/suites/test_suite_bignum_core.function
+++ b/tests/suites/test_suite_bignum_core.function
@@ -766,3 +766,72 @@
     mbedtls_mpi_free( &R );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_core_get_mont_r2_unsafe_neg(  )
+{
+    mbedtls_mpi N, RR;
+    mbedtls_mpi_init( &N );
+    mbedtls_mpi_init( &RR );
+    const char * n = "7ffffffffffffff1";
+
+    /* Test for zero divisor */
+    TEST_EQUAL( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO,
+               mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
+
+    /* Test for negative input */
+    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, n ) );
+    N.s = -1;
+    TEST_EQUAL( MBEDTLS_ERR_MPI_NEGATIVE_VALUE,
+               mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
+    N.s = 1;
+
+exit:
+    mbedtls_mpi_free( &N );
+    mbedtls_mpi_free( &RR );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_core_get_mont_r2_unsafe( char * input_N,
+                                  char * input_RR_X4,
+                                  char * input_RR_X8 )
+{
+    mbedtls_mpi N, RR, RR_REF;
+
+    /* Select the appropriate output */
+    char * input_rr = ( sizeof(mbedtls_mpi_uint) == 4 ) ? input_RR_X4: input_RR_X8;
+
+    mbedtls_mpi_init( &N );
+    mbedtls_mpi_init( &RR );
+    mbedtls_mpi_init( &RR_REF );
+
+    /* Read inputs */
+    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi( &RR_REF, input_rr ) );
+
+    /* All of the inputs are +ve (or zero) */
+    TEST_EQUAL( 1, N.s );
+    TEST_EQUAL( 1, RR_REF.s );
+
+    /* Test valid input */
+    TEST_EQUAL( 0, mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
+
+    /* Test that the moduli is odd */
+    TEST_EQUAL( N.p[0] ^ 1, N.p[0] - 1 );
+
+   /* Output is +ve (or zero) */
+    TEST_EQUAL( 1, RR_REF.s );
+
+    /* rr is updated to a valid pointer */
+    TEST_ASSERT( RR.p != NULL );
+
+    /* Calculated rr matches expected value */
+    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &RR, &RR_REF ) == 0 );
+
+exit:
+    mbedtls_mpi_free( &N );
+    mbedtls_mpi_free( &RR );
+    mbedtls_mpi_free( &RR_REF );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_bignum_core.misc.data b/tests/suites/test_suite_bignum_core.misc.data
index cb6fe42..a8fe9ab 100644
--- a/tests/suites/test_suite_bignum_core.misc.data
+++ b/tests/suites/test_suite_bignum_core.misc.data
@@ -328,3 +328,39 @@
 
 mbedtls_mpi_montg_init #15
 mpi_montg_init:"bf741f75e28a44e271cf43e68dbadd23c72d2f2e1fc78a6d6aaaadf2ccbf26c9a232aff5b3f3f29323b114f3018144ed9438943e07820e222137d3bb229b61671e61f75f6021a26436df9e669929fa392df021f105d2fce0717468a522018721ccde541b9a7b558128419f457ef33a5753f00c20c2d709727eef6278c55b278b10abe1d13e538514128b5dcb7bfd015e0fdcb081555071813974135d5ab5000630a94f5b0f4021a504ab4f3df2403e6140b9939f8bbe714635f5cff10744be03":"aab901da57bba355"
+
+mbedtls_mpi_core_get_mont_r2_unsafe_neg
+mpi_core_get_mont_r2_unsafe_neg:
+
+mbedtls_mpi_core_get_mont_r2_unsafe #1
+mpi_core_get_mont_r2_unsafe:"f":"1":"1"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #2
+mpi_core_get_mont_r2_unsafe:"fd":"ec":"24"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #3
+mpi_core_get_mont_r2_unsafe:"eeff99aa37":"a23bd6a686":"a23bd6a686"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #4
+mpi_core_get_mont_r2_unsafe:"eeff99aa11":"3308cb71":"3308cb71"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #5
+mpi_core_get_mont_r2_unsafe:"800000000005":"6400000000":"6400000000"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #6
+mpi_core_get_mont_r2_unsafe:"7fffffffffffffff":"4":"4"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #7
+mpi_core_get_mont_r2_unsafe:"80fe000a10000001":"5dbc6e833bad575a":"5dbc6e833bad575a"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #8
+mpi_core_get_mont_r2_unsafe:"25a55a46e5da99c71c7":"11637ce1347edeaf669":"1e455bf7451c05bc711"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #9
+mpi_core_get_mont_r2_unsafe:"314dc643fb763f2b8c0e2de00879":"1058ad82120c3a10196bb36229c1":"1058ad82120c3a10196bb36229c1"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #10
+mpi_core_get_mont_r2_unsafe:"8335616aed761f1f7f44e6bd49e807b82e3bf2bf11bfa63":"5d96a26447dca0cb7209c048f9e63e8dc623d67c8f44396":"5d96a26447dca0cb7209c048f9e63e8dc623d67c8f44396"
+
+mbedtls_mpi_core_get_mont_r2_unsafe #11
+mpi_core_get_mont_r2_unsafe:"d1cece570f2f991013f26dd5b03c4c5b65f97be5905f36cb4664f2c78ff80aa8135a4aaf57ccb8a0aca2f394909a74cef1ef6758a64d11e2c149c393659d124bfc94196f0ce88f7d7d567efa5a649e2deefaa6e10fdc3deac60d606bf63fc540ac95294347031aefd73d6a9ee10188aaeb7a90d920894553cb196881691cadc51808715a07e8b24fcb1a63df047c7cdf084dd177ba368c806f3d51ddb5d3898c863e687ecaf7d649a57a46264a582f94d3c8f2edaf59f77a7f6bdaf83c991e8f06abe220ec8507386fce8c3da84c6c3903ab8f3ad4630a204196a7dbcbd9bcca4e40ec5cc5c09938d49f5e1e6181db8896f33bb12e6ef73f12ec5c5ea7a8a337":"12d7243d92ebc8338221f6dcec8ad8a2ec64c10a98339c8721beb1cb79e629253a7aa35e25d5421e6c2b43ddc4310cf4443875c070a7a5a5cc2c4c3eefa8a133af2e477fb7bb5b5058c6120946a7f9f08f2fab51e2f243b9ba206d2bfd62e4ef647dda49100d7004794f28172be2d715905fbd2e9ab8588c774523c0e096b49b6855a10e5ce0d8498370949a29d71d293788bf10a71e2447d4b2f11959a72f7290e2950772d14c83f15532468745fa58a83fca8883b0b6169a27ec0cf922c4f39d283bb20fca5ff1de01d9c66b8a710108b951af634d56c843d9505bf2edd5a7b8f0b72a5c95672151e60075a78084e83fbe284617a90c74c8335cce38bb012e":"12d7243d92ebc8338221f6dcec8ad8a2ec64c10a98339c8721beb1cb79e629253a7aa35e25d5421e6c2b43ddc4310cf4443875c070a7a5a5cc2c4c3eefa8a133af2e477fb7bb5b5058c6120946a7f9f08f2fab51e2f243b9ba206d2bfd62e4ef647dda49100d7004794f28172be2d715905fbd2e9ab8588c774523c0e096b49b6855a10e5ce0d8498370949a29d71d293788bf10a71e2447d4b2f11959a72f7290e2950772d14c83f15532468745fa58a83fca8883b0b6169a27ec0cf922c4f39d283bb20fca5ff1de01d9c66b8a710108b951af634d56c843d9505bf2edd5a7b8f0b72a5c95672151e60075a78084e83fbe284617a90c74c8335cce38bb012e"