diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 1e1c06330f..297c0a6ba4 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -974,6 +974,8 @@ int mbedtls_mpi_random(mbedtls_mpi *X, * \brief Compute the greatest common divisor: G = gcd(A, B) * * \param G The destination MPI. This must point to an initialized MPI. + * This will be positive unless \p B is 0, in which case \p A + * will be returned, where \p A could be negative. * \param A The first operand. This must point to an initialized MPI. * \param B The second operand. This must point to an initialized MPI. * @@ -988,10 +990,12 @@ 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 and be greater than one. * * \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..f710bb5939 100644 --- a/tests/suites/test_suite_bignum.function +++ b/tests/suites/test_suite_bignum.function @@ -390,12 +390,24 @@ 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); + + /* Test pointer aliasing where &Z == &X. */ + TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_X), 0); + TEST_EQUAL(mbedtls_mpi_gcd(&Z, /* X */ &Z, &Y), 0); + TEST_ASSERT(sign_is_valid(&Z)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); + + /* Test pointer aliasing where &Z == &Y. */ + TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_Y), 0); + TEST_EQUAL(mbedtls_mpi_gcd(&Z, &X, /* Y */ &Z), 0); + TEST_ASSERT(sign_is_valid(&Z)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); exit: mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); @@ -1134,14 +1146,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); + } + + /* Test pointer aliasing where &Z == &X. */ + TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_X), 0); + res = mbedtls_mpi_inv_mod(&Z, /* X */ &Z, &Y); + TEST_EQUAL(res, div_result); + if (res == 0) { + TEST_ASSERT(sign_is_valid(&Z)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); + } + + /* Test pointer aliasing where &Z == &Y. */ + TEST_EQUAL(mbedtls_test_read_mpi(&Z, input_Y), 0); + res = mbedtls_mpi_inv_mod(&Z, &X, /* Y */ &Z); + TEST_EQUAL(res, div_result); + if (res == 0) { + TEST_ASSERT(sign_is_valid(&Z)); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &A), 0); } exit: diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data index 2e3ff1ecc0..c6701b2567 100644 --- a/tests/suites/test_suite_bignum.misc.data +++ b/tests/suites/test_suite_bignum.misc.data @@ -1435,6 +1435,9 @@ mpi_gcd:"":"":"0" Test GCD: 0 (null), 0 (1 limb) mpi_gcd:"":"00":"0" +Test GCD: 0 (1 limb), 0 (1 limb) +mpi_gcd:"00":"00":"0" + Test GCD: 0 (null), 3 mpi_gcd:"":"03":"3" @@ -1462,48 +1465,57 @@ mpi_gcd:"06":"":"6" Test GCD: 6, 0 (1 limb) mpi_gcd:"06":"00":"6" -Test GCD: gcd=1, 0 < A < B +Test GCD: negative, 0 (null) +mpi_gcd:"-50000":"":"-50000" + +Test GCD: negative, 0 (1 limb) +mpi_gcd:"-a782374b2ee927df28802745833a":"00":"-a782374b2ee927df28802745833a" + +Test GCD: gcd=1, A is odd, B is odd, 0 < A < B mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1" -Test GCD: gcd=1, 0 < B < A +Test GCD: gcd=1, A is odd, B is odd, 0 < B < A mpi_gcd:"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"1" -Test GCD: gcd=1, A > 0, B < 0 +Test GCD: gcd=1, A is odd, B is odd, A > 0, B < 0 mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1" -Test GCD: gcd=1, A < 0 < B, |A| < |B| +Test GCD: gcd=1, A is odd, B is odd, A < 0 < B, |A| < |B| mpi_gcd:"-109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1" -Test GCD: gcd=1, B < A < 0 +Test GCD: gcd=1, A is odd, B is odd, B < A < 0 mpi_gcd:"-109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-33ae3764fd06a00cdc3cba5c45dc79a9edb4e67e4d057cc74139d531c25190d111775fc4a0f4439b8b1930bbd766e7b46f170601f316c8a18ff8d5cb5ca5581f168345d101edb462b7d93b7c520ccb8fb276b447a63d869203cc11f67a1122dc4da034218de85e39":"1" -Test GCD: gcd=2, 0 < A < B +Test GCD: gcd=2, A is even, B is even, 0 < A < B mpi_gcd:"213fc8ae290cdcadfba95b36d6d0dbe4e4495f6f0d19e9e1976f28a4d2650a797e17dd4c2b282ccca9a279b3fc1b3b4b2952fdc40461e25f6a869bce7f69f0204e4b402c4566363d485c744ca032073583be630d37b2f261af25f6e59b552e3b15002b5e":"675c6ec9fa0d4019b87974b88bb8f353db69ccfc9a0af98e8273aa6384a321a222eebf8941e8873716326177aecdcf68de2e0c03e62d91431ff1ab96b94ab03e2d068ba203db68c56fb276f8a419971f64ed688f4c7b0d24079823ecf42245b89b4068431bd0bc72":"2" -Test GCD: gcd=2, 0 < B < A +Test GCD: gcd=2, A is even, B is even, 0 < B < A mpi_gcd:"675c6ec9fa0d4019b87974b88bb8f353db69ccfc9a0af98e8273aa6384a321a222eebf8941e8873716326177aecdcf68de2e0c03e62d91431ff1ab96b94ab03e2d068ba203db68c56fb276f8a419971f64ed688f4c7b0d24079823ecf42245b89b4068431bd0bc72":"213fc8ae290cdcadfba95b36d6d0dbe4e4495f6f0d19e9e1976f28a4d2650a797e17dd4c2b282ccca9a279b3fc1b3b4b2952fdc40461e25f6a869bce7f69f0204e4b402c4566363d485c744ca032073583be630d37b2f261af25f6e59b552e3b15002b5e":"2" -Test GCD: gcd=3, 0 < A < B +Test GCD: gcd=3, A is odd, B is odd, 0 < A < B mpi_gcd:"31dfad053d934b04f97e08d2423949d7566e0f2693a6ded26326bcf73b978fb63d23cbf240bc4332fe73b68dfa28d8f0bdfc7ca60692d38f1fc9e9b5bf1ee8307570e0426819515bec8aae72f04b0ad0459d9493d38c6b9286b8f25868ffc5589f80410d":"9b0aa62ef713e02694b62f14d1956cfdc91eb37ae7107655c3ad7f9546f4b27334661f4de2dccad2a14b92338634b71d4d451205d94459e4afea816215f0085d4389d17305c91d28278bb274f62662af17641cd6f2b893b60b6435e36e336894e8e09c64a9b91aab":"3" -Test GCD: gcd=3, 0 < B < A +Test GCD: gcd=3, A is odd, B is odd, 0 < B < A mpi_gcd:"9b0aa62ef713e02694b62f14d1956cfdc91eb37ae7107655c3ad7f9546f4b27334661f4de2dccad2a14b92338634b71d4d451205d94459e4afea816215f0085d4389d17305c91d28278bb274f62662af17641cd6f2b893b60b6435e36e336894e8e09c64a9b91aab":"31dfad053d934b04f97e08d2423949d7566e0f2693a6ded26326bcf73b978fb63d23cbf240bc4332fe73b68dfa28d8f0bdfc7ca60692d38f1fc9e9b5bf1ee8307570e0426819515bec8aae72f04b0ad0459d9493d38c6b9286b8f25868ffc5589f80410d":"3" -Test GCD: gcd=4, 0 < A < B +Test GCD: gcd=4, A is even, B is even, 0 < A < B mpi_gcd:"427f915c5219b95bf752b66dada1b7c9c892bede1a33d3c32ede5149a4ca14f2fc2fba98565059995344f367f836769652a5fb8808c3c4bed50d379cfed3e0409c9680588acc6c7a90b8e89940640e6b077cc61a6f65e4c35e4bedcb36aa5c762a0056bc":"ceb8dd93f41a803370f2e9711771e6a7b6d399f93415f31d04e754c70946434445dd7f1283d10e6e2c64c2ef5d9b9ed1bc5c1807cc5b22863fe3572d7295607c5a0d174407b6d18adf64edf148332e3ec9dad11e98f61a480f3047d9e8448b713680d08637a178e4":"4" -Test GCD: gcd=4, 0 < B < A +Test GCD: gcd=4, A is even, B is even, 0 < B < A mpi_gcd:"ceb8dd93f41a803370f2e9711771e6a7b6d399f93415f31d04e754c70946434445dd7f1283d10e6e2c64c2ef5d9b9ed1bc5c1807cc5b22863fe3572d7295607c5a0d174407b6d18adf64edf148332e3ec9dad11e98f61a480f3047d9e8448b713680d08637a178e4":"427f915c5219b95bf752b66dada1b7c9c892bede1a33d3c32ede5149a4ca14f2fc2fba98565059995344f367f836769652a5fb8808c3c4bed50d379cfed3e0409c9680588acc6c7a90b8e89940640e6b077cc61a6f65e4c35e4bedcb36aa5c762a0056bc":"4" -Test GCD: gcd=6, 0 < A < B +Test GCD: gcd=6, A is even, B is even, 0 < A < B mpi_gcd:"63bf5a0a7b269609f2fc11a4847293aeacdc1e4d274dbda4c64d79ee772f1f6c7a4797e481788665fce76d1bf451b1e17bf8f94c0d25a71e3f93d36b7e3dd060eae1c084d032a2b7d9155ce5e09615a08b3b2927a718d7250d71e4b0d1ff8ab13f00821a":"136154c5dee27c04d296c5e29a32ad9fb923d66f5ce20ecab875aff2a8de964e668cc3e9bc5b995a5429724670c696e3a9a8a240bb288b3c95fd502c42be010ba8713a2e60b923a504f1764e9ec4cc55e2ec839ade571276c16c86bc6dc66d129d1c138c953723556":"6" -Test GCD: gcd=6, 0 < B < A +Test GCD: gcd=6, A is even, B is even, 0 < B < A mpi_gcd:"136154c5dee27c04d296c5e29a32ad9fb923d66f5ce20ecab875aff2a8de964e668cc3e9bc5b995a5429724670c696e3a9a8a240bb288b3c95fd502c42be010ba8713a2e60b923a504f1764e9ec4cc55e2ec839ade571276c16c86bc6dc66d129d1c138c953723556":"63bf5a0a7b269609f2fc11a4847293aeacdc1e4d274dbda4c64d79ee772f1f6c7a4797e481788665fce76d1bf451b1e17bf8f94c0d25a71e3f93d36b7e3dd060eae1c084d032a2b7d9155ce5e09615a08b3b2927a718d7250d71e4b0d1ff8ab13f00821a":"6" -Test GCD: 0 < A = B +Test GCD: A is odd, B is odd, 0 < A = B mpi_gcd:"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"109fe45714866e56fdd4ad9b6b686df27224afb7868cf4f0cbb794526932853cbf0beea61594166654d13cd9fe0d9da594a97ee20230f12fb5434de73fb4f8102725a01622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af" +Test GCD: A is odd, B is odd, A = B < 0 +mpi_gcd:"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"-9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af":"9986dabb54d13cd9fe0d9da594a97e8372ab26ed98ff622b31b1ea42e3a265019039ac1df31869bd97930d792fb72cdaa971d8a8015af" + Base test mbedtls_mpi_inv_mod #1 mpi_inv_mod:"3":"b":"4":0 @@ -1513,15 +1525,60 @@ mpi_inv_mod:"3":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA Test mbedtls_mpi_inv_mod: mod 0 (1 limb) mpi_inv_mod:"3":"0":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA +Test mbedtls_mpi_inv_mod: 0 (null) mod positive +mpi_inv_mod:"":"25":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + +Test mbedtls_mpi_inv_mod: 0 (1 limb) mod positive +mpi_inv_mod:"00":"25":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + +Test mbedtls_mpi_inv_mod: 0 (null) mod 0 (null) +mpi_inv_mod:"":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 0 (1 limb) +mpi_inv_mod:"00":"00":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (null) mod 0 (1 limb) +mpi_inv_mod:"":"00":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 0 (null) +mpi_inv_mod:"00":"":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + Test mbedtls_mpi_inv_mod: mod negative mpi_inv_mod:"3":"-b":"4":MBEDTLS_ERR_MPI_BAD_INPUT_DATA +Test mbedtls_mpi_inv_mod: negative mod negative +mpi_inv_mod:"-3543a":"-f":"5":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 1 mod negative +mpi_inv_mod:"1":"-f":"1":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (null) mod negative +mpi_inv_mod:"":"-f":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (1 limb) mod negative +mpi_inv_mod:"00":"-f":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + Test mbedtls_mpi_inv_mod: 2^-1 mod 4 mpi_inv_mod:"2":"4":"0":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE Test mbedtls_mpi_inv_mod: mod 1 mpi_inv_mod:"3":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA +Test mbedtls_mpi_inv_mod: negative mod 1 +mpi_inv_mod:"-732487665ae082f75c44":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 1 mod 1 +mpi_inv_mod:"1":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: larger positive mod 1 +mpi_inv_mod:"aaf97513ce987d99d9d934e":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (null) mod 1 +mpi_inv_mod:"":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +Test mbedtls_mpi_inv_mod: 0 (1 limb) mod 1 +mpi_inv_mod:"00":"1":"0":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + Test mbedtls_mpi_inv_mod: 0 (null) ^-1 mpi_inv_mod:"":"11":"":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE