From 9646537e94fe16b0f113a1171c17e5457251ac7c Mon Sep 17 00:00:00 2001 From: Felix Conway Date: Thu, 24 Jul 2025 15:25:00 +0100 Subject: [PATCH] Improve testing of mbedtls_mpi_gcd() and mbedtls_mpi_inv_mod() Signed-off-by: Felix Conway --- include/mbedtls/bignum.h | 7 +++- tests/suites/test_suite_bignum.function | 49 +++++++++++++++++++----- tests/suites/test_suite_bignum.misc.data | 3 ++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 1e1c06330f..ed0c4e798e 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -988,10 +988,13 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, * \brief Compute the modular inverse: X = A^-1 mod N * * \param X The destination MPI. This must point to an initialized MPI. + * The value returned on success will be between [1, N-1]. * \param A The MPI to calculate the modular inverse of. This must point - * to an initialized MPI. + * to an initialized MPI. This value can be negative, in which + * case a positive answer will still be returned in \p X. * \param N The base of the modular inversion. This must point to an - * initialized MPI. + * initialized MPI. If this points to the same MPI as \p X, + * then the value returned in \p X will be incorrect. * * \return \c 0 if successful. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function index 36f1476d76..c94e7ccf85 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -390,12 +390,23 @@ void mpi_gcd(char *input_X, char *input_Y, mbedtls_mpi A, X, Y, Z; mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); - TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0); - TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0); + TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&Y, input_Y), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0); + TEST_EQUAL(mbedtls_mpi_gcd(&Z, &X, &Y), 0); TEST_ASSERT(sign_is_valid(&Z)); - TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); + + mbedtls_mpi *Z_alias_X = &X; + TEST_EQUAL(mbedtls_mpi_gcd(Z_alias_X, &X, &Y), 0); + TEST_ASSERT(sign_is_valid(Z_alias_X)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(Z_alias_X, &A), 0); + + mbedtls_mpi *Z_alias_Y = &Y; + TEST_EQUAL(mbedtls_mpi_gcd(Z_alias_Y, &X, &Y), 0); + TEST_ASSERT(sign_is_valid(Z_alias_Y)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(Z_alias_Y, &A), 0); + exit: mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); @@ -1134,14 +1145,32 @@ void mpi_inv_mod(char *input_X, char *input_Y, int res; mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A); - TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0); + TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&Y, input_Y), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0); res = mbedtls_mpi_inv_mod(&Z, &X, &Y); - TEST_ASSERT(res == div_result); + TEST_EQUAL(res, div_result); if (res == 0) { TEST_ASSERT(sign_is_valid(&Z)); - TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); + } + + mbedtls_mpi *Z_alias_X = &X; + res = mbedtls_mpi_inv_mod(Z_alias_X, &X, &Y); + TEST_EQUAL(res, div_result); + if (res == 0) { + TEST_ASSERT(sign_is_valid(Z_alias_X)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(Z_alias_X, &A), 0); + } + + /* When Z is an alias of Y, the answer returned in Z is normally incorrect. */ + mbedtls_mpi *Z_alias_Y = &Y; + res = mbedtls_mpi_inv_mod(Z_alias_Y, &X, &Y); + TEST_EQUAL(res, div_result); + if (res == 0) { + TEST_ASSERT(sign_is_valid(Z_alias_Y)); + /* Testing if Z_alias_Y == &A is not useful as it is true sometimes, but is + often false. */ } exit: diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data index 2e3ff1ecc0..d4c730059d 100644 --- a/tests/suites/test_suite_bignum.misc.data +++ b/tests/suites/test_suite_bignum.misc.data @@ -1504,6 +1504,9 @@ mpi_gcd:"136154c5dee27c04d296c5e29a32ad9fb923d66f5ce20ecab875aff2a8de964e668cc3e Test GCD: 0 < A = B mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af" +Test GCD: A = B < 0 +mpi_gcd:"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af" + Base test mbedtls_mpi_inv_mod #1 mpi_inv_mod:"3":"b":"4":0