Functions to convert raw residues to/from the modulus representation

Test cases will be generated automatically by a subsequent commit.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index fbd90bf..721efc8 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -176,6 +176,36 @@
 
 /* BEGIN MERGE SLOT 6 */
 
+int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
+    mbedtls_mpi_uint *X,
+    const mbedtls_mpi_mod_modulus *N )
+{
+    switch( N->int_rep )
+    {
+        case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+            return( mbedtls_mpi_mod_raw_to_mont_rep( X, N ) );
+        case MBEDTLS_MPI_MOD_REP_OPT_RED:
+            return( 0 );
+        default:
+            return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+}
+
+int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
+    mbedtls_mpi_uint *X,
+    const mbedtls_mpi_mod_modulus *N )
+{
+    switch( N->int_rep )
+    {
+        case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+            return( mbedtls_mpi_mod_raw_from_mont_rep( X, N ) );
+        case MBEDTLS_MPI_MOD_REP_OPT_RED:
+            return( 0 );
+        default:
+            return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+}
+
 int mbedtls_mpi_mod_raw_random( mbedtls_mpi_uint *X,
                                 mbedtls_mpi_uint min,
                                 const mbedtls_mpi_mod_modulus *N,
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
index 87e241f..dad060b 100644
--- a/library/bignum_mod_raw.h
+++ b/library/bignum_mod_raw.h
@@ -297,6 +297,40 @@
 
 /* BEGIN MERGE SLOT 6 */
 
+/** Convert an MPI from canonical representation (little-endian limb array)
+ * to the representation associated with the modulus.
+ *
+ * \param[in,out] X The limb array to convert.
+ *                  It must have as many limbs as \p N.
+ *                  It is converted in place.
+ *                  If this function returns an error, the content of \p X
+ *                  is unspecified.
+ * \param[in] N     The modulus structure.
+ *
+ *\ return          \c 0 if successful.
+ *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
+ */
+int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
+    mbedtls_mpi_uint *X,
+    const mbedtls_mpi_mod_modulus *N );
+
+/** Convert an MPI from the representation associated with the modulus
+ * to canonical representation (little-endian limb array).
+ *
+ * \param[in,out] X The limb array to convert.
+ *                  It must have as many limbs as \p N.
+ *                  It is converted in place.
+ *                  If this function returns an error, the content of \p X
+ *                  is unspecified.
+ * \param[in] N     The modulus structure.
+ *
+ *\ return          \c 0 if successful.
+ *                  Otherwise an \c MBEDTLS_ERR_MPI_xxx error code.
+ */
+int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
+    mbedtls_mpi_uint *X,
+    const mbedtls_mpi_mod_modulus *N );
+
 /** Generate a random number uniformly in a range.
  *
  * This function generates a random number between \p min inclusive and
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 83e1f54..51d096e 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -520,7 +520,59 @@
 /* END MERGE SLOT 5 */
 
 /* BEGIN MERGE SLOT 6 */
+/* BEGIN_CASE */
+void mpi_mod_raw_canonical_to_modulus_rep( const char *input_N, int rep,
+                                           const char *input_A,
+                                           const char *input_X )
+{
+    mbedtls_mpi_mod_modulus N;
+    mbedtls_mpi_mod_modulus_init( &N );
+    mbedtls_mpi_uint *A = NULL;
+    size_t A_limbs = 0;;
+    mbedtls_mpi_uint *X = NULL;
+    size_t X_limbs = 0;
 
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_modulus( &N, input_N, rep ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_raw_canonical_to_modulus_rep( A, &N ) );
+    ASSERT_COMPARE( A, A_limbs * sizeof( mbedtls_mpi_uint ),
+                    X, X_limbs * sizeof( mbedtls_mpi_uint ) );
+
+exit:
+    mbedtls_test_mpi_mod_modulus_free_with_limbs( &N );
+    mbedtls_free( A );
+    mbedtls_free( X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_mod_raw_modulus_to_canonical_rep( const char *input_N, int rep,
+                                           const char *input_A,
+                                           const char *input_X )
+{
+    mbedtls_mpi_mod_modulus N;
+    mbedtls_mpi_mod_modulus_init( &N );
+    mbedtls_mpi_uint *A = NULL;
+    size_t A_limbs = 0;;
+    mbedtls_mpi_uint *X = NULL;
+    size_t X_limbs = 0;
+
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_modulus( &N, input_N, rep ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_raw_modulus_to_canonical_rep( A, &N ) );
+    ASSERT_COMPARE( A, A_limbs * sizeof( mbedtls_mpi_uint ),
+                    X, X_limbs * sizeof( mbedtls_mpi_uint ) );
+
+exit:
+    mbedtls_test_mpi_mod_modulus_free_with_limbs( &N );
+    mbedtls_free( A );
+    mbedtls_free( X );
+}
+/* END_CASE */
 /* END MERGE SLOT 6 */
 
 /* BEGIN MERGE SLOT 7 */