Simplify x25519 reduction using internal bignum MLA helper

Signed-off-by: Hanno Becker <hanno.becker@arm.com>
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 421a067..6bc8591 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -26,6 +26,7 @@
 #include "mbedtls/error.h"
 
 #include "bn_mul.h"
+#include "bignum_internal.h"
 #include "ecp_invasive.h"
 
 #include <string.h>
@@ -5213,40 +5214,29 @@
 
 /*
  * Fast quasi-reduction modulo p255 = 2^255 - 19
- * Write N as A0 + 2^255 A1, return A0 + 19 * A1
+ * Write N as A0 + 2^256 A1, return A0 + 38 * A1
  */
 static int ecp_mod_p255( mbedtls_mpi *N )
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    mbedtls_mpi M;
-    mbedtls_mpi_uint Mp[P255_WIDTH + 2];
+    mbedtls_mpi_uint Mp[P255_WIDTH];
 
-    if( N->n < P255_WIDTH )
+    /* Helper references for top part of N */
+    mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH;
+    unsigned const NT_n = N->n - P255_WIDTH;
+    if( NT_n > P255_WIDTH )
         return( 0 );
 
-    /* M = A1 */
-    M.s = 1;
-    M.n = N->n - ( P255_WIDTH - 1 );
-    if( M.n > P255_WIDTH + 1 )
-        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
-    M.p = Mp;
-    memset( Mp, 0, sizeof Mp );
-    memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
-    M.n++; /* Make room for multiplication by 19 */
+    /* Split N as N + 2^256 M */
+    memset( Mp,   0,    sizeof( Mp ) );
+    memcpy( Mp,   NT_p, sizeof( mbedtls_mpi_uint ) * NT_n );
+    memset( NT_p, 0,    sizeof( mbedtls_mpi_uint ) * NT_n );
 
-    /* N = A0 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
-    for( i = P255_WIDTH; i < N->n; i++ )
-        N->p[i] = 0;
+    /* N = A0 + 38 * A1 */
+    mbedtls_mpi_core_mla( N->p, N->n,
+                          Mp, P255_WIDTH,
+                          38 );
 
-    /* N = A0 + 19 * A1 */
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
-
-cleanup:
-    return( ret );
+    return( 0 );
 }
 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */