From c98871339d8b80c120d40b2611840c8c9bb90b2c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 24 Aug 2022 12:54:36 +0100 Subject: [PATCH 1/6] Extract MPI_CORE(add) from the prototype Signed-off-by: Tom Cosgrove --- library/bignum_core.c | 18 +++++++++++++++--- library/bignum_core.h | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 00837298b0..3f4e6510aa 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -316,8 +316,6 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *X, return( 0 ); } - - void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, size_t count ) { @@ -360,7 +358,21 @@ void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, } } - +mbedtls_mpi_uint MPI_CORE(add)( mbedtls_mpi_uint *d, + const mbedtls_mpi_uint *l, + const mbedtls_mpi_uint *r, + size_t n ) +{ + mbedtls_mpi_uint c = 0, t; + for( size_t i = 0; i < n; i++ ) + { + t = c; + t += l[i]; c = ( t < l[i] ); + t += r[i]; c += ( t < r[i] ); + d[i] = t; + } + return( c ); +} mbedtls_mpi_uint mbedtls_mpi_core_add_if( mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, diff --git a/library/bignum_core.h b/library/bignum_core.h index 56a3bf874f..0d7b89f20a 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -277,6 +277,29 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A, void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, size_t count ); +#define MPI_CORE(func) mbedtls_mpi_core_ ## func ## _minimal + +/** + * \brief Add two known-size large unsigned integers, returning the carry. + * + * Calculate l + r where l and r have the same size. + * This function operates modulo (2^ciL)^n and returns the carry + * (1 if there was a wraparound, and 0 otherwise). + * + * d may be aliased to l or r. + * + * \param[out] d The result of the addition. + * \param[in] l The left operand. + * \param[in] r The right operand. + * \param n Number of limbs of \p d, \p l and \p r. + * + * \return 1 if `l + r >= (2^{ciL})^n`, 0 otherwise. + */ +mbedtls_mpi_uint MPI_CORE(add)( mbedtls_mpi_uint *d, + const mbedtls_mpi_uint *l, + const mbedtls_mpi_uint *r, + size_t n ); + /** * \brief Conditional addition of two fixed-size large unsigned integers, * returning the carry. From af7d44b4d2a098317dea61c7692757f5b827713f Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 24 Aug 2022 14:05:26 +0100 Subject: [PATCH 2/6] Tidy up, remove MPI_CORE(), apply the naming convention, and use the new mbedtls_mpi_core_add() Signed-off-by: Tom Cosgrove --- library/bignum.c | 31 ++++++++++++++----------------- library/bignum_core.c | 23 +++++++++++++---------- library/bignum_core.h | 29 ++++++++++++++--------------- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 58cd2f7329..f30df2bc59 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -867,8 +867,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i, j; - mbedtls_mpi_uint *o, *p, c, tmp; + size_t j; MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( A != NULL ); MPI_VALIDATE_RET( B != NULL ); @@ -882,7 +881,7 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); /* - * X should always be positive as a result of unsigned additions. + * X must always be positive as a result of unsigned additions. */ X->s = 1; @@ -892,27 +891,25 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); - o = B->p; p = X->p; c = 0; + /* j is the number of non-zero limbs of B. Add those to X. */ - /* - * tmp is used because it might happen that p == o - */ - for( i = 0; i < j; i++, o++, p++ ) - { - tmp= *o; - *p += c; c = ( *p < c ); - *p += tmp; c += ( *p < tmp ); - } + mbedtls_mpi_uint *p = X->p; + + mbedtls_mpi_uint c = mbedtls_mpi_core_add( p, p, B->p, j); + + p += j; + + /* Now propagate any carry */ while( c != 0 ) { - if( i >= X->n ) + if( j >= X->n ) { - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) ); - p = X->p + i; + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j + 1 ) ); + p = X->p + j; } - *p += c; c = ( *p < c ); i++; p++; + *p += c; c = ( *p < c ); j++; p++; } cleanup: diff --git a/library/bignum_core.c b/library/bignum_core.c index 3f4e6510aa..6862316c46 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -358,19 +358,22 @@ void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, } } -mbedtls_mpi_uint MPI_CORE(add)( mbedtls_mpi_uint *d, - const mbedtls_mpi_uint *l, - const mbedtls_mpi_uint *r, - size_t n ) +mbedtls_mpi_uint mbedtls_mpi_core_add( mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs ) { - mbedtls_mpi_uint c = 0, t; - for( size_t i = 0; i < n; i++ ) + mbedtls_mpi_uint c = 0; + + for( size_t i = 0; i < limbs; i++ ) { - t = c; - t += l[i]; c = ( t < l[i] ); - t += r[i]; c += ( t < r[i] ); - d[i] = t; + mbedtls_mpi_uint t = c + A[i]; + c = ( t < A[i] ); + t += B[i]; + c += ( t < B[i] ); + X[i] = t; } + return( c ); } diff --git a/library/bignum_core.h b/library/bignum_core.h index 0d7b89f20a..8cc985ef33 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -277,28 +277,27 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A, void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, size_t count ); -#define MPI_CORE(func) mbedtls_mpi_core_ ## func ## _minimal - /** - * \brief Add two known-size large unsigned integers, returning the carry. + * \brief Add two fixed-size large unsigned integers, returning the carry. * - * Calculate l + r where l and r have the same size. - * This function operates modulo (2^ciL)^n and returns the carry + * Calculates `A + B` where `A` and `B` have the same size. + * + * This function operates modulo 2^(biL*limbs) and returns the carry * (1 if there was a wraparound, and 0 otherwise). * - * d may be aliased to l or r. + * \p X may be aliased to \p A or \p B. * - * \param[out] d The result of the addition. - * \param[in] l The left operand. - * \param[in] r The right operand. - * \param n Number of limbs of \p d, \p l and \p r. + * \param[out] X The result of the addition. + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs of \p X, \p A and \p B. * - * \return 1 if `l + r >= (2^{ciL})^n`, 0 otherwise. + * \return 1 if `A + B >= 2^(biL*limbs)`, 0 otherwise. */ -mbedtls_mpi_uint MPI_CORE(add)( mbedtls_mpi_uint *d, - const mbedtls_mpi_uint *l, - const mbedtls_mpi_uint *r, - size_t n ); +mbedtls_mpi_uint mbedtls_mpi_core_add( mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs ); /** * \brief Conditional addition of two fixed-size large unsigned integers, From eee0d6ce6bcf5f280f9986f2679d2e3dd43c4736 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 25 Oct 2022 12:45:50 +0100 Subject: [PATCH 3/6] Extend the unit tests for mbedtls_mpi_core_add_if() to also test mbedtls_mpi_core_add() Signed-off-by: Tom Cosgrove --- scripts/mbedtls_dev/bignum_core.py | 8 +-- tests/suites/test_suite_bignum_core.function | 64 +++++++++++++++----- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index e46364b1a4..0d238e714b 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -144,12 +144,12 @@ class BignumCoreOperationArchSplit(BignumCoreOperation): yield cls(a_value, b_value, 32).create_test_case() yield cls(a_value, b_value, 64).create_test_case() -class BignumCoreAddIf(BignumCoreOperationArchSplit): - """Test cases for bignum core add if.""" +class BignumCoreAddAndAddIf(BignumCoreOperationArchSplit): + """Test cases for bignum core add and add-if.""" count = 0 symbol = "+" - test_function = "mpi_core_add_if" - test_name = "mbedtls_mpi_core_add_if" + test_function = "mpi_core_add_and_add_if" + test_name = "mpi_core_add_and_add_if" def result(self) -> List[str]: result = self.int_a + self.int_b diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index fb5fe3ae49..1cd8b40819 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -359,41 +359,52 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void mpi_core_add_if( char * input_A, char * input_B, - char * input_S, int carry ) +void mpi_core_add_and_add_if( char * input_A, char * input_B, + char * input_S, int carry ) { mbedtls_mpi_uint *A = NULL; /* first value to add */ - size_t A_limbs; mbedtls_mpi_uint *B = NULL; /* second value to add */ - size_t B_limbs; mbedtls_mpi_uint *S = NULL; /* expected result */ - size_t S_limbs; mbedtls_mpi_uint *X = NULL; /* destination - the in/out first operand */ - size_t X_limbs; + size_t A_limbs, B_limbs, S_limbs; TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) ); TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) ); TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &S, &S_limbs, input_S ) ); - X_limbs = S_limbs; - ASSERT_ALLOC( X, X_limbs ); - /* add_if expects all operands to be the same length */ + /* add and add_if expect all operands to be the same length */ TEST_EQUAL( A_limbs, B_limbs ); TEST_EQUAL( A_limbs, S_limbs ); size_t limbs = A_limbs; size_t bytes = limbs * sizeof( *A ); + ASSERT_ALLOC( X, limbs ); + /* The test cases have A <= B to avoid repetition, so we test A + B then, * if A != B, B + A. If A == B, we can test when A and B are aliased */ /* A + B */ - /* cond = 0 => X unchanged, no carry */ + /* add => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add, alias output and first operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add, alias output and second operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add_if: cond = 0 => X unchanged, no carry */ memcpy( X, A, bytes ); TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) ); ASSERT_COMPARE( X, bytes, A, bytes ); - /* cond = 1 => correct result and carry */ + /* add_if: cond = 1 => correct result and carry */ TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) ); ASSERT_COMPARE( X, bytes, S, bytes ); @@ -401,12 +412,21 @@ void mpi_core_add_if( char * input_A, char * input_B, { /* A == B, so test where A and B are aliased */ - /* cond = 0 => X unchanged, no carry */ + /* add => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add, output aliased to both operands => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add_if: cond = 0 => X unchanged, no carry */ memcpy( X, B, bytes ); TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) ); ASSERT_COMPARE( X, bytes, B, bytes ); - /* cond = 1 => correct result and carry */ + /* add_if: cond = 1 => correct result and carry */ TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) ); ASSERT_COMPARE( X, bytes, S, bytes ); } @@ -414,12 +434,26 @@ void mpi_core_add_if( char * input_A, char * input_B, { /* A != B, so test B + A */ - /* cond = 0 => d unchanged, no carry */ + /* add => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add, alias output and first operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add, alias output and second operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* add_if: cond = 0 => d unchanged, no carry */ memcpy( X, B, bytes ); TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) ); ASSERT_COMPARE( X, bytes, B, bytes ); - /* cond = 1 => correct result and carry */ + /* add_if: cond = 1 => correct result and carry */ TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) ); ASSERT_COMPARE( X, bytes, S, bytes ); } From 82f131063a871f40f9cd06ceb59735530514f4ef Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 25 Oct 2022 12:46:03 +0100 Subject: [PATCH 4/6] Update documentation following review comment Signed-off-by: Tom Cosgrove --- library/bignum_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum_core.h b/library/bignum_core.h index 8cc985ef33..084af74878 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -282,7 +282,7 @@ void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, * * Calculates `A + B` where `A` and `B` have the same size. * - * This function operates modulo 2^(biL*limbs) and returns the carry + * This function operates modulo `2^(biL*limbs)` and returns the carry * (1 if there was a wraparound, and 0 otherwise). * * \p X may be aliased to \p A or \p B. From 6469fdfb0aa44da4ccb7e55a692deaf02a9bf14c Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 25 Oct 2022 12:46:13 +0100 Subject: [PATCH 5/6] Fix whitespace issue spotted in review Signed-off-by: Tom Cosgrove --- library/bignum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum.c b/library/bignum.c index f30df2bc59..d33f07cc46 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -895,7 +895,7 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi mbedtls_mpi_uint *p = X->p; - mbedtls_mpi_uint c = mbedtls_mpi_core_add( p, p, B->p, j); + mbedtls_mpi_uint c = mbedtls_mpi_core_add( p, p, B->p, j ); p += j; From 93003d87a93879f647251b2f7994f1e57d1b2e9f Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 25 Oct 2022 17:01:19 +0100 Subject: [PATCH 6/6] Split out testing of core_add and core_add_if per Janos' request Signed-off-by: Tom Cosgrove --- tests/suites/test_suite_bignum_core.function | 230 ++++++++++++------- 1 file changed, 151 insertions(+), 79 deletions(-) diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 1cd8b40819..c5ef62dde5 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -5,6 +5,154 @@ #include "constant_time_internal.h" #include "test/constant_flow.h" +/** Verifies mbedtls_mpi_core_add(). + * + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). + * \param[in] S Little-endian presentation of the expected sum. + * \param carry Expected carry from the addition. + * \param[in,out] X Temporary storage to be used for results. + * + * \return 1 if mbedtls_mpi_core_add() passes this test, otherwise 0. + */ +static int mpi_core_verify_add( mbedtls_mpi_uint *A, + mbedtls_mpi_uint *B, + size_t limbs, + mbedtls_mpi_uint *S, + int carry, + mbedtls_mpi_uint *X ) +{ + int ret = 0; + + size_t bytes = limbs * sizeof( *A ); + + /* The test cases have A <= B to avoid repetition, so we test A + B then, + * if A != B, B + A. If A == B, we can test when A and B are aliased */ + + /* A + B */ + + /* A + B => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + B; alias output and first operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + B; alias output and second operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + if ( memcmp( A, B, bytes ) == 0 ) + { + /* A == B, so test where A and B are aliased */ + + /* A + A => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + A, output aliased to both operands => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + else + { + /* A != B, so test B + A */ + + /* B + A => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* B + A; alias output and first operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* B + A; alias output and second operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + + ret = 1; + +exit: + return ret; +} + +/** Verifies mbedtls_mpi_core_add_if(). + * + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). + * \param[in] S Little-endian presentation of the expected sum. + * \param carry Expected carry from the addition. + * \param[in,out] X Temporary storage to be used for results. + * + * \return 1 if mbedtls_mpi_core_add_if() passes this test, otherwise 0. + */ +static int mpi_core_verify_add_if( mbedtls_mpi_uint *A, + mbedtls_mpi_uint *B, + size_t limbs, + mbedtls_mpi_uint *S, + int carry, + mbedtls_mpi_uint *X ) +{ + int ret = 0; + + size_t bytes = limbs * sizeof( *A ); + + /* The test cases have A <= B to avoid repetition, so we test A + B then, + * if A != B, B + A. If A == B, we can test when A and B are aliased */ + + /* A + B */ + + /* cond = 0 => X unchanged, no carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, A, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + if ( memcmp( A, B, bytes ) == 0 ) + { + /* A == B, so test where A and B are aliased */ + + /* cond = 0 => X unchanged, no carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, B, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + else + { + /* A != B, so test B + A */ + + /* cond = 0 => d unchanged, no carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, B, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + + ret = 1; + +exit: + return ret; +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -375,88 +523,12 @@ void mpi_core_add_and_add_if( char * input_A, char * input_B, /* add and add_if expect all operands to be the same length */ TEST_EQUAL( A_limbs, B_limbs ); TEST_EQUAL( A_limbs, S_limbs ); - size_t limbs = A_limbs; - size_t bytes = limbs * sizeof( *A ); + size_t limbs = A_limbs; ASSERT_ALLOC( X, limbs ); - /* The test cases have A <= B to avoid repetition, so we test A + B then, - * if A != B, B + A. If A == B, we can test when A and B are aliased */ - - /* A + B */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and first operand => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and second operand => correct result and carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => X unchanged, no carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, A, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - if ( memcmp( A, B, bytes ) == 0 ) - { - /* A == B, so test where A and B are aliased */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, output aliased to both operands => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => X unchanged, no carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, B, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - } - else - { - /* A != B, so test B + A */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and first operand => correct result and carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and second operand => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => d unchanged, no carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, B, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - } + TEST_ASSERT( mpi_core_verify_add( A, B, limbs, S, carry, X ) ); + TEST_ASSERT( mpi_core_verify_add_if( A, B, limbs, S, carry, X ) ); exit: mbedtls_free( A );