Merge pull request #6618 from gilles-peskine-arm/mpi_sint-min-ub-2.28

Backport 2.28: Fix undefined behavior in bignum: NULL+0 and -most-negative-sint
diff --git a/ChangeLog.d/negative-zero-from-add.txt b/ChangeLog.d/negative-zero-from-add.txt
new file mode 100644
index 0000000..107d858
--- /dev/null
+++ b/ChangeLog.d/negative-zero-from-add.txt
@@ -0,0 +1,6 @@
+Bugfix
+   * In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
+     with A > 0 created an unintended representation of the value 0 which was
+     not processed correctly by some bignum operations. Fix this. This had no
+     consequence on cryptography code, but might affect applications that call
+     bignum directly and use negative numbers.
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 5a393c1..0f3aa00 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -205,9 +205,27 @@
  */
 typedef struct mbedtls_mpi
 {
-    int s;              /*!<  Sign: -1 if the mpi is negative, 1 otherwise */
-    size_t n;           /*!<  total # of limbs  */
-    mbedtls_mpi_uint *p;          /*!<  pointer to limbs  */
+    /** Sign: -1 if the mpi is negative, 1 otherwise.
+     *
+     * The number 0 must be represented with `s = +1`. Although many library
+     * functions treat all-limbs-zero as equivalent to a valid representation
+     * of 0 regardless of the sign bit, there are exceptions, so bignum
+     * functions and external callers must always set \c s to +1 for the
+     * number zero.
+     *
+     * Note that this implies that calloc() or `... = {0}` does not create
+     * a valid MPI representation. You must call mbedtls_mpi_init().
+     */
+    int s;
+
+    /** Total number of limbs in \c p.  */
+    size_t n;
+
+    /** Pointer to limbs.
+     *
+     * This may be \c NULL if \c n is 0.
+     */
+    mbedtls_mpi_uint *p;
 }
 mbedtls_mpi;
 
diff --git a/library/bignum.c b/library/bignum.c
index 9dcd0f8..7b851ca 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1265,10 +1265,12 @@
     return( ret );
 }
 
-/*
- * Signed addition: X = A + B
+/* Common function for signed addition and subtraction.
+ * Calculate A + B * flip_B where flip_B is 1 or -1.
  */
-int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+static int add_sub_mpi( mbedtls_mpi *X,
+                        const mbedtls_mpi *A, const mbedtls_mpi *B,
+                        int flip_B )
 {
     int ret, s;
     MPI_VALIDATE_RET( X != NULL );
@@ -1276,16 +1278,21 @@
     MPI_VALIDATE_RET( B != NULL );
 
     s = A->s;
-    if( A->s * B->s < 0 )
+    if( A->s * B->s * flip_B < 0 )
     {
-        if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
+        int cmp = mbedtls_mpi_cmp_abs( A, B );
+        if( cmp >= 0 )
         {
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
-            X->s =  s;
+            /* If |A| = |B|, the result is 0 and we must set the sign bit
+             * to +1 regardless of which of A or B was negative. Otherwise,
+             * since |A| > |B|, the sign is the sign of A. */
+            X->s = cmp == 0 ? 1 : s;
         }
         else
         {
             MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
+            /* Since |A| < |B|, the sign is the opposite of A. */
             X->s = -s;
         }
     }
@@ -1301,38 +1308,19 @@
 }
 
 /*
+ * Signed addition: X = A + B
+ */
+int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    return( add_sub_mpi( X, A, B, 1 ) );
+}
+
+/*
  * Signed subtraction: X = A - B
  */
 int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
 {
-    int ret, s;
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( A != NULL );
-    MPI_VALIDATE_RET( B != NULL );
-
-    s = A->s;
-    if( A->s * B->s > 0 )
-    {
-        if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
-        {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
-            X->s =  s;
-        }
-        else
-        {
-            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
-            X->s = -s;
-        }
-    }
-    else
-    {
-        MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
-        X->s = s;
-    }
-
-cleanup:
-
-    return( ret );
+    return( add_sub_mpi( X, A, B, -1 ) );
 }
 
 /*
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index fbb2a20..7a87c5b 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -360,13 +360,19 @@
 #if defined(MBEDTLS_BIGNUM_C)
 /** Read an MPI from a hexadecimal string.
  *
- * Like mbedtls_mpi_read_string(), but size the resulting bignum based
- * on the number of digits in the string. In particular, construct a
- * bignum with 0 limbs for an empty string, and a bignum with leading 0
- * limbs if the string has sufficiently many leading 0 digits.
+ * Like mbedtls_mpi_read_string(), but with tighter guarantees around
+ * edge cases.
  *
- * This is important so that the "0 (null)" and "0 (1 limb)" and
- * "leading zeros" test cases do what they claim.
+ * - This function guarantees that if \p s begins with '-' then the sign
+ *   bit of the result will be negative, even if the value is 0.
+ *   When this function encounters such a "negative 0", it
+ *   increments #mbedtls_test_case_uses_negative_0.
+ * - The size of the result is exactly the minimum number of limbs needed
+ *   to fit the digits in the input. In particular, this function constructs
+ *   a bignum with 0 limbs for an empty string, and a bignum with leading 0
+ *   limbs if the string has sufficiently many leading 0 digits.
+ *   This is important so that the "0 (null)" and "0 (1 limb)" and
+ *   "leading zeros" test cases do what they claim.
  *
  * \param[out] X        The MPI object to populate. It must be initialized.
  * \param[in] s         The null-terminated hexadecimal string to read from.
@@ -374,6 +380,14 @@
  * \return \c 0 on success, an \c MBEDTLS_ERR_MPI_xxx error code otherwise.
  */
 int mbedtls_test_read_mpi( mbedtls_mpi *X, const char *s );
+
+/** Nonzero if the current test case had an input parsed with
+ * mbedtls_test_read_mpi() that is a negative 0 (`"-"`, `"-0"`, `"-00"`, etc.,
+ * constructing a result with the sign bit set to -1 and the value being
+ * all-limbs-0, which is not a valid representation in #mbedtls_mpi but is
+ * tested for robustness).
+ */
+extern unsigned mbedtls_test_case_uses_negative_0;
 #endif /* MBEDTLS_BIGNUM_C */
 
 #endif /* TEST_HELPERS_H */
diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py
index 5cb7997..c76294c 100755
--- a/tests/scripts/generate_bignum_tests.py
+++ b/tests/scripts/generate_bignum_tests.py
@@ -54,9 +54,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import itertools
 import sys
-import typing
 
 from abc import ABCMeta, abstractmethod
 from typing import Iterator, List, Tuple, TypeVar
@@ -68,20 +66,20 @@
 T = TypeVar('T') #pylint: disable=invalid-name
 
 def hex_to_int(val: str) -> int:
-    return int(val, 16) if val else 0
+    """Implement the syntax accepted by mbedtls_test_read_mpi().
+
+    This is a superset of what is accepted by mbedtls_test_read_mpi_core().
+    """
+    if val in ['', '-']:
+        return 0
+    return int(val, 16)
 
 def quote_str(val) -> str:
     return "\"{}\"".format(val)
 
 def combination_pairs(values: List[T]) -> List[Tuple[T, T]]:
     """Return all pair combinations from input values."""
-    # The return value is cast, as older versions of mypy are unable to derive
-    # the specific type returned by itertools.combinations_with_replacement.
-    return typing.cast(
-        List[Tuple[T, T]],
-        list(itertools.combinations_with_replacement(values, 2))
-    )
-
+    return [(x, y) for x in values for y in values]
 
 class BignumTarget(test_data_generation.BaseTarget, metaclass=ABCMeta):
     #pylint: disable=abstract-method
