Add mpi_safe_cond_assign()
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index 1052c5a..6e2afac 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -232,6 +232,25 @@
 void mpi_swap( mpi *X, mpi *Y );
 
 /**
+ * \brief          Safe conditional assignement X = Y if assign is 1
+ *
+ * \param X        MPI to conditionally assign to
+ * \param Y        Value to be assigned
+ * \param assign   1: perform the assignment, 0: leave X untouched
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
+ *                 POLARSSL_ERR_MPI_BAD_INPUT_DATA if assing is not 0 or 1
+ *
+ * \note           This function is equivalent to
+ *                      if( assign ) mpi_copy( X, Y );
+ *                 except that it avoids leaking any information about whether
+ *                 the assignment was done or not (the above code may leak
+ *                 information through branch prediction analysis).
+ */
+int mpi_safe_cond_assign( mpi *X, mpi *Y, unsigned char assign );
+
+/**
  * \brief          Set value from integer
  *
  * \param X        MPI to set
diff --git a/library/bignum.c b/library/bignum.c
index 55f7463..663d924 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -205,6 +205,31 @@
 }
 
 /*
+ * Conditionally assign X = Y, without leaking information
+ */
+int mpi_safe_cond_assign( mpi *X, mpi *Y, unsigned char assign )
+{
+    int ret = 0;
+    size_t i;
+
+    if( assign * ( 1 - assign ) != 0 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    /* Make sure both MPIs have the same size */
+    if( X->n > Y->n )
+        MPI_CHK( mpi_grow( Y, X->n ) );
+    if( Y->n > X->n )
+        MPI_CHK( mpi_grow( X, Y->n ) );
+
+    /* Do the conditional assign safely */
+    for( i = 0; i < X->n; i++ )
+        X->p[i] = X->p[i] * (1 - assign) + Y->p[i] * assign;
+
+cleanup:
+    return( ret );
+}
+
+/*
  * Set value from integer
  */
 int mpi_lset( mpi *X, t_sint z )
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index e763374..8755fa2 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -205,6 +205,15 @@
 Test mpi_shrink #8
 mpi_shrink:4:0:0:1
 
+Test mpi_safe_cond_assign #1
+mpi_safe_cond_assign:"01":"02"
+
+Test mpi_safe_cond_assign #2
+mpi_safe_cond_assign:"FF000000000000000001":"02"
+
+Test mpi_safe_cond_assign #3
+mpi_safe_cond_assign:"01":"FF000000000000000002"
+
 Base test mpi_add_abs #1
 mpi_add_abs:10:"12345678":10:"642531":10:"12988209"
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index d3a0d48..ee9b94a 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -309,6 +309,26 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mpi_safe_cond_assign( char *x_str, char *y_str )
+{
+    mpi X, Y, XX;
+    mpi_init( &X ); mpi_init( &Y ); mpi_init( &XX );
+
+    TEST_ASSERT( mpi_read_string( &X, 16, x_str ) == 0 );
+    TEST_ASSERT( mpi_read_string( &Y, 16, y_str ) == 0 );
+    TEST_ASSERT( mpi_copy( &XX, &X ) == 0 );
+
+    TEST_ASSERT( mpi_safe_cond_assign( &X, &Y, 0 ) == 0 );
+    TEST_ASSERT( mpi_cmp_mpi( &X, &XX ) == 0 );
+
+    TEST_ASSERT( mpi_safe_cond_assign( &X, &Y, 1 ) == 0 );
+    TEST_ASSERT( mpi_cmp_mpi( &X, &Y ) == 0 );
+
+    mpi_free( &X ); mpi_free( &Y ); mpi_free( &XX );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mpi_swap( int input_X,  int input_Y )
 {
     mpi X, Y, A;