New constant-flow function mbedtls_mpi_core_uint_le_mpi

Compare a single-limb MPI with a multi-limb MPI. This is rather ad hoc, but
will be useful for mbedtls_mpi_core_random.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/bignum_core.c b/library/bignum_core.c
index 6635351..08158fa 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -154,6 +154,27 @@
     }
 }
 
+/* Whether min <= A, in constant time.
+ * A_limbs must be at least 1. */
+unsigned mbedtls_mpi_core_uint_le_mpi( mbedtls_mpi_uint min,
+                                       const mbedtls_mpi_uint *A,
+                                       size_t A_limbs )
+{
+    /* min <= least significant limb? */
+    unsigned min_le_lsl = 1 ^ mbedtls_ct_mpi_uint_lt( A[0], min );
+
+    /* most significant limbs (excluding 1) are all zero? */
+    mbedtls_mpi_uint msll_mask = 0;
+    for( size_t i = 1; i < A_limbs; i++ )
+        msll_mask |= A[i];
+    /* The most significant limbs of A are not all zero iff msll_mask != 0. */
+    unsigned msll_nonzero = mbedtls_ct_mpi_uint_mask( msll_mask ) & 1;
+
+    /* min <= A iff the lowest limb of A is >= min or the other limbs
+     * are not all zero. */
+    return( min_le_lsl | msll_nonzero );
+}
+
 void mbedtls_mpi_core_cond_assign( mbedtls_mpi_uint *X,
                                    const mbedtls_mpi_uint *A,
                                    size_t limbs,
diff --git a/library/bignum_core.h b/library/bignum_core.h
index 24559c6..120fa18 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -129,6 +129,22 @@
 void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
                                          size_t A_limbs );
 
+/** \brief         Compare a machine integer with an MPI.
+ *
+ *                 This function operates in constant time with respect
+ *                 to the values of \p min and \p A.
+ *
+ * \param min      A machine integer.
+ * \param[in] A    An MPI.
+ * \param A_limbs  The number of limbs of \p A.
+ *                 This must be at least 1.
+ *
+ * \return         1 if \p min is less than or equal to \p A, otherwise 0.
+ */
+unsigned mbedtls_mpi_core_uint_le_mpi( mbedtls_mpi_uint min,
+                                       const mbedtls_mpi_uint *A,
+                                       size_t A_limbs );
+
 /**
  * \brief   Perform a safe conditional copy of an MPI which doesn't reveal
  *          whether assignment was done or not.