@@ -105,7 +103,8 @@
     """
     symbol = ""
     input_values = [
-        "", "0", "7b", "-7b",
+        "", "0", "-", "-0",
+        "7b", "-7b",
         "0000000000000000123", "-0000000000000000123",
         "1230000000000000000", "-1230000000000000000"
     ] # type: List[str]
@@ -120,6 +119,11 @@
     def arguments(self) -> List[str]:
         return [quote_str(self.arg_a), quote_str(self.arg_b), self.result()]
 
+    def description_suffix(self) -> str:
+        #pylint: disable=no-self-use # derived classes need self
+        """Text to add at the end of the test case description."""
+        return ""
+
     def description(self) -> str:
         """Generate a description for the test case.
 
@@ -133,6 +137,9 @@
                 self.symbol,
                 self.value_description(self.arg_b)
             )
+            description_suffix = self.description_suffix()
+            if description_suffix:
+                self.case_description += " " + description_suffix
         return super().description()
 
     @abstractmethod
@@ -153,6 +160,8 @@
         """
         if val == "":
             return "0 (null)"
+        if val == "-":
+            return "negative 0 (null)"
         if val == "0":
             return "0 (1 limb)"
 
@@ -228,8 +237,21 @@
         ]
     )
 
+    def __init__(self, val_a: str, val_b: str) -> None:
+        super().__init__(val_a, val_b)
+        self._result = self.int_a + self.int_b
+
+    def description_suffix(self) -> str:
+        if (self.int_a >= 0 and self.int_b >= 0):
+            return "" # obviously positive result or 0
+        if (self.int_a <= 0 and self.int_b <= 0):
+            return "" # obviously negative result or 0
+        # The sign of the result is not obvious, so indicate it
+        return ", result{}0".format('>' if self._result > 0 else
+                                    '<' if self._result < 0 else '=')
+
     def result(self) -> str:
-        return quote_str("{:x}".format(self.int_a + self.int_b))
+        return quote_str("{:x}".format(self._result))
 
 if __name__ == '__main__':
     # Use the section of the docstring relevant to the CLI as description
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index bfd2189..77b4d94 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -107,6 +107,10 @@
     mbedtls_test_info.step = step;
 }
 
+#if defined(MBEDTLS_BIGNUM_C)
+unsigned mbedtls_test_case_uses_negative_0 = 0;
+#endif
+
 void mbedtls_test_info_reset( void )
 {
     mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SUCCESS;
@@ -116,6 +120,9 @@
     mbedtls_test_info.filename = 0;
     memset( mbedtls_test_info.line1, 0, sizeof( mbedtls_test_info.line1 ) );
     memset( mbedtls_test_info.line2, 0, sizeof( mbedtls_test_info.line2 ) );
+#if defined(MBEDTLS_BIGNUM_C)
+    mbedtls_test_case_uses_negative_0 = 0;
+#endif
 }
 
 int mbedtls_test_equal( const char *test, int line_no, const char* filename,
@@ -426,6 +433,15 @@
 #if defined(MBEDTLS_BIGNUM_C)
 int mbedtls_test_read_mpi( mbedtls_mpi *X, const char *s )
 {
+    int negative = 0;
+    /* Always set the sign bit to -1 if the input has a minus sign, even for 0.
+     * This creates an invalid representation, which mbedtls_mpi_read_string()
+     * avoids but we want to be able to create that in test data. */
+    if( s[0] == '-' )
+    {
+        ++s;
+        negative = 1;
+    }
     /* mbedtls_mpi_read_string() currently retains leading zeros.
      * It always allocates at least one limb for the value 0. */
     if( s[0] == 0 )
@@ -433,7 +449,15 @@
         mbedtls_mpi_free( X );
         return( 0 );
     }
-    else
-        return( mbedtls_mpi_read_string( X, 16, s ) );
+    int ret = mbedtls_mpi_read_string( X, 16, s );
+    if( ret != 0 )
+        return( ret );
+    if( negative )
+    {
+        if( mbedtls_mpi_cmp_int( X, 0 ) == 0 )
+            ++mbedtls_test_case_uses_negative_0;
+        X->s = -1;
+    }
+    return( 0 );
 }
 #endif
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index a0d0404..35952f0 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -11,10 +11,21 @@
  * constructing the value. */
 static int sign_is_valid( const mbedtls_mpi *X )
 {
+    /* Only +1 and -1 are valid sign bits, not e.g. 0 */
     if( X->s != 1 && X->s != -1 )
-        return( 0 ); // invalid sign bit, e.g. 0
-    if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
-        return( 0 ); // negative zero
+        return( 0 );
+
+    /* The value 0 must be represented with the sign +1. A "negative zero"
+     * with s=-1 is an invalid representation. Forbid that. As an exception,
+     * we sometimes test the robustness of library functions when given
+     * a negative zero input. If a test case has a negative zero as input,
+     * we don't mind if the function has a negative zero output. */
+    if( ! mbedtls_test_case_uses_negative_0 &&
+        mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
+    {
+        return( 0 );
+    }
+
     return( 1 );
 }
 
diff --git a/tests/suites/test_suite_bignum.generated.data b/tests/suites/test_suite_bignum.generated.data
index 947d06f..00379ef 100644
--- a/tests/suites/test_suite_bignum.generated.data
+++ b/tests/suites/test_suite_bignum.generated.data
@@ -6,136 +6,346 @@
 MPI add #2 0 (null) + 0 (1 limb)
 mbedtls_mpi_add_mpi:"":"0":"0"
 
-MPI add #3 0 (null) + positive
+MPI add #3 0 (null) + negative 0 (null)
+mbedtls_mpi_add_mpi:"":"-":"0"
+
+MPI add #4 0 (null) + negative with leading zero limb
+mbedtls_mpi_add_mpi:"":"-0":"0"
+
+MPI add #5 0 (null) + positive
 mbedtls_mpi_add_mpi:"":"7b":"7b"
 
-MPI add #4 0 (null) + negative
+MPI add #6 0 (null) + negative
 mbedtls_mpi_add_mpi:"":"-7b":"-7b"
 
-MPI add #5 0 (null) + positive with leading zero limb
+MPI add #7 0 (null) + positive with leading zero limb
 mbedtls_mpi_add_mpi:"":"0000000000000000123":"123"
 
-MPI add #6 0 (null) + negative with leading zero limb
+MPI add #8 0 (null) + negative with leading zero limb
 mbedtls_mpi_add_mpi:"":"-0000000000000000123":"-123"
 
-MPI add #7 0 (null) + large positive
+MPI add #9 0 (null) + large positive
 mbedtls_mpi_add_mpi:"":"1230000000000000000":"1230000000000000000"
 
-MPI add #8 0 (null) + large negative
+MPI add #10 0 (null) + large negative
 mbedtls_mpi_add_mpi:"":"-1230000000000000000":"-1230000000000000000"
 
-MPI add #9 0 (1 limb) + 0 (1 limb)
+MPI add #11 0 (1 limb) + 0 (null)
+mbedtls_mpi_add_mpi:"0":"":"0"
+
+MPI add #12 0 (1 limb) + 0 (1 limb)
 mbedtls_mpi_add_mpi:"0":"0":"0"
 
-MPI add #10 0 (1 limb) + positive
+MPI add #13 0 (1 limb) + negative 0 (null)
+mbedtls_mpi_add_mpi:"0":"-":"0"
+
+MPI add #14 0 (1 limb) + negative with leading zero limb
+mbedtls_mpi_add_mpi:"0":"-0":"0"
+
+MPI add #15 0 (1 limb) + positive
 mbedtls_mpi_add_mpi:"0":"7b":"7b"
 
-MPI add #11 0 (1 limb) + negative
+MPI add #16 0 (1 limb) + negative
 mbedtls_mpi_add_mpi:"0":"-7b":"-7b"
 
-MPI add #12 0 (1 limb) + positive with leading zero limb
+MPI add #17 0 (1 limb) + positive with leading zero limb
 mbedtls_mpi_add_mpi:"0":"0000000000000000123":"123"
 
-MPI add #13 0 (1 limb) + negative with leading zero limb
+MPI add #18 0 (1 limb) + negative with leading zero limb
 mbedtls_mpi_add_mpi:"0":"-0000000000000000123":"-123"
 
-MPI add #14 0 (1 limb) + large positive
+MPI add #19 0 (1 limb) + large positive
 mbedtls_mpi_add_mpi:"0":"1230000000000000000":"1230000000000000000"
 
-MPI add #15 0 (1 limb) + large negative
+MPI add #20 0 (1 limb) + large negative
 mbedtls_mpi_add_mpi:"0":"-1230000000000000000":"-1230000000000000000"
 
-MPI add #16 positive + positive
+MPI add #21 negative 0 (null) + 0 (null)
+mbedtls_mpi_add_mpi:"-":"":"0"
+
+MPI add #22 negative 0 (null) + 0 (1 limb)
+mbedtls_mpi_add_mpi:"-":"0":"0"
+
+MPI add #23 negative 0 (null) + negative 0 (null)
+mbedtls_mpi_add_mpi:"-":"-":"0"
+
+MPI add #24 negative 0 (null) + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-":"-0":"0"
+
+MPI add #25 negative 0 (null) + positive
+mbedtls_mpi_add_mpi:"-":"7b":"7b"
+
+MPI add #26 negative 0 (null) + negative
+mbedtls_mpi_add_mpi:"-":"-7b":"-7b"
+
+MPI add #27 negative 0 (null) + positive with leading zero limb
+mbedtls_mpi_add_mpi:"-":"0000000000000000123":"123"
+
+MPI add #28 negative 0 (null) + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-":"-0000000000000000123":"-123"
+
+MPI add #29 negative 0 (null) + large positive
+mbedtls_mpi_add_mpi:"-":"1230000000000000000":"1230000000000000000"
+
+MPI add #30 negative 0 (null) + large negative
+mbedtls_mpi_add_mpi:"-":"-1230000000000000000":"-1230000000000000000"
+
+MPI add #31 negative with leading zero limb + 0 (null)
+mbedtls_mpi_add_mpi:"-0":"":"0"
+
+MPI add #32 negative with leading zero limb + 0 (1 limb)
+mbedtls_mpi_add_mpi:"-0":"0":"0"
+
+MPI add #33 negative with leading zero limb + negative 0 (null)
+mbedtls_mpi_add_mpi:"-0":"-":"0"
+
+MPI add #34 negative with leading zero limb + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-0":"-0":"0"
+
+MPI add #35 negative with leading zero limb + positive
+mbedtls_mpi_add_mpi:"-0":"7b":"7b"
+
+MPI add #36 negative with leading zero limb + negative
+mbedtls_mpi_add_mpi:"-0":"-7b":"-7b"
+
+MPI add #37 negative with leading zero limb + positive with leading zero limb
+mbedtls_mpi_add_mpi:"-0":"0000000000000000123":"123"
+
+MPI add #38 negative with leading zero limb + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-0":"-0000000000000000123":"-123"
+
+MPI add #39 negative with leading zero limb + large positive
+mbedtls_mpi_add_mpi:"-0":"1230000000000000000":"1230000000000000000"
+
+MPI add #40 negative with leading zero limb + large negative
+mbedtls_mpi_add_mpi:"-0":"-1230000000000000000":"-1230000000000000000"
+
+MPI add #41 positive + 0 (null)
+mbedtls_mpi_add_mpi:"7b":"":"7b"
+
+MPI add #42 positive + 0 (1 limb)
+mbedtls_mpi_add_mpi:"7b":"0":"7b"
+
+MPI add #43 positive + negative 0 (null)
+mbedtls_mpi_add_mpi:"7b":"-":"7b"
+
+MPI add #44 positive + negative with leading zero limb
+mbedtls_mpi_add_mpi:"7b":"-0":"7b"
+
+MPI add #45 positive + positive
 mbedtls_mpi_add_mpi:"7b":"7b":"f6"
 
-MPI add #17 positive + negative
+MPI add #46 positive + negative , result=0
 mbedtls_mpi_add_mpi:"7b":"-7b":"0"
 
-MPI add #18 positive + positive with leading zero limb
+MPI add #47 positive + positive with leading zero limb
 mbedtls_mpi_add_mpi:"7b":"0000000000000000123":"19e"
 
-MPI add #19 positive + negative with leading zero limb
+MPI add #48 positive + negative with leading zero limb , result<0
 mbedtls_mpi_add_mpi:"7b":"-0000000000000000123":"-a8"
 
-MPI add #20 positive + large positive
+MPI add #49 positive + large positive
 mbedtls_mpi_add_mpi:"7b":"1230000000000000000":"123000000000000007b"
 
-MPI add #21 positive + large negative
+MPI add #50 positive + large negative , result<0
 mbedtls_mpi_add_mpi:"7b":"-1230000000000000000":"-122ffffffffffffff85"
 
-MPI add #22 negative + negative
+MPI add #51 negative + 0 (null)
+mbedtls_mpi_add_mpi:"-7b":"":"-7b"
+
+MPI add #52 negative + 0 (1 limb)
+mbedtls_mpi_add_mpi:"-7b":"0":"-7b"
+
+MPI add #53 negative + negative 0 (null)
+mbedtls_mpi_add_mpi:"-7b":"-":"-7b"
+
+MPI add #54 negative + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-7b":"-0":"-7b"
+
+MPI add #55 negative + positive , result=0
+mbedtls_mpi_add_mpi:"-7b":"7b":"0"
+
+MPI add #56 negative + negative
 mbedtls_mpi_add_mpi:"-7b":"-7b":"-f6"
 
-MPI add #23 negative + positive with leading zero limb
+MPI add #57 negative + positive with leading zero limb , result>0
 mbedtls_mpi_add_mpi:"-7b":"0000000000000000123":"a8"
 
-MPI add #24 negative + negative with leading zero limb
+MPI add #58 negative + negative with leading zero limb
 mbedtls_mpi_add_mpi:"-7b":"-0000000000000000123":"-19e"
 
-MPI add #25 negative + large positive
+MPI add #59 negative + large positive , result>0
 mbedtls_mpi_add_mpi:"-7b":"1230000000000000000":"122ffffffffffffff85"
 
-MPI add #26 negative + large negative
+MPI add #60 negative + large negative
 mbedtls_mpi_add_mpi:"-7b":"-1230000000000000000":"-123000000000000007b"
 
-MPI add #27 positive with leading zero limb + positive with leading zero limb
+MPI add #61 positive with leading zero limb + 0 (null)
+mbedtls_mpi_add_mpi:"0000000000000000123":"":"123"
+
+MPI add #62 positive with leading zero limb + 0 (1 limb)
+mbedtls_mpi_add_mpi:"0000000000000000123":"0":"123"
+
+MPI add #63 positive with leading zero limb + negative 0 (null)
+mbedtls_mpi_add_mpi:"0000000000000000123":"-":"123"
+
+MPI add #64 positive with leading zero limb + negative with leading zero limb
+mbedtls_mpi_add_mpi:"0000000000000000123":"-0":"123"
+
+MPI add #65 positive with leading zero limb + positive
+mbedtls_mpi_add_mpi:"0000000000000000123":"7b":"19e"
+
+MPI add #66 positive with leading zero limb + negative , result>0
+mbedtls_mpi_add_mpi:"0000000000000000123":"-7b":"a8"
+
+MPI add #67 positive with leading zero limb + positive with leading zero limb
 mbedtls_mpi_add_mpi:"0000000000000000123":"0000000000000000123":"246"
 
-MPI add #28 positive with leading zero limb + negative with leading zero limb
+MPI add #68 positive with leading zero limb + negative with leading zero limb , result=0
 mbedtls_mpi_add_mpi:"0000000000000000123":"-0000000000000000123":"0"
 
-MPI add #29 positive with leading zero limb + large positive
+MPI add #69 positive with leading zero limb + large positive
 mbedtls_mpi_add_mpi:"0000000000000000123":"1230000000000000000":"1230000000000000123"
 
-MPI add #30 positive with leading zero limb + large negative
+MPI add #70 positive with leading zero limb + large negative , result<0
 mbedtls_mpi_add_mpi:"0000000000000000123":"-1230000000000000000":"-122fffffffffffffedd"
 
-MPI add #31 negative with leading zero limb + negative with leading zero limb
+MPI add #71 negative with leading zero limb + 0 (null)
+mbedtls_mpi_add_mpi:"-0000000000000000123":"":"-123"
+
+MPI add #72 negative with leading zero limb + 0 (1 limb)
+mbedtls_mpi_add_mpi:"-0000000000000000123":"0":"-123"
+
+MPI add #73 negative with leading zero limb + negative 0 (null)
+mbedtls_mpi_add_mpi:"-0000000000000000123":"-":"-123"
+
+MPI add #74 negative with leading zero limb + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-0000000000000000123":"-0":"-123"
+
+MPI add #75 negative with leading zero limb + positive , result<0
+mbedtls_mpi_add_mpi:"-0000000000000000123":"7b":"-a8"
+
+MPI add #76 negative with leading zero limb + negative
+mbedtls_mpi_add_mpi:"-0000000000000000123":"-7b":"-19e"
+
+MPI add #77 negative with leading zero limb + positive with leading zero limb , result=0
+mbedtls_mpi_add_mpi:"-0000000000000000123":"0000000000000000123":"0"
+
+MPI add #78 negative with leading zero limb + negative with leading zero limb
 mbedtls_mpi_add_mpi:"-0000000000000000123":"-0000000000000000123":"-246"
 
-MPI add #32 negative with leading zero limb + large positive
+MPI add #79 negative with leading zero limb + large positive , result>0
 mbedtls_mpi_add_mpi:"-0000000000000000123":"1230000000000000000":"122fffffffffffffedd"
 
-MPI add #33 negative with leading zero limb + large negative
+MPI add #80 negative with leading zero limb + large negative
 mbedtls_mpi_add_mpi:"-0000000000000000123":"-1230000000000000000":"-1230000000000000123"
 
-MPI add #34 large positive + large positive
+MPI add #81 large positive + 0 (null)
+mbedtls_mpi_add_mpi:"1230000000000000000":"":"1230000000000000000"
+
+MPI add #82 large positive + 0 (1 limb)
+mbedtls_mpi_add_mpi:"1230000000000000000":"0":"1230000000000000000"
+
+MPI add #83 large positive + negative 0 (null)
+mbedtls_mpi_add_mpi:"1230000000000000000":"-":"1230000000000000000"
+
+MPI add #84 large positive + negative with leading zero limb
+mbedtls_mpi_add_mpi:"1230000000000000000":"-0":"1230000000000000000"
+
+MPI add #85 large positive + positive
+mbedtls_mpi_add_mpi:"1230000000000000000":"7b":"123000000000000007b"
+
+MPI add #86 large positive + negative , result>0
+mbedtls_mpi_add_mpi:"1230000000000000000":"-7b":"122ffffffffffffff85"
+
+MPI add #87 large positive + positive with leading zero limb
+mbedtls_mpi_add_mpi:"1230000000000000000":"0000000000000000123":"1230000000000000123"
+
+MPI add #88 large positive + negative with leading zero limb , result>0
+mbedtls_mpi_add_mpi:"1230000000000000000":"-0000000000000000123":"122fffffffffffffedd"
+
+MPI add #89 large positive + large positive
 mbedtls_mpi_add_mpi:"1230000000000000000":"1230000000000000000":"2460000000000000000"
 
-MPI add #35 large positive + large negative
+MPI add #90 large positive + large negative , result=0
 mbedtls_mpi_add_mpi:"1230000000000000000":"-1230000000000000000":"0"
 
-MPI add #36 large negative + large negative
+MPI add #91 large negative + 0 (null)
+mbedtls_mpi_add_mpi:"-1230000000000000000":"":"-1230000000000000000"
+
+MPI add #92 large negative + 0 (1 limb)
+mbedtls_mpi_add_mpi:"-1230000000000000000":"0":"-1230000000000000000"
+
+MPI add #93 large negative + negative 0 (null)
+mbedtls_mpi_add_mpi:"-1230000000000000000":"-":"-1230000000000000000"
+
+MPI add #94 large negative + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-1230000000000000000":"-0":"-1230000000000000000"
+
+MPI add #95 large negative + positive , result<0
+mbedtls_mpi_add_mpi:"-1230000000000000000":"7b":"-122ffffffffffffff85"
+
+MPI add #96 large negative + negative
+mbedtls_mpi_add_mpi:"-1230000000000000000":"-7b":"-123000000000000007b"
+
+MPI add #97 large negative + positive with leading zero limb , result<0
+mbedtls_mpi_add_mpi:"-1230000000000000000":"0000000000000000123":"-122fffffffffffffedd"
+
+MPI add #98 large negative + negative with leading zero limb
+mbedtls_mpi_add_mpi:"-1230000000000000000":"-0000000000000000123":"-1230000000000000123"
+
+MPI add #99 large negative + large positive , result=0
+mbedtls_mpi_add_mpi:"-1230000000000000000":"1230000000000000000":"0"
+
+MPI add #100 large negative + large negative
 mbedtls_mpi_add_mpi:"-1230000000000000000":"-1230000000000000000":"-2460000000000000000"
 
-MPI add #37 large positive + large positive
+MPI add #101 large positive + large positive
 mbedtls_mpi_add_mpi:"1c67967269c6":"1c67967269c6":"38cf2ce4d38c"
 
-MPI add #38 large positive + positive
+MPI add #102 large positive + positive
 mbedtls_mpi_add_mpi:"1c67967269c6":"9cde3":"1c67967c37a9"
 
-MPI add #39 large positive + large negative
+MPI add #103 large positive + large negative , result=0
 mbedtls_mpi_add_mpi:"1c67967269c6":"-1c67967269c6":"0"
 
-MPI add #40 large positive + negative
+MPI add #104 large positive + negative , result>0
 mbedtls_mpi_add_mpi:"1c67967269c6":"-9cde3":"1c6796689be3"
 
-MPI add #41 positive + positive
+MPI add #105 positive + large positive
+mbedtls_mpi_add_mpi:"9cde3":"1c67967269c6":"1c67967c37a9"
+
+MPI add #106 positive + positive
 mbedtls_mpi_add_mpi:"9cde3":"9cde3":"139bc6"
 
-MPI add #42 positive + large negative
+MPI add #107 positive + large negative , result<0
 mbedtls_mpi_add_mpi:"9cde3":"-1c67967269c6":"-1c6796689be3"
 
-MPI add #43 positive + negative
+MPI add #108 positive + negative , result=0
 mbedtls_mpi_add_mpi:"9cde3":"-9cde3":"0"
 
-MPI add #44 large negative + large negative
+MPI add #109 large negative + large positive , result=0
+mbedtls_mpi_add_mpi:"-1c67967269c6":"1c67967269c6":"0"
+
+MPI add #110 large negative + positive , result<0
+mbedtls_mpi_add_mpi:"-1c67967269c6":"9cde3":"-1c6796689be3"
+
+MPI add #111 large negative + large negative
 mbedtls_mpi_add_mpi:"-1c67967269c6":"-1c67967269c6":"-38cf2ce4d38c"
 
-MPI add #45 large negative + negative
+MPI add #112 large negative + negative
 mbedtls_mpi_add_mpi:"-1c67967269c6":"-9cde3":"-1c67967c37a9"
 
-MPI add #46 negative + negative
+MPI add #113 negative + large positive , result>0
+mbedtls_mpi_add_mpi:"-9cde3":"1c67967269c6":"1c6796689be3"
+
+MPI add #114 negative + positive , result=0
+mbedtls_mpi_add_mpi:"-9cde3":"9cde3":"0"
+
+MPI add #115 negative + large negative
+mbedtls_mpi_add_mpi:"-9cde3":"-1c67967269c6":"-1c67967c37a9"
+
+MPI add #116 negative + negative
 mbedtls_mpi_add_mpi:"-9cde3":"-9cde3":"-139bc6"
 
 MPI compare #1 0 (null) == 0 (null)
@@ -144,118 +354,310 @@
 MPI compare #2 0 (null) == 0 (1 limb)
 mbedtls_mpi_cmp_mpi:"":"0":0
 
-MPI compare #3 0 (null) < positive
+MPI compare #3 0 (null) == negative 0 (null)
+mbedtls_mpi_cmp_mpi:"":"-":0
+
+MPI compare #4 0 (null) == negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"":"-0":0
+
+MPI compare #5 0 (null) < positive
 mbedtls_mpi_cmp_mpi:"":"7b":-1
 
-MPI compare #4 0 (null) > negative
+MPI compare #6 0 (null) > negative
 mbedtls_mpi_cmp_mpi:"":"-7b":1
 
-MPI compare #5 0 (null) < positive with leading zero limb
+MPI compare #7 0 (null) < positive with leading zero limb
 mbedtls_mpi_cmp_mpi:"":"0000000000000000123":-1
 
-MPI compare #6 0 (null) > negative with leading zero limb
+MPI compare #8 0 (null) > negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"":"-0000000000000000123":1
 
-MPI compare #7 0 (null) < large positive
+MPI compare #9 0 (null) < large positive
 mbedtls_mpi_cmp_mpi:"":"1230000000000000000":-1
 
-MPI compare #8 0 (null) > large negative
+MPI compare #10 0 (null) > large negative
 mbedtls_mpi_cmp_mpi:"":"-1230000000000000000":1
 
-MPI compare #9 0 (1 limb) == 0 (1 limb)
+MPI compare #11 0 (1 limb) == 0 (null)
+mbedtls_mpi_cmp_mpi:"0":"":0
+
+MPI compare #12 0 (1 limb) == 0 (1 limb)
 mbedtls_mpi_cmp_mpi:"0":"0":0
 
-MPI compare #10 0 (1 limb) < positive
+MPI compare #13 0 (1 limb) == negative 0 (null)
+mbedtls_mpi_cmp_mpi:"0":"-":0
+
+MPI compare #14 0 (1 limb) == negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"0":"-0":0
+
+MPI compare #15 0 (1 limb) < positive
 mbedtls_mpi_cmp_mpi:"0":"7b":-1
 
-MPI compare #11 0 (1 limb) > negative
+MPI compare #16 0 (1 limb) > negative
 mbedtls_mpi_cmp_mpi:"0":"-7b":1
 
-MPI compare #12 0 (1 limb) < positive with leading zero limb
+MPI compare #17 0 (1 limb) < positive with leading zero limb
 mbedtls_mpi_cmp_mpi:"0":"0000000000000000123":-1
 
-MPI compare #13 0 (1 limb) > negative with leading zero limb
+MPI compare #18 0 (1 limb) > negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"0":"-0000000000000000123":1
 
-MPI compare #14 0 (1 limb) < large positive
+MPI compare #19 0 (1 limb) < large positive
 mbedtls_mpi_cmp_mpi:"0":"1230000000000000000":-1
 
-MPI compare #15 0 (1 limb) > large negative
+MPI compare #20 0 (1 limb) > large negative
 mbedtls_mpi_cmp_mpi:"0":"-1230000000000000000":1
 
-MPI compare #16 positive == positive
+MPI compare #21 negative 0 (null) == 0 (null)
+mbedtls_mpi_cmp_mpi:"-":"":0
+
+MPI compare #22 negative 0 (null) == 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"-":"0":0
+
+MPI compare #23 negative 0 (null) == negative 0 (null)
+mbedtls_mpi_cmp_mpi:"-":"-":0
+
+MPI compare #24 negative 0 (null) == negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-":"-0":0
+
+MPI compare #25 negative 0 (null) < positive
+mbedtls_mpi_cmp_mpi:"-":"7b":-1
+
+MPI compare #26 negative 0 (null) > negative
+mbedtls_mpi_cmp_mpi:"-":"-7b":1
+
+MPI compare #27 negative 0 (null) < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:"-":"0000000000000000123":-1
+
+MPI compare #28 negative 0 (null) > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-":"-0000000000000000123":1
+
+MPI compare #29 negative 0 (null) < large positive
+mbedtls_mpi_cmp_mpi:"-":"1230000000000000000":-1
+
+MPI compare #30 negative 0 (null) > large negative
+mbedtls_mpi_cmp_mpi:"-":"-1230000000000000000":1
+
+MPI compare #31 negative with leading zero limb == 0 (null)
+mbedtls_mpi_cmp_mpi:"-0":"":0
+
+MPI compare #32 negative with leading zero limb == 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"-0":"0":0
+
+MPI compare #33 negative with leading zero limb == negative 0 (null)
+mbedtls_mpi_cmp_mpi:"-0":"-":0
+
+MPI compare #34 negative with leading zero limb == negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-0":"-0":0
+
+MPI compare #35 negative with leading zero limb < positive
+mbedtls_mpi_cmp_mpi:"-0":"7b":-1
+
+MPI compare #36 negative with leading zero limb > negative
+mbedtls_mpi_cmp_mpi:"-0":"-7b":1
+
+MPI compare #37 negative with leading zero limb < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:"-0":"0000000000000000123":-1
+
+MPI compare #38 negative with leading zero limb > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-0":"-0000000000000000123":1
+
+MPI compare #39 negative with leading zero limb < large positive
+mbedtls_mpi_cmp_mpi:"-0":"1230000000000000000":-1
+
+MPI compare #40 negative with leading zero limb > large negative
+mbedtls_mpi_cmp_mpi:"-0":"-1230000000000000000":1
+
+MPI compare #41 positive > 0 (null)
+mbedtls_mpi_cmp_mpi:"7b":"":1
+
+MPI compare #42 positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"7b":"0":1
+
+MPI compare #43 positive > negative 0 (null)
+mbedtls_mpi_cmp_mpi:"7b":"-":1
+
+MPI compare #44 positive > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"7b":"-0":1
+
+MPI compare #45 positive == positive
 mbedtls_mpi_cmp_mpi:"7b":"7b":0
 
-MPI compare #17 positive > negative
+MPI compare #46 positive > negative
 mbedtls_mpi_cmp_mpi:"7b":"-7b":1
 
-MPI compare #18 positive < positive with leading zero limb
+MPI compare #47 positive < positive with leading zero limb
 mbedtls_mpi_cmp_mpi:"7b":"0000000000000000123":-1
 
-MPI compare #19 positive > negative with leading zero limb
+MPI compare #48 positive > negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"7b":"-0000000000000000123":1
 
-MPI compare #20 positive < large positive
+MPI compare #49 positive < large positive
 mbedtls_mpi_cmp_mpi:"7b":"1230000000000000000":-1
 
-MPI compare #21 positive > large negative
+MPI compare #50 positive > large negative
 mbedtls_mpi_cmp_mpi:"7b":"-1230000000000000000":1
 
-MPI compare #22 negative == negative
+MPI compare #51 negative < 0 (null)
+mbedtls_mpi_cmp_mpi:"-7b":"":-1
+
+MPI compare #52 negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"-7b":"0":-1
+
+MPI compare #53 negative < negative 0 (null)
+mbedtls_mpi_cmp_mpi:"-7b":"-":-1
+
+MPI compare #54 negative < negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-7b":"-0":-1
+
+MPI compare #55 negative < positive
+mbedtls_mpi_cmp_mpi:"-7b":"7b":-1
+
+MPI compare #56 negative == negative
 mbedtls_mpi_cmp_mpi:"-7b":"-7b":0
 
-MPI compare #23 negative < positive with leading zero limb
+MPI compare #57 negative < positive with leading zero limb
 mbedtls_mpi_cmp_mpi:"-7b":"0000000000000000123":-1
 
-MPI compare #24 negative > negative with leading zero limb
+MPI compare #58 negative > negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"-7b":"-0000000000000000123":1
 
-MPI compare #25 negative < large positive
+MPI compare #59 negative < large positive
 mbedtls_mpi_cmp_mpi:"-7b":"1230000000000000000":-1
 
-MPI compare #26 negative > large negative
+MPI compare #60 negative > large negative
 mbedtls_mpi_cmp_mpi:"-7b":"-1230000000000000000":1
 
-MPI compare #27 positive with leading zero limb == positive with leading zero limb
+MPI compare #61 positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"":1
+
+MPI compare #62 positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"0":1
+
+MPI compare #63 positive with leading zero limb > negative 0 (null)
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"-":1
+
+MPI compare #64 positive with leading zero limb > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"-0":1
+
+MPI compare #65 positive with leading zero limb > positive
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"7b":1
+
+MPI compare #66 positive with leading zero limb > negative
+mbedtls_mpi_cmp_mpi:"0000000000000000123":"-7b":1
+
+MPI compare #67 positive with leading zero limb == positive with leading zero limb
 mbedtls_mpi_cmp_mpi:"0000000000000000123":"0000000000000000123":0
 
-MPI compare #28 positive with leading zero limb > negative with leading zero limb
+MPI compare #68 positive with leading zero limb > negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"0000000000000000123":"-0000000000000000123":1
 
-MPI compare #29 positive with leading zero limb < large positive
+MPI compare #69 positive with leading zero limb < large positive
 mbedtls_mpi_cmp_mpi:"0000000000000000123":"1230000000000000000":-1
 
-MPI compare #30 positive with leading zero limb > large negative
+MPI compare #70 positive with leading zero limb > large negative
 mbedtls_mpi_cmp_mpi:"0000000000000000123":"-1230000000000000000":1
 
-MPI compare #31 negative with leading zero limb == negative with leading zero limb
+MPI compare #71 negative with leading zero limb < 0 (null)
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"":-1
+
+MPI compare #72 negative with leading zero limb < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"0":-1
+
+MPI compare #73 negative with leading zero limb < negative 0 (null)
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-":-1
+
+MPI compare #74 negative with leading zero limb < negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-0":-1
+
+MPI compare #75 negative with leading zero limb < positive
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"7b":-1
+
+MPI compare #76 negative with leading zero limb < negative
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-7b":-1
+
+MPI compare #77 negative with leading zero limb < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:"-0000000000000000123":"0000000000000000123":-1
+
+MPI compare #78 negative with leading zero limb == negative with leading zero limb
 mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-0000000000000000123":0
 
-MPI compare #32 negative with leading zero limb < large positive
+MPI compare #79 negative with leading zero limb < large positive
 mbedtls_mpi_cmp_mpi:"-0000000000000000123":"1230000000000000000":-1
 
-MPI compare #33 negative with leading zero limb > large negative
+MPI compare #80 negative with leading zero limb > large negative
 mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-1230000000000000000":1
 
-MPI compare #34 large positive == large positive
+MPI compare #81 large positive > 0 (null)
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"":1
+
+MPI compare #82 large positive > 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"0":1
+
+MPI compare #83 large positive > negative 0 (null)
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"-":1
+
+MPI compare #84 large positive > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"-0":1
+
+MPI compare #85 large positive > positive
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"7b":1
+
+MPI compare #86 large positive > negative
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"-7b":1
+
+MPI compare #87 large positive > positive with leading zero limb
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"0000000000000000123":1
+
+MPI compare #88 large positive > negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"1230000000000000000":"-0000000000000000123":1
+
+MPI compare #89 large positive == large positive
 mbedtls_mpi_cmp_mpi:"1230000000000000000":"1230000000000000000":0
 
-MPI compare #35 large positive > large negative
+MPI compare #90 large positive > large negative
 mbedtls_mpi_cmp_mpi:"1230000000000000000":"-1230000000000000000":1
 
-MPI compare #36 large negative == large negative
+MPI compare #91 large negative < 0 (null)
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"":-1
+
+MPI compare #92 large negative < 0 (1 limb)
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"0":-1
+
+MPI compare #93 large negative < negative 0 (null)
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-":-1
+
+MPI compare #94 large negative < negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-0":-1
+
+MPI compare #95 large negative < positive
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"7b":-1
+
+MPI compare #96 large negative < negative
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-7b":-1
+
+MPI compare #97 large negative < positive with leading zero limb
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"0000000000000000123":-1
+
+MPI compare #98 large negative < negative with leading zero limb
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-0000000000000000123":-1
+
+MPI compare #99 large negative < large positive
+mbedtls_mpi_cmp_mpi:"-1230000000000000000":"1230000000000000000":-1
+
+MPI compare #100 large negative == large negative
 mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-1230000000000000000":0
 
-MPI compare #37 negative > negative
+MPI compare #101 negative > negative
 mbedtls_mpi_cmp_mpi:"-2":"-3":1
 
-MPI compare #38 negative == negative
+MPI compare #102 negative == negative
 mbedtls_mpi_cmp_mpi:"-2":"-2":0
 
-MPI compare #39 positive < positive
+MPI compare #103 positive < positive
 mbedtls_mpi_cmp_mpi:"2b4":"2b5":-1
 
-MPI compare #40 positive < positive
+MPI compare #104 positive < positive
 mbedtls_mpi_cmp_mpi:"2b5":"2b6":-1
 
 MPI compare (abs) #1 0 (null) == 0 (null)
@@ -264,118 +666,310 @@
 MPI compare (abs) #2 0 (null) == 0 (1 limb)
 mbedtls_mpi_cmp_abs:"":"0":0
 
-MPI compare (abs) #3 0 (null) < positive
+MPI compare (abs) #3 0 (null) == 0 (null)
+mbedtls_mpi_cmp_abs:"":"":0
+
+MPI compare (abs) #4 0 (null) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"":"0":0
+
+MPI compare (abs) #5 0 (null) < positive
 mbedtls_mpi_cmp_abs:"":"7b":-1
 
-MPI compare (abs) #4 0 (null) < positive
+MPI compare (abs) #6 0 (null) < positive
 mbedtls_mpi_cmp_abs:"":"7b":-1
 
-MPI compare (abs) #5 0 (null) < positive with leading zero limb
+MPI compare (abs) #7 0 (null) < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1
 
-MPI compare (abs) #6 0 (null) < positive with leading zero limb
+MPI compare (abs) #8 0 (null) < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1
 
-MPI compare (abs) #7 0 (null) < large positive
+MPI compare (abs) #9 0 (null) < large positive
 mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1
 
-MPI compare (abs) #8 0 (null) < large positive
+MPI compare (abs) #10 0 (null) < large positive
 mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1
 
-MPI compare (abs) #9 0 (1 limb) == 0 (1 limb)
+MPI compare (abs) #11 0 (1 limb) == 0 (null)
+mbedtls_mpi_cmp_abs:"0":"":0
+
+MPI compare (abs) #12 0 (1 limb) == 0 (1 limb)
 mbedtls_mpi_cmp_abs:"0":"0":0
 
-MPI compare (abs) #10 0 (1 limb) < positive
+MPI compare (abs) #13 0 (1 limb) == 0 (null)
+mbedtls_mpi_cmp_abs:"0":"":0
+
+MPI compare (abs) #14 0 (1 limb) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0":"0":0
+
+MPI compare (abs) #15 0 (1 limb) < positive
 mbedtls_mpi_cmp_abs:"0":"7b":-1
 
-MPI compare (abs) #11 0 (1 limb) < positive
+MPI compare (abs) #16 0 (1 limb) < positive
 mbedtls_mpi_cmp_abs:"0":"7b":-1
 
-MPI compare (abs) #12 0 (1 limb) < positive with leading zero limb
+MPI compare (abs) #17 0 (1 limb) < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1
 
-MPI compare (abs) #13 0 (1 limb) < positive with leading zero limb
+MPI compare (abs) #18 0 (1 limb) < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1
 
-MPI compare (abs) #14 0 (1 limb) < large positive
+MPI compare (abs) #19 0 (1 limb) < large positive
 mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1
 
-MPI compare (abs) #15 0 (1 limb) < large positive
+MPI compare (abs) #20 0 (1 limb) < large positive
 mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1
 
-MPI compare (abs) #16 positive == positive
+MPI compare (abs) #21 0 (null) == 0 (null)
+mbedtls_mpi_cmp_abs:"":"":0
+
+MPI compare (abs) #22 0 (null) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"":"0":0
+
+MPI compare (abs) #23 0 (null) == 0 (null)
+mbedtls_mpi_cmp_abs:"":"":0
+
+MPI compare (abs) #24 0 (null) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"":"0":0
+
+MPI compare (abs) #25 0 (null) < positive
+mbedtls_mpi_cmp_abs:"":"7b":-1
+
+MPI compare (abs) #26 0 (null) < positive
+mbedtls_mpi_cmp_abs:"":"7b":-1
+
+MPI compare (abs) #27 0 (null) < positive with leading zero limb
+mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1
+
+MPI compare (abs) #28 0 (null) < positive with leading zero limb
+mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1
+
+MPI compare (abs) #29 0 (null) < large positive
+mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1
+
+MPI compare (abs) #30 0 (null) < large positive
+mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1
+
+MPI compare (abs) #31 0 (1 limb) == 0 (null)
+mbedtls_mpi_cmp_abs:"0":"":0
+
+MPI compare (abs) #32 0 (1 limb) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0":"0":0
+
+MPI compare (abs) #33 0 (1 limb) == 0 (null)
+mbedtls_mpi_cmp_abs:"0":"":0
+
+MPI compare (abs) #34 0 (1 limb) == 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0":"0":0
+
+MPI compare (abs) #35 0 (1 limb) < positive
+mbedtls_mpi_cmp_abs:"0":"7b":-1
+
+MPI compare (abs) #36 0 (1 limb) < positive
+mbedtls_mpi_cmp_abs:"0":"7b":-1
+
+MPI compare (abs) #37 0 (1 limb) < positive with leading zero limb
+mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1
+
+MPI compare (abs) #38 0 (1 limb) < positive with leading zero limb
+mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1
+
+MPI compare (abs) #39 0 (1 limb) < large positive
+mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1
+
+MPI compare (abs) #40 0 (1 limb) < large positive
+mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1
+
+MPI compare (abs) #41 positive > 0 (null)
+mbedtls_mpi_cmp_abs:"7b":"":1
+
+MPI compare (abs) #42 positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"7b":"0":1
+
+MPI compare (abs) #43 positive > 0 (null)
+mbedtls_mpi_cmp_abs:"7b":"":1
+
+MPI compare (abs) #44 positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"7b":"0":1
+
+MPI compare (abs) #45 positive == positive
 mbedtls_mpi_cmp_abs:"7b":"7b":0
 
-MPI compare (abs) #17 positive == positive
+MPI compare (abs) #46 positive == positive
 mbedtls_mpi_cmp_abs:"7b":"7b":0
 
-MPI compare (abs) #18 positive < positive with leading zero limb
+MPI compare (abs) #47 positive < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1
 
-MPI compare (abs) #19 positive < positive with leading zero limb
+MPI compare (abs) #48 positive < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1
 
-MPI compare (abs) #20 positive < large positive
+MPI compare (abs) #49 positive < large positive
 mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1
 
-MPI compare (abs) #21 positive < large positive
+MPI compare (abs) #50 positive < large positive
 mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1
 
-MPI compare (abs) #22 positive == positive
+MPI compare (abs) #51 positive > 0 (null)
+mbedtls_mpi_cmp_abs:"7b":"":1
+
+MPI compare (abs) #52 positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"7b":"0":1
+
+MPI compare (abs) #53 positive > 0 (null)
+mbedtls_mpi_cmp_abs:"7b":"":1
+
+MPI compare (abs) #54 positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"7b":"0":1
+
+MPI compare (abs) #55 positive == positive
 mbedtls_mpi_cmp_abs:"7b":"7b":0
 
-MPI compare (abs) #23 positive < positive with leading zero limb
+MPI compare (abs) #56 positive == positive
+mbedtls_mpi_cmp_abs:"7b":"7b":0
+
+MPI compare (abs) #57 positive < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1
 
-MPI compare (abs) #24 positive < positive with leading zero limb
+MPI compare (abs) #58 positive < positive with leading zero limb
 mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1
 
-MPI compare (abs) #25 positive < large positive
+MPI compare (abs) #59 positive < large positive
 mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1
 
-MPI compare (abs) #26 positive < large positive
+MPI compare (abs) #60 positive < large positive
 mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1
 
-MPI compare (abs) #27 positive with leading zero limb == positive with leading zero limb
+MPI compare (abs) #61 positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"":1
+
+MPI compare (abs) #62 positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"0":1
+
+MPI compare (abs) #63 positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"":1
+
+MPI compare (abs) #64 positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"0":1
+
+MPI compare (abs) #65 positive with leading zero limb > positive
+mbedtls_mpi_cmp_abs:"0000000000000000123":"7b":1
+
+MPI compare (abs) #66 positive with leading zero limb > positive
+mbedtls_mpi_cmp_abs:"0000000000000000123":"7b":1
+
+MPI compare (abs) #67 positive with leading zero limb == positive with leading zero limb
 mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0
 
-MPI compare (abs) #28 positive with leading zero limb == positive with leading zero limb
+MPI compare (abs) #68 positive with leading zero limb == positive with leading zero limb
 mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0
 
-MPI compare (abs) #29 positive with leading zero limb < large positive
+MPI compare (abs) #69 positive with leading zero limb < large positive
 mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1
 
-MPI compare (abs) #30 positive with leading zero limb < large positive
+MPI compare (abs) #70 positive with leading zero limb < large positive
 mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1
 
-MPI compare (abs) #31 positive with leading zero limb == positive with leading zero limb
+MPI compare (abs) #71 positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"":1
+
+MPI compare (abs) #72 positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"0":1
+
+MPI compare (abs) #73 positive with leading zero limb > 0 (null)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"":1
+
+MPI compare (abs) #74 positive with leading zero limb > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"0000000000000000123":"0":1
+
+MPI compare (abs) #75 positive with leading zero limb > positive
+mbedtls_mpi_cmp_abs:"0000000000000000123":"7b":1
+
+MPI compare (abs) #76 positive with leading zero limb > positive
+mbedtls_mpi_cmp_abs:"0000000000000000123":"7b":1
+
+MPI compare (abs) #77 positive with leading zero limb == positive with leading zero limb
 mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0
 
-MPI compare (abs) #32 positive with leading zero limb < large positive
+MPI compare (abs) #78 positive with leading zero limb == positive with leading zero limb
+mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0
+
+MPI compare (abs) #79 positive with leading zero limb < large positive
 mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1
 
-MPI compare (abs) #33 positive with leading zero limb < large positive
+MPI compare (abs) #80 positive with leading zero limb < large positive
 mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1
 
-MPI compare (abs) #34 large positive == large positive
+MPI compare (abs) #81 large positive > 0 (null)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"":1
+
+MPI compare (abs) #82 large positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0":1
+
+MPI compare (abs) #83 large positive > 0 (null)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"":1
+
+MPI compare (abs) #84 large positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0":1
+
+MPI compare (abs) #85 large positive > positive
+mbedtls_mpi_cmp_abs:"1230000000000000000":"7b":1
+
+MPI compare (abs) #86 large positive > positive
+mbedtls_mpi_cmp_abs:"1230000000000000000":"7b":1
+
+MPI compare (abs) #87 large positive > positive with leading zero limb
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0000000000000000123":1
+
+MPI compare (abs) #88 large positive > positive with leading zero limb
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0000000000000000123":1
+
+MPI compare (abs) #89 large positive == large positive
 mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0
 
-MPI compare (abs) #35 large positive == large positive
+MPI compare (abs) #90 large positive == large positive
 mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0
 
-MPI compare (abs) #36 large positive == large positive
+MPI compare (abs) #91 large positive > 0 (null)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"":1
+
+MPI compare (abs) #92 large positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0":1
+
+MPI compare (abs) #93 large positive > 0 (null)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"":1
+
+MPI compare (abs) #94 large positive > 0 (1 limb)
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0":1
+
+MPI compare (abs) #95 large positive > positive
+mbedtls_mpi_cmp_abs:"1230000000000000000":"7b":1
+
+MPI compare (abs) #96 large positive > positive
+mbedtls_mpi_cmp_abs:"1230000000000000000":"7b":1
+
+MPI compare (abs) #97 large positive > positive with leading zero limb
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0000000000000000123":1
+
+MPI compare (abs) #98 large positive > positive with leading zero limb
+mbedtls_mpi_cmp_abs:"1230000000000000000":"0000000000000000123":1
+
+MPI compare (abs) #99 large positive == large positive
 mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0
 
-MPI compare (abs) #37 positive < positive
+MPI compare (abs) #100 large positive == large positive
+mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0
+
+MPI compare (abs) #101 positive < positive
 mbedtls_mpi_cmp_abs:"2":"3":-1
 
-MPI compare (abs) #38 positive == positive
+MPI compare (abs) #102 positive == positive
 mbedtls_mpi_cmp_abs:"2":"2":0
 
-MPI compare (abs) #39 positive < positive
+MPI compare (abs) #103 positive < positive
 mbedtls_mpi_cmp_abs:"2b4":"2b5":-1
 
-MPI compare (abs) #40 positive < positive
+MPI compare (abs) #104 positive < positive
 mbedtls_mpi_cmp_abs:"2b5":"2b6":-1
 
 # End of automatically generated file.
diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data
index 2ab5924..9da54ff 100644
--- a/tests/suites/test_suite_bignum.misc.data
+++ b/tests/suites/test_suite_bignum.misc.data
@@ -1141,6 +1141,18 @@
 Test mbedtls_mpi_div_mpi: 0 (null) / -1
 mbedtls_mpi_div_mpi:"":"-1":"":"":0
 
+Test mbedtls_mpi_div_mpi: -0 (null) / 1
+mbedtls_mpi_div_mpi:"-":"1":"":"":0
+
+Test mbedtls_mpi_div_mpi: -0 (null) / -1
+mbedtls_mpi_div_mpi:"-":"-1":"":"":0
+
+Test mbedtls_mpi_div_mpi: -0 (null) / 42
+mbedtls_mpi_div_mpi:"-":"2a":"":"":0
+
+Test mbedtls_mpi_div_mpi: -0 (null) / -42
+mbedtls_mpi_div_mpi:"-":"-2a":"":"":0
+
 Test mbedtls_mpi_div_mpi #1
 mbedtls_mpi_div_mpi:"9e22d6da18a33d1ef28d2a82242b3f6e9c9742f63e5d440f58a190bfaf23a7866e67589adb80":"22":"4a6abf75b13dc268ea9cc8b5b6aaf0ac85ecd437a4e0987fb13cf8d2acc57c0306c738c1583":"1a":0
 
@@ -1201,6 +1213,18 @@
 Test mbedtls_mpi_mod_mpi: 0 (null) % -1
 mbedtls_mpi_mod_mpi:"":"-1":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
 
+Test mbedtls_mpi_mod_mpi: -0 (null) % 1
+mbedtls_mpi_mod_mpi:"-":"1":"":0
+
+Test mbedtls_mpi_mod_mpi: -0 (null) % -1
+mbedtls_mpi_mod_mpi:"-":"-1":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
+Test mbedtls_mpi_mod_mpi: -0 (null) % 42
+mbedtls_mpi_mod_mpi:"-":"2a":"":0
+
+Test mbedtls_mpi_mod_mpi: -0 (null) % -42
+mbedtls_mpi_mod_mpi:"-":"-2a":"":MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+
 Base test mbedtls_mpi_mod_int #1
 mbedtls_mpi_mod_int:"3e8":"d":"c":0