From 42df16c84b4720588d5694700b92493233a092e5 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 1 Feb 2023 13:58:04 +0100 Subject: [PATCH 01/20] Extract Secp521r1 from the prototype Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 65 +++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 2a97b8c000..a1a21c27a4 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5189,11 +5189,6 @@ cleanup: MBEDTLS_ECP_DP_SECP384R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - /* Size of p521 in terms of mbedtls_mpi_uint */ #define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) @@ -5201,48 +5196,56 @@ cleanup: #define P521_MASK 0x01FF /* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 + * Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) */ static int ecp_mod_p521(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + size_t expected_width = 2 * ((521 + biL - 1) / biL); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); + ret = ecp_mod_p521_raw(N->p, expected_width); +cleanup: + return ret; +} +static int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) +{ + mbedtls_mpi_uint carry = 0; - if (N->n < P521_WIDTH) { + if (N_n > 2*P521_WIDTH) { + N_n = 2*P521_WIDTH; + } + if (N_n < P521_WIDTH) { return 0; } - /* M = A1 */ - M.s = 1; - M.n = N->n - (P521_WIDTH - 1); - if (M.n > P521_WIDTH + 1) { - M.n = P521_WIDTH + 1; - } - M.p = Mp; - memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint)))); + /* Step 1: Reduction to P521_WIDTH limbs */ + if (N_n > P521_WIDTH) { + /* Helper references for top part of N */ + mbedtls_mpi_uint *NT_p = N_p + P521_WIDTH; + size_t NT_n = N_n - P521_WIDTH; - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for (i = P521_WIDTH; i < N->n; i++) { - N->p[i] = 0; + /* Split N as A0 + 2^(512 + biL) A1 and compute A0 + 2^(biL - 9) * A1. + * This can be done in place. */ + mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); + carry = MPI_CORE(mla)(N_p, P521_WIDTH, NT_p, NT_n, shift); + + /* Clear top part */ + memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); } - /* N = A0 + A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); + /* Step 2: Reduction to < 2p. + * Now split as A0 + 2^521 * c, with c a scalar, and compute A0 + c. */ + carry <<= (biL - 9); + carry += (N_p[P521_WIDTH-1] >> 9); + N_p[P521_WIDTH-1] &= P521_MASK; + (void) mbedtls_core_add_int(N_p, N_p, carry, P521_WIDTH); -cleanup: - return ret; + return 0; } #undef P521_WIDTH #undef P521_MASK + #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ #endif /* MBEDTLS_ECP_NIST_OPTIM */ From 8450ab9c60249db6ec0855ca8539756eda6061ab Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 15:47:00 +0100 Subject: [PATCH 02/20] Fix Secp521r1 reduction The prototype calculated with wrong limb size and not taken into account the overflow in the shared limb. Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index a1a21c27a4..f58539d224 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5211,14 +5211,19 @@ static int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) { mbedtls_mpi_uint carry = 0; - if (N_n > 2*P521_WIDTH) { - N_n = 2*P521_WIDTH; + if (N_n > 2 * P521_WIDTH - 1) { + N_n = 2 * P521_WIDTH - 1; } if (N_n < P521_WIDTH) { return 0; } - /* Step 1: Reduction to P521_WIDTH limbs */ + /* Save and clear the A1 content of the shared limb to prevent it + from overwrite. */ + mbedtls_mpi_uint remainder[P521_WIDTH] = {0}; + remainder[0] = N_p[P521_WIDTH - 1] >> 9; + N_p[P521_WIDTH - 1] &= P521_MASK; + if (N_n > P521_WIDTH) { /* Helper references for top part of N */ mbedtls_mpi_uint *NT_p = N_p + P521_WIDTH; @@ -5227,18 +5232,14 @@ static int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) /* Split N as A0 + 2^(512 + biL) A1 and compute A0 + 2^(biL - 9) * A1. * This can be done in place. */ mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = MPI_CORE(mla)(N_p, P521_WIDTH, NT_p, NT_n, shift); + carry = mbedtls_mpi_core_mla(N_p, P521_WIDTH - 1, NT_p, NT_n, shift); /* Clear top part */ memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); } - /* Step 2: Reduction to < 2p. - * Now split as A0 + 2^521 * c, with c a scalar, and compute A0 + c. */ - carry <<= (biL - 9); - carry += (N_p[P521_WIDTH-1] >> 9); - N_p[P521_WIDTH-1] &= P521_MASK; - (void) mbedtls_core_add_int(N_p, N_p, carry, P521_WIDTH); + (void)mbedtls_mpi_core_add(N_p, N_p, remainder, P521_WIDTH); + N_p[P521_WIDTH - 1] += carry; return 0; } From 2cb630edee50c9799e88af39b7d52a3162cd4ec5 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 1 Feb 2023 14:02:16 +0100 Subject: [PATCH 03/20] Change the ecp_mod_p521_raw to be testable Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 6 +++++- library/ecp_invasive.h | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index f58539d224..269f5fcf90 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4584,6 +4584,8 @@ static int ecp_mod_p384(mbedtls_mpi *); #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) static int ecp_mod_p521(mbedtls_mpi *); +MBEDTLS_STATIC_TESTABLE +int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); #endif #define NIST_MODP(P) grp->modp = ecp_mod_ ## P; @@ -5207,7 +5209,9 @@ static int ecp_mod_p521(mbedtls_mpi *N) cleanup: return ret; } -static int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) + +MBEDTLS_STATIC_TESTABLE +int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) { mbedtls_mpi_uint carry = 0; diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index 3ee238ee53..31646b92d7 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -95,6 +95,13 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + +MBEDTLS_STATIC_TESTABLE +int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); + +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_INVASIVE_H */ From d8f67b975bdaca75a0eed75fad2e968fa8bd34d3 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 15:49:42 +0100 Subject: [PATCH 04/20] Add test generation for ecp_mod_p521_raw Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/ecp.py | 83 ++++++++++++++++++++++++++++ tests/suites/test_suite_ecp.function | 44 ++++++++++++++- 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 93cd2123ff..96ddd057fb 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -75,3 +75,86 @@ class EcpP192R1Raw(bignum_common.ModOperationCommon, @property def is_valid(self) -> bool: return True + +class EcpP521R1Raw(bignum_common.ModOperationCommon, + EcpTarget): + """Test cases for ecp quasi_reduction().""" + test_function = "ecp_mod_p521_raw" + test_name = "ecp_mod_p521_raw" + input_style = "fixed" + arity = 1 + + moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + ] # type: List[str] + + input_values = [ + "0", "1", + + # Test case for overflow during addition + ("0001efffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "000001ef" + "0000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000f000000"), + + # First 8 number generated by random.getrandbits(1042) - seed(2,2) + ("0003cc2e82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f" + "6e405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd" + "9b1f282e" + "4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124" + "5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"), + ("00017052829e07b0829a48d422fe99a22c70501e533c91352d3d854e061b9030" + "3b08c6e33c7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c5055" + "6c71c4a6" + "6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a" + "09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57eb"), + ("00021f15a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26" + "294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64" + "ca2ce6bc" + "5d3fd983c34c769fe89204e2e8168561867e5e15bc01bfce6a27e0dfcbf87544" + "72154e76e4c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"), + ("000381bc2a838af8d5c44a4eb3172062d08f1bb2531d6460f0caeef038c89b38" + "a8acb5137c9260dc74e088a9b9492f258ebdbfe3eb9ac688b9d39cca91551e82" + "59cc60b1" + "7604e4b4e73695c3e652c71a74667bffe202849da9643a295a9ac6decbd4d3e2" + "d4dec9ef83f0be4e80371eb97f81375eecc1cb6347733e847d718d733ff98ff3"), + ("00034816c8c69069134bccd3e1cf4f589f8e4ce0af29d115ef24bd625dd961e6" + "830b54fa7d28f93435339774bb1e386c4fd5079e681b8f5896838b769da59b74" + "a6c3181c" + "81e220df848b1df78feb994a81167346d4c0dca8b4c9e755cc9c3adcf515a823" + "4da4daeb4f3f87777ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48e86ec9c6"), + ("000397846c4454b90f756132e16dce72f18e859835e1f291d322a7353ead4efe" + "440e2b4fda9c025a22f1a83185b98f5fc11e60de1b343f52ea748db9e020307a" + "aeb6db2c" + "3a038a709779ac1f45e9dd320c855fdfa7251af0930cdbd30f0ad2a81b2d19a2" + "beaa14a7ff3fe32a30ffc4eed0a7bd04e85bfcdd0227eeb7b9d7d01f5769da05"), + ("00002c3296e6bc4d62b47204007ee4fab105d83e85e951862f0981aebc1b00d9" + "2838e766ef9b6bf2d037fe2e20b6a8464174e75a5f834da70569c018eb2b5693" + "babb7fbb" + "0a76c196067cfdcb11457d9cf45e2fa01d7f4275153924800600571fac3a5b26" + "3fdf57cd2c0064975c3747465cc36c270e8a35b10828d569c268a20eb78ac332"), + ("00009d23b4917fc09f20dbb0dcc93f0e66dfe717c17313394391b6e2e6eacb0f" + "0bb7be72bd6d25009aeb7fa0c4169b148d2f527e72daf0a54ef25c0707e33868" + "7d1f7157" + "5653a45c49390aa51cf5192bbf67da14be11d56ba0b4a2969d8055a9f03f2d71" + "581d8e830112ff0f0948eccaf8877acf26c377c13f719726fd70bddacb4deeec"), + + # Next 2 number generated by random.getrandbits(521) + ("12b84ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da1a1fe" + "3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccdf572df00790813e3"), + ("166049dd332a73fa0b26b75196cf87eb8a09b27ec714307c68c425424a1574f1" + "eedf5b0f16cdfdb839424d201e653f53d6883ca1c107ca6e706649889c0c7f38608") + ] + + @property + def arg_a(self) -> str: + return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits - 2 * self.bits_in_limb // 8) + + def result(self) -> List[str]: + result = self.int_a % self.int_n + return [self.format_result(result)] + + @property + def is_valid(self) -> bool: + return True diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index b9d2b5ea55..b1a096d046 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -4,8 +4,8 @@ #include "mbedtls/ecdh.h" #include "bignum_core.h" -#include "bignum_mod_raw_invasive.h" #include "ecp_invasive.h" +#include "bignum_mod_raw_invasive.h" #if defined(MBEDTLS_TEST_HOOKS) && \ (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ @@ -1344,3 +1344,45 @@ exit: mbedtls_free(N); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */ +void ecp_mod_p521_raw(char *input_N, + char *input_X, + char *result) +{ + mbedtls_mpi_uint *X = NULL; + mbedtls_mpi_uint *N = NULL; + mbedtls_mpi_uint *res = NULL; + size_t limbs_X; + size_t limbs_N; + size_t limbs_res; + + mbedtls_mpi_mod_modulus m; + mbedtls_mpi_mod_modulus_init(&m); + + TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0); + TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0); + TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0); + + size_t limbs = limbs_N; + size_t bytes = limbs * sizeof(mbedtls_mpi_uint); + + TEST_EQUAL(limbs_X, 2 * limbs - 1); + TEST_EQUAL(limbs_res, limbs); + + TEST_EQUAL(mbedtls_mpi_mod_modulus_setup( + &m, N, limbs, + MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); + + TEST_EQUAL(ecp_mod_p521_raw(X, limbs_X), 0); + mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m); + ASSERT_COMPARE(X, bytes, res, bytes); + +exit: + mbedtls_free(X); + mbedtls_free(res); + + mbedtls_mpi_mod_modulus_free(&m); + mbedtls_free(N); +} +/* END_CASE */ From b1c62caa1fce2e6ea10629b44e6efc912ba7c4d4 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 16:02:05 +0100 Subject: [PATCH 05/20] Add documentation Signed-off-by: Gabor Mezei --- library/ecp_invasive.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index 31646b92d7..2854fb0a96 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -97,6 +97,12 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) + * + * \param[in,out] N_p The address of the MPI to be converted. + * Must have 2 * N - 1 limbs, where N is the modulus. + * \param[in] N_n The length of \p N_p in limbs. + */ MBEDTLS_STATIC_TESTABLE int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); From b62ad5d569a1df385f6d81df10d1f804e2e27e22 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 17:13:02 +0100 Subject: [PATCH 06/20] Rename function to follow naming convention Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 6 +++--- library/ecp_invasive.h | 2 +- tests/suites/test_suite_ecp.function | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 269f5fcf90..2da4bdd92c 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4585,7 +4585,7 @@ static int ecp_mod_p384(mbedtls_mpi *); #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) static int ecp_mod_p521(mbedtls_mpi *); MBEDTLS_STATIC_TESTABLE -int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); #endif #define NIST_MODP(P) grp->modp = ecp_mod_ ## P; @@ -5205,13 +5205,13 @@ static int ecp_mod_p521(mbedtls_mpi *N) int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t expected_width = 2 * ((521 + biL - 1) / biL); MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); - ret = ecp_mod_p521_raw(N->p, expected_width); + ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); cleanup: return ret; } MBEDTLS_STATIC_TESTABLE -int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) { mbedtls_mpi_uint carry = 0; diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index 2854fb0a96..45b0006963 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -104,7 +104,7 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); * \param[in] N_n The length of \p N_p in limbs. */ MBEDTLS_STATIC_TESTABLE -int ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index b1a096d046..a0042ed348 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1374,7 +1374,7 @@ void ecp_mod_p521_raw(char *input_N, &m, N, limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); - TEST_EQUAL(ecp_mod_p521_raw(X, limbs_X), 0); + TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0); mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m); ASSERT_COMPARE(X, bytes, res, bytes); From 05c138e1722860d603894a340dcfeef5bc05f6be Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 18:03:39 +0100 Subject: [PATCH 07/20] Fix pylint issues Create a new function for calculating the number of hex digits needed for a certain amount of limbs. Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/bignum_common.py | 6 +++++- scripts/mbedtls_dev/ecp.py | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 2422175541..5319ec68b2 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -74,6 +74,10 @@ def combination_pairs(values: List[T]) -> List[Tuple[T, T]]: """Return all pair combinations from input values.""" return [(x, y) for x in values for y in values] +def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int: + """ Retrun the hex digits need for a number of limbs. """ + return 2 * (limbs * bits_in_limb // 8) + class OperationCommon(test_data_generation.BaseTest): """Common features for bignum binary operations. @@ -138,7 +142,7 @@ class OperationCommon(test_data_generation.BaseTest): @property def hex_digits(self) -> int: - return 2 * (self.limbs * self.bits_in_limb // 8) + return hex_digits_for_limb(self.limbs, self.bits_in_limb) def format_arg(self, val: str) -> str: if self.input_style not in self.input_styles: diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 96ddd057fb..c167f6b6ff 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -149,7 +149,9 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, @property def arg_a(self) -> str: - return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits - 2 * self.bits_in_limb // 8) + # Number of limbs: 2 * N - 1 + hex_digits = bignum_common.hex_digits_for_limb(2 * self.limbs - 1, self.bits_in_limb) + return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits) def result(self) -> List[str]: result = self.int_a % self.int_n From 6bfbd3650788bc82216906c9bf540f4090ee7f06 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 6 Feb 2023 18:06:54 +0100 Subject: [PATCH 08/20] Fix coding style issues Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 2da4bdd92c..00642650cc 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5224,7 +5224,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) /* Save and clear the A1 content of the shared limb to prevent it from overwrite. */ - mbedtls_mpi_uint remainder[P521_WIDTH] = {0}; + mbedtls_mpi_uint remainder[P521_WIDTH] = { 0 }; remainder[0] = N_p[P521_WIDTH - 1] >> 9; N_p[P521_WIDTH - 1] &= P521_MASK; @@ -5242,7 +5242,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); } - (void)mbedtls_mpi_core_add(N_p, N_p, remainder, P521_WIDTH); + (void) mbedtls_mpi_core_add(N_p, N_p, remainder, P521_WIDTH); N_p[P521_WIDTH - 1] += carry; return 0; From b50aeb8f0533d5f5ed981c6eeb68163fb7e3c909 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Tue, 7 Feb 2023 12:46:54 +0100 Subject: [PATCH 09/20] Fix 32-bit issues The 521 bit needs different limb alignment for different word sizes. Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/ecp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index c167f6b6ff..e0fb000354 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -81,7 +81,7 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, """Test cases for ecp quasi_reduction().""" test_function = "ecp_mod_p521_raw" test_name = "ecp_mod_p521_raw" - input_style = "fixed" + input_style = "arch_split" arity = 1 moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" From 13c3aa13af220d96b95d98f0bf47bb0105f56267 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 7 Feb 2023 15:24:57 +0000 Subject: [PATCH 10/20] Revert changes to mod_p521 flow It is not necessary to save the middle limb upfront as overwriting it is the desired result: in the first step we are reducing modulo 2^{512+biL}. Arguably, the original flow is more intuitive and easier to see the idea behind it. Signed-off-by: Janos Follath Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 00642650cc..7d029de1fc 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5222,12 +5222,6 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) return 0; } - /* Save and clear the A1 content of the shared limb to prevent it - from overwrite. */ - mbedtls_mpi_uint remainder[P521_WIDTH] = { 0 }; - remainder[0] = N_p[P521_WIDTH - 1] >> 9; - N_p[P521_WIDTH - 1] &= P521_MASK; - if (N_n > P521_WIDTH) { /* Helper references for top part of N */ mbedtls_mpi_uint *NT_p = N_p + P521_WIDTH; @@ -5236,14 +5230,17 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) /* Split N as A0 + 2^(512 + biL) A1 and compute A0 + 2^(biL - 9) * A1. * This can be done in place. */ mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = mbedtls_mpi_core_mla(N_p, P521_WIDTH - 1, NT_p, NT_n, shift); + carry = mbedtls_mpi_core_mla(N_p, P521_WIDTH, NT_p, NT_n, shift); /* Clear top part */ memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); } + mbedtls_mpi_uint remainder[P521_WIDTH] = { 0 }; + remainder[0] = carry << (biL - 9); + remainder[0] += (N_p[P521_WIDTH - 1] >> 9); + N_p[P521_WIDTH - 1] &= P521_MASK; (void) mbedtls_mpi_core_add(N_p, N_p, remainder, P521_WIDTH); - N_p[P521_WIDTH - 1] += carry; return 0; } From 755ff0e6853fbc568abb0414da21991fbabc2411 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 7 Feb 2023 15:27:44 +0000 Subject: [PATCH 11/20] Add corner case to mod_p521 tests Signed-off-by: Janos Follath Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/ecp.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index e0fb000354..fa70dedb55 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -91,6 +91,13 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, input_values = [ "0", "1", + # Corner case: maximum canonical P521 multiplication result + ("0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffff800" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000004"), + # Test case for overflow during addition ("0001efffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" From 666673e83f2e692dfd0720ed0547fdf4eabc7fd6 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 7 Feb 2023 15:49:15 +0000 Subject: [PATCH 12/20] modp521: apply naming conventions Apply the usual parameter name and align the local variables and comments. This naming diverges from the standard notation, but this is beneficial as our variable meanings diverge as well and the difference can help avoiding confusion. Signed-off-by: Janos Follath Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 7d029de1fc..186dabef20 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5211,36 +5211,39 @@ cleanup: } MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n) +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) { mbedtls_mpi_uint carry = 0; - if (N_n > 2 * P521_WIDTH - 1) { - N_n = 2 * P521_WIDTH - 1; + if (X_limbs > 2 * P521_WIDTH - 1) { + X_limbs = 2 * P521_WIDTH - 1; } - if (N_n < P521_WIDTH) { + if (X_limbs < P521_WIDTH) { return 0; } - if (N_n > P521_WIDTH) { - /* Helper references for top part of N */ - mbedtls_mpi_uint *NT_p = N_p + P521_WIDTH; - size_t NT_n = N_n - P521_WIDTH; + if (X_limbs > P521_WIDTH) { + /* Helper references for bottom part of X */ + mbedtls_mpi_uint *X0 = X; + size_t X0_limbs = P521_WIDTH; + /* Helper references for top part of X */ + mbedtls_mpi_uint *X1 = X + X0_limbs; + size_t X1_limbs = X_limbs - X0_limbs; - /* Split N as A0 + 2^(512 + biL) A1 and compute A0 + 2^(biL - 9) * A1. + /* Split X as X0 + 2^(512 + biL) X1 and compute X0 + 2^(biL - 9) * X1. * This can be done in place. */ mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = mbedtls_mpi_core_mla(N_p, P521_WIDTH, NT_p, NT_n, shift); + carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); /* Clear top part */ - memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); + memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); } - mbedtls_mpi_uint remainder[P521_WIDTH] = { 0 }; - remainder[0] = carry << (biL - 9); - remainder[0] += (N_p[P521_WIDTH - 1] >> 9); - N_p[P521_WIDTH - 1] &= P521_MASK; - (void) mbedtls_mpi_core_add(N_p, N_p, remainder, P521_WIDTH); + mbedtls_mpi_uint addend[P521_WIDTH] = { 0 }; + addend[0] = carry << (biL - 9); + addend[0] += (X[P521_WIDTH - 1] >> 9); + X[P521_WIDTH - 1] &= P521_MASK; + (void) mbedtls_mpi_core_add(X, X, addend, P521_WIDTH); return 0; } From fe24e91a34324a5ee20dd2beda5d81de53dc3fe5 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 8 Feb 2023 10:14:21 +0000 Subject: [PATCH 13/20] mod_p521: document reduction algorithm Signed-off-by: Janos Follath Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 186dabef20..74392661c7 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5222,6 +5222,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) return 0; } + /* Step 1: Reduction to P521_WIDTH limbs */ if (X_limbs > P521_WIDTH) { /* Helper references for bottom part of X */ mbedtls_mpi_uint *X0 = X; @@ -5230,20 +5231,43 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) mbedtls_mpi_uint *X1 = X + X0_limbs; size_t X1_limbs = X_limbs - X0_limbs; - /* Split X as X0 + 2^(512 + biL) X1 and compute X0 + 2^(biL - 9) * X1. - * This can be done in place. */ + /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. + * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that + * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) + * The high order limb of the result will be held in carry and the rest + * in X0 (that is the result will be represented as + * 2^P521_WIDTH carry + X0). + * + * Also, note that the resulting carry is either 0 or 1: + * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 + * therefore + * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) + * which in turn is less than 2 * 2^(512 + biL). + */ mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); - /* Clear top part */ + /* Set X to X0 (by clearing the top part). */ memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); } - mbedtls_mpi_uint addend[P521_WIDTH] = { 0 }; - addend[0] = carry << (biL - 9); - addend[0] += (X[P521_WIDTH - 1] >> 9); + /* Step 2: Reduction modulo P521 + * + * At this point X is reduced to P521_WIDTH limbs. What remains is to add + * the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */ + + /* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521. + * Also, recall that carry is either 0 or 1. */ + mbedtls_mpi_uint addend = carry << (biL - 9); + /* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */ + addend += (X[P521_WIDTH - 1] >> 9); X[P521_WIDTH - 1] &= P521_MASK; - (void) mbedtls_mpi_core_add(X, X, addend, P521_WIDTH); + /* Declare a helper array for carrying out the addition. */ + mbedtls_mpi_uint addend_arr[P521_WIDTH] = { 0 }; + addend_arr[0] = addend; + (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); + /* Both addends were less than P521 therefore X < 2 P521. (This also means + * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ return 0; } From d10d429380135040a0af53539ebd9788ef9b09f1 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 8 Feb 2023 16:27:03 +0100 Subject: [PATCH 14/20] Stack usage optimization for mod_p521 Instead of creating an mpi on the stack, reuse the unused part of the input mpi. Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 74392661c7..49182a44f9 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5262,12 +5262,22 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) /* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */ addend += (X[P521_WIDTH - 1] >> 9); X[P521_WIDTH - 1] &= P521_MASK; - /* Declare a helper array for carrying out the addition. */ - mbedtls_mpi_uint addend_arr[P521_WIDTH] = { 0 }; + + /* Resuse the top part of X (already zeroed) as a helper array for + * carrying out the addition. */ + mbedtls_mpi_uint *addend_arr = X + P521_WIDTH; addend_arr[0] = addend; - (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); - /* Both addends were less than P521 therefore X < 2 P521. (This also means - * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ + /* The unused part of X is P521_WIDTH - 1 limbs in size and only that + * size can be used for addition. Due to the addend fit in a limb + * the limbs other the first in the helper array are only used for + * propagating the carry. By adding the carry of the P521_WIDTH - 1 limb + * addition to the last limb of X makes the addition of X and the addend + * complete. */ + carry = mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH - 1); + X[P521_WIDTH - 1] += carry; + + /* Clear the reused part of X. */ + addend_arr[0] = 0; return 0; } From cf228706cdb8bab4b3b4d7a8a0281a8eda418a51 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 15 Feb 2023 16:52:33 +0100 Subject: [PATCH 15/20] Restrict input parameter size for ecp_mod_p521_raw The imput mpi parameter must have twice as many limbs as the modulus. Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 70 ++++++++++++---------------- scripts/mbedtls_dev/ecp.py | 7 ++- tests/suites/test_suite_ecp.function | 2 +- 3 files changed, 33 insertions(+), 46 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 49182a44f9..85d634ab01 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5203,7 +5203,7 @@ cleanup: static int ecp_mod_p521(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((521 + biL - 1) / biL); + size_t expected_width = 2 * P521_WIDTH; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); cleanup: @@ -5215,41 +5215,34 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) { mbedtls_mpi_uint carry = 0; - if (X_limbs > 2 * P521_WIDTH - 1) { - X_limbs = 2 * P521_WIDTH - 1; - } - if (X_limbs < P521_WIDTH) { - return 0; + if (X_limbs != 2 * P521_WIDTH || X[2 * P521_WIDTH - 1] != 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } /* Step 1: Reduction to P521_WIDTH limbs */ - if (X_limbs > P521_WIDTH) { - /* Helper references for bottom part of X */ - mbedtls_mpi_uint *X0 = X; - size_t X0_limbs = P521_WIDTH; - /* Helper references for top part of X */ - mbedtls_mpi_uint *X1 = X + X0_limbs; - size_t X1_limbs = X_limbs - X0_limbs; - - /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. - * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that - * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) - * The high order limb of the result will be held in carry and the rest - * in X0 (that is the result will be represented as - * 2^P521_WIDTH carry + X0). - * - * Also, note that the resulting carry is either 0 or 1: - * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 - * therefore - * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) - * which in turn is less than 2 * 2^(512 + biL). - */ - mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); - carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); - - /* Set X to X0 (by clearing the top part). */ - memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); - } + /* Helper references for bottom part of X */ + mbedtls_mpi_uint *X0 = X; + size_t X0_limbs = P521_WIDTH; + /* Helper references for top part of X */ + mbedtls_mpi_uint *X1 = X + X0_limbs; + size_t X1_limbs = X_limbs - X0_limbs; + /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. + * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that + * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) + * The high order limb of the result will be held in carry and the rest + * in X0 (that is the result will be represented as + * 2^P521_WIDTH carry + X0). + * + * Also, note that the resulting carry is either 0 or 1: + * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 + * therefore + * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) + * which in turn is less than 2 * 2^(512 + biL). + */ + mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); + carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); + /* Set X to X0 (by clearing the top part). */ + memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); /* Step 2: Reduction modulo P521 * @@ -5267,14 +5260,9 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) * carrying out the addition. */ mbedtls_mpi_uint *addend_arr = X + P521_WIDTH; addend_arr[0] = addend; - /* The unused part of X is P521_WIDTH - 1 limbs in size and only that - * size can be used for addition. Due to the addend fit in a limb - * the limbs other the first in the helper array are only used for - * propagating the carry. By adding the carry of the P521_WIDTH - 1 limb - * addition to the last limb of X makes the addition of X and the addend - * complete. */ - carry = mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH - 1); - X[P521_WIDTH - 1] += carry; + (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); + /* Both addends were less than P521 therefore X < 2 * P521. (This also means + * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ /* Clear the reused part of X. */ addend_arr[0] = 0; diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index fa70dedb55..d436d0a35c 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -81,7 +81,7 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, """Test cases for ecp quasi_reduction().""" test_function = "ecp_mod_p521_raw" test_name = "ecp_mod_p521_raw" - input_style = "arch_split" + input_style = "fixed" arity = 1 moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" @@ -156,9 +156,8 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, @property def arg_a(self) -> str: - # Number of limbs: 2 * N - 1 - hex_digits = bignum_common.hex_digits_for_limb(2 * self.limbs - 1, self.bits_in_limb) - return super().format_arg('{:x}'.format(self.int_a)).zfill(hex_digits) + # Number of limbs: 2 * N + return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits) def result(self) -> List[str]: result = self.int_a % self.int_n diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index a0042ed348..212dfcbf9f 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1367,7 +1367,7 @@ void ecp_mod_p521_raw(char *input_N, size_t limbs = limbs_N; size_t bytes = limbs * sizeof(mbedtls_mpi_uint); - TEST_EQUAL(limbs_X, 2 * limbs - 1); + TEST_EQUAL(limbs_X, 2 * limbs); TEST_EQUAL(limbs_res, limbs); TEST_EQUAL(mbedtls_mpi_mod_modulus_setup( From 2b064ec33221c4f41663cd0f379ef4dcd960cb1d Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 15 Feb 2023 17:04:40 +0100 Subject: [PATCH 16/20] Revert the addition of hex digit calculator function This reverts commit 0f83e15e670565147daa32fd1fac510759520e26. Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/bignum_common.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 5319ec68b2..2422175541 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -74,10 +74,6 @@ def combination_pairs(values: List[T]) -> List[Tuple[T, T]]: """Return all pair combinations from input values.""" return [(x, y) for x in values for y in values] -def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int: - """ Retrun the hex digits need for a number of limbs. """ - return 2 * (limbs * bits_in_limb // 8) - class OperationCommon(test_data_generation.BaseTest): """Common features for bignum binary operations. @@ -142,7 +138,7 @@ class OperationCommon(test_data_generation.BaseTest): @property def hex_digits(self) -> int: - return hex_digits_for_limb(self.limbs, self.bits_in_limb) + return 2 * (self.limbs * self.bits_in_limb // 8) def format_arg(self, val: str) -> str: if self.input_style not in self.input_styles: From 555b1f7e44480a6231a69328daf0e97ba2e2219c Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 15 Feb 2023 17:13:20 +0100 Subject: [PATCH 17/20] Add check for test Check the bit length of the output of ecp_mod_p521_raw. Signed-off-by: Gabor Mezei --- tests/suites/test_suite_ecp.function | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 212dfcbf9f..4e74d9b8eb 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1375,6 +1375,7 @@ void ecp_mod_p521_raw(char *input_N, MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0); + TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 522); mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m); ASSERT_COMPARE(X, bytes, res, bytes); From 7e6fcc1fbc83c8d9d613e85001fd4bf559faba88 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 15 Feb 2023 17:51:59 +0100 Subject: [PATCH 18/20] Update documentation Signed-off-by: Gabor Mezei --- library/ecp_invasive.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index 45b0006963..3d1321c525 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -99,12 +99,21 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); /** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) * - * \param[in,out] N_p The address of the MPI to be converted. - * Must have 2 * N - 1 limbs, where N is the modulus. - * \param[in] N_n The length of \p N_p in limbs. + * \param[in,out] X The address of the MPI to be converted. + * Must have twice as many limbs as the modulus + * (the modulus is 521 bits long). Upon return this + * holds the reduced value. The reduced value is + * in range `0 <= X < 2 * N` (where N is the modulus). + * and its the bitlength is one plus the bitlength + * of the modulus. + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have + * twice as many limbs as the modulus. */ MBEDTLS_STATIC_TESTABLE -int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs); #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ From 2c8e144ef6796cb0a7b20b89bae6a9d415a4204a Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 16 Feb 2023 10:25:08 +0100 Subject: [PATCH 19/20] Fix tests for 32bit Signed-off-by: Gabor Mezei --- scripts/mbedtls_dev/ecp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index d436d0a35c..6370d258aa 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -81,7 +81,7 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, """Test cases for ecp quasi_reduction().""" test_function = "ecp_mod_p521_raw" test_name = "ecp_mod_p521_raw" - input_style = "fixed" + input_style = "arch_split" arity = 1 moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" From ac70ad657650580e4b3dbc7425f52d4360cf863c Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 16 Feb 2023 19:31:21 +0100 Subject: [PATCH 20/20] Fix coding style Signed-off-by: Gabor Mezei --- library/ecp_curves.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 85d634ab01..1a027d6aa3 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5216,7 +5216,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) mbedtls_mpi_uint carry = 0; if (X_limbs != 2 * P521_WIDTH || X[2 * P521_WIDTH - 1] != 0) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } /* Step 1: Reduction to P521_WIDTH limbs */