From d0292c2acafc75be99c283a652450c82fa0f5033 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 10 May 2023 15:46:47 +0100 Subject: [PATCH 01/10] ecp_curves: Refactored `mbedtls_ecp_mod_p255`. This patch introduces following methods, as implemented in the design prototype, and updates them to utilise the _core methods available for multiplication and addition. * `mbedtls_ecp_mod_p255()` * `mbedtls_ecp_mod_p255_raw()` An entry has been exposed in the `ecp_invasive.h` header to facilitate testing. Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 51 ++++++++++++++++++++++++++++++------------ library/ecp_invasive.h | 7 ++++++ 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 6573f8954..98e2f9519 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4604,6 +4604,8 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); /* Additional forward declarations */ #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) static int ecp_mod_p255(mbedtls_mpi *); +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); #endif #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) static int ecp_mod_p448(mbedtls_mpi *); @@ -5417,26 +5419,47 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) */ static int ecp_mod_p255(mbedtls_mpi *N) { - mbedtls_mpi_uint Mp[P255_WIDTH]; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t expected_width = 2 * ((256 + biL - 1) / biL); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); + ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); +cleanup: + return ret; +} - /* Helper references for top part of N */ - mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH; - const size_t NT_n = N->n - P255_WIDTH; - if (N->n <= P255_WIDTH) { +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) +{ + mbedtls_mpi_uint carry[P255_WIDTH]; + memset(carry, 0, sizeof(mbedtls_mpi_uint) * P255_WIDTH); + + if (X_Limbs > 2*P255_WIDTH) { + X_Limbs = 2*P255_WIDTH; + } else if (X_Limbs < P255_WIDTH) { return 0; } - if (NT_n > P255_WIDTH) { - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + + /* Step 1: Reduction to P255_WIDTH limbs */ + if (X_Limbs > P255_WIDTH) { + /* Helper references for top part of N */ + mbedtls_mpi_uint * const NT_p = X + P255_WIDTH; + const size_t NT_n = X_Limbs - P255_WIDTH; + + /* N = A0 + 38 * A1, capture carry out */ + carry[0] = mbedtls_mpi_core_mla(X, P255_WIDTH, NT_p, NT_n, 38); + /* Clear top part */ + memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); } - /* Split N as N + 2^256 M */ - memcpy(Mp, NT_p, sizeof(mbedtls_mpi_uint) * NT_n); - memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); + /* Step 2: Reduce to

> (biL - 1)); + carry[0] *= 19; - /* N = A0 + 38 * A1 */ - mbedtls_mpi_core_mla(N->p, P255_WIDTH + 1, - Mp, NT_n, - 38); + /* Clear top bit */ + X[P255_WIDTH-1] <<= 1; X[P255_WIDTH-1] >>= 1; + (void) mbedtls_mpi_core_add(X, X, &carry[0], P255_WIDTH); return 0; } diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index aadcdbc78..bea002c35 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -241,6 +241,13 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) MBEDTLS_STATIC_TESTABLE From c2c967b1f03dc5f592e886aecca0b407d53fc7ed Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 11 May 2023 09:59:05 +0100 Subject: [PATCH 02/10] ecp.py: Added tests for `mbedtls_ecp_mod_p255_raw` This patch introduces the `EcpP255Raw` test class for testing the curve using the preestablished `ecp_mod_p_generic_raw()` test. The test's logic has been updated accordingly. Signed-off-by: Minos Galanakis --- scripts/mbedtls_dev/ecp.py | 82 ++++++++++++++++++++++++++++ tests/suites/test_suite_ecp.function | 7 +++ 2 files changed, 89 insertions(+) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index c9fb5e55e..9d882819c 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -711,6 +711,88 @@ class EcpP256K1Raw(bignum_common.ModOperationCommon, return ["MBEDTLS_ECP_DP_SECP256K1"] + args +class EcpP255Raw(bignum_common.ModOperationCommon, + EcpTarget): + """Test cases for ECP 25519 fast reduction.""" + symbol = "-" + test_function = "ecp_mod_p_generic_raw" + test_name = "mbedtls_ecp_mod_p255_raw" + input_style = "fixed" + arity = 1 + dependencies = ["MBEDTLS_ECP_DP_CURVE25519_ENABLED"] + + moduli = [("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed")] # type: List[str] + + input_values = [ + "0", "1", + + # Modulus - 1 + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffec"), + + # Modulus + 1 + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffee"), + + # 2^255 - 1 + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffff"), + + # Maximum canonical P255 multiplication result + ("3fffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffec000000000000000000000000000000000000000000000000" + "0000000000000190"), + + # First 8 number generated by random.getrandbits(510) - seed(2,2) + ("1019f0d64ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5" + "e341245c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4" + "bb99f4bea973"), + ("20948fa1feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e" + "405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653" + "f8dd9b1f282e"), + ("3a1893ea5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09" + "325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f" + "57ebf30b94fa"), + ("20a6923522fe99a22c70501e533c91352d3d854e061b90303b08c6e33c" + "7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71" + "c4a66148a86f"), + ("3a248138e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4" + "c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14" + "bc4a829e07b0"), + ("2f450feab714210c665d7435c1066932f4767f26294365b2721dea3bf6" + "3f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3f" + "d983c34c769f"), + ("1d199effe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80" + "371eb97f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a8" + "3ee0761ebfd2"), + ("3423c6ec531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9" + "492f258ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e736" + "95c3e652c71a"), + + # Next 2 number generated by random.getrandbits(255) + ("62f1243644a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3" + "172062"), + ("6a606e54b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9" + "500ec9"), + ] + + @property + def arg_a(self) -> str: + 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 + return [self.format_result(result)] + + @property + def is_valid(self) -> bool: + return True + + def arguments(self): + args = super().arguments() + return ["MBEDTLS_ECP_DP_CURVE25519"] + args + + class EcpP448Raw(bignum_common.ModOperationCommon, EcpTarget): """Test cases for ECP P448 fast reduction.""" diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 250efcc67..cc8a3271e 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1348,6 +1348,13 @@ void ecp_mod_p_generic_raw(int curve_id, curve_bits = 256; curve_func = &mbedtls_ecp_mod_p256k1_raw; break; +#endif +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + limbs = 2 * limbs_N; + curve_bits = 255; + curve_func = &mbedtls_ecp_mod_p255_raw; + break; #endif default: mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__); From aada68f1bef17976d5f7ce11980bdfe7ca14f221 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 May 2023 17:10:16 +0100 Subject: [PATCH 03/10] ecp.py: Fixed types for `arguments()` overrides. Signed-off-by: Minos Galanakis --- scripts/mbedtls_dev/ecp.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 9d882819c..7626eda40 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -97,7 +97,7 @@ class EcpP192R1Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_SECP192R1"] + args @@ -174,7 +174,7 @@ class EcpP224R1Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_SECP224R1"] + args @@ -258,7 +258,7 @@ class EcpP256R1Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_SECP256R1"] + args @@ -380,7 +380,7 @@ class EcpP384R1Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_SECP384R1"] + args @@ -485,7 +485,7 @@ class EcpP521R1Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_SECP521R1"] + args @@ -721,18 +721,19 @@ class EcpP255Raw(bignum_common.ModOperationCommon, arity = 1 dependencies = ["MBEDTLS_ECP_DP_CURVE25519_ENABLED"] - moduli = [("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed")] # type: List[str] + moduli = [("7fffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffed")] # type: List[str] input_values = [ "0", "1", # Modulus - 1 ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffec"), + "ffffffec"), # Modulus + 1 ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffee"), + "ffffffee"), # 2^255 - 1 ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" @@ -788,7 +789,7 @@ class EcpP255Raw(bignum_common.ModOperationCommon, def is_valid(self) -> bool: return True - def arguments(self): + def arguments(self)-> List[str]: args = super().arguments() return ["MBEDTLS_ECP_DP_CURVE25519"] + args From 2daa374ea868a48e0dbd8de6f03d54f62ae90bd2 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 17 May 2023 15:01:08 +0100 Subject: [PATCH 04/10] ecp_curves: Minor refactoring of `mbedtls_ecp_mod_p255_raw()` * Fixed whitespace issues. * Renamed variables to align with bignum conventions. * Updated alignment on test input data. Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 24 ++++++--------- scripts/mbedtls_dev/ecp.py | 60 +++++++++++++++----------------------- 2 files changed, 32 insertions(+), 52 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 98e2f9519..fe62fec4d 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5420,7 +5420,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p255(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((256 + biL - 1) / biL); + size_t expected_width = 2 * ((255 + biL - 1) / biL); MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); cleanup: @@ -5433,32 +5433,26 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) mbedtls_mpi_uint carry[P255_WIDTH]; memset(carry, 0, sizeof(mbedtls_mpi_uint) * P255_WIDTH); - if (X_Limbs > 2*P255_WIDTH) { - X_Limbs = 2*P255_WIDTH; - } else if (X_Limbs < P255_WIDTH) { - return 0; - } - /* Step 1: Reduction to P255_WIDTH limbs */ if (X_Limbs > P255_WIDTH) { - /* Helper references for top part of N */ - mbedtls_mpi_uint * const NT_p = X + P255_WIDTH; - const size_t NT_n = X_Limbs - P255_WIDTH; + /* Helper references for top part of X */ + mbedtls_mpi_uint * const A1 = X + P255_WIDTH; + const size_t A1_limbs = X_Limbs - P255_WIDTH; - /* N = A0 + 38 * A1, capture carry out */ - carry[0] = mbedtls_mpi_core_mla(X, P255_WIDTH, NT_p, NT_n, 38); + /* X = A0 + 38 * A1, capture carry out */ + carry[0] = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38); /* Clear top part */ - memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); + memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs); } /* Step 2: Reduce to

> (biL - 1)); + carry[0] += (X[P255_WIDTH - 1] >> (biL - 1)); carry[0] *= 19; /* Clear top bit */ - X[P255_WIDTH-1] <<= 1; X[P255_WIDTH-1] >>= 1; + X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1; (void) mbedtls_mpi_core_add(X, X, &carry[0], P255_WIDTH); return 0; diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 7626eda40..02db438a7 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -728,53 +728,39 @@ class EcpP255Raw(bignum_common.ModOperationCommon, "0", "1", # Modulus - 1 - ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffec"), + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"), # Modulus + 1 - ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffee"), + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee"), # 2^255 - 1 - ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffff"), + ("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), # Maximum canonical P255 multiplication result - ("3fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffec000000000000000000000000000000000000000000000000" - "0000000000000190"), + ("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec" + "0000000000000000000000000000000000000000000000000000000000000190"), # First 8 number generated by random.getrandbits(510) - seed(2,2) - ("1019f0d64ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5" - "e341245c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4" - "bb99f4bea973"), - ("20948fa1feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e" - "405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653" - "f8dd9b1f282e"), - ("3a1893ea5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09" - "325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f" - "57ebf30b94fa"), - ("20a6923522fe99a22c70501e533c91352d3d854e061b90303b08c6e33c" - "7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71" - "c4a66148a86f"), - ("3a248138e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4" - "c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14" - "bc4a829e07b0"), - ("2f450feab714210c665d7435c1066932f4767f26294365b2721dea3bf6" - "3f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3f" - "d983c34c769f"), - ("1d199effe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80" - "371eb97f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a8" - "3ee0761ebfd2"), - ("3423c6ec531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9" - "492f258ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e736" - "95c3e652c71a"), + ("1019f0d64ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124" + "5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"), + ("20948fa1feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f6e405d93" + "ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd9b1f282e"), + ("3a1893ea5186ee32ee8d7ee9770348a05d300cb90706a045defc044a09325626" + "e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57ebf30b94fa"), + ("20a6923522fe99a22c70501e533c91352d3d854e061b90303b08c6e33c729578" + "2d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f"), + ("3a248138e8168561867e5e15bc01bfce6a27e0dfcbf8754472154e76e4c11ab2" + "fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f15c14bc4a829e07b0"), + ("2f450feab714210c665d7435c1066932f4767f26294365b2721dea3bf63f23d0" + "dbe53fcafb2147df5ca495fa5a91c89b97eeab64ca2ce6bc5d3fd983c34c769f"), + ("1d199effe202849da9643a295a9ac6decbd4d3e2d4dec9ef83f0be4e80371eb9" + "7f81375eecc1cb6347733e847d718d733ff98ff387c56473a7a83ee0761ebfd2"), + ("3423c6ec531d6460f0caeef038c89b38a8acb5137c9260dc74e088a9b9492f25" + "8ebdbfe3eb9ac688b9d39cca91551e8259cc60b17604e4b4e73695c3e652c71a"), # Next 2 number generated by random.getrandbits(255) - ("62f1243644a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3" - "172062"), - ("6a606e54b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9" - "500ec9"), + ("62f1243644a4a8f69dc8db48e86ec9c6e06f291b2a838af8d5c44a4eb3172062"), + ("6a606e54b4c9e755cc9c3adcf515a8234da4daeb4f3f87777ad1f45ae9500ec9"), ] @property From 65c386ee3dd6423622f5152cc6e5400b23dbb62b Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 17 May 2023 18:18:13 +0100 Subject: [PATCH 05/10] ecp_curves: Switched to dynamic memory for Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index fe62fec4d..16800aadc 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -22,6 +22,7 @@ #if defined(MBEDTLS_ECP_LIGHT) #include "mbedtls/ecp.h" +#include "mbedtls/platform.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" @@ -5430,8 +5431,10 @@ cleanup: MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) { - mbedtls_mpi_uint carry[P255_WIDTH]; - memset(carry, 0, sizeof(mbedtls_mpi_uint) * P255_WIDTH); + mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL); + if (carry == NULL) { + return MBEDTLS_ERR_ECP_ALLOC_FAILED; + } /* Step 1: Reduction to P255_WIDTH limbs */ if (X_Limbs > P255_WIDTH) { @@ -5440,21 +5443,22 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) const size_t A1_limbs = X_Limbs - P255_WIDTH; /* X = A0 + 38 * A1, capture carry out */ - carry[0] = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38); + *carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38); /* Clear top part */ memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs); } /* Step 2: Reduce to

> (biL - 1)); - carry[0] *= 19; + *carry <<= 1; + *carry += (X[P255_WIDTH - 1] >> (biL - 1)); + *carry *= 19; /* Clear top bit */ X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1; - (void) mbedtls_mpi_core_add(X, X, &carry[0], P255_WIDTH); + (void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH); + mbedtls_free(carry); return 0; } #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ From 31f0b452c7b76531ff1d6cf1851ae159f76d1b3c Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 18 May 2023 11:08:50 +0100 Subject: [PATCH 06/10] ecp_curves: Reintroduced input checking for Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 16800aadc..180815292 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5431,6 +5431,13 @@ cleanup: MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) { + + if (X_Limbs > 2*P255_WIDTH) { + X_Limbs = 2*P255_WIDTH; + } else if (X_Limbs < P255_WIDTH) { + return 0; + } + mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL); if (carry == NULL) { return MBEDTLS_ERR_ECP_ALLOC_FAILED; From 47249fd9ec96167b9caf91769fc55463f77ce6f6 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 18 May 2023 16:16:17 +0100 Subject: [PATCH 07/10] ecp_curves: Added documentation for mbedtls_ecp_mod_p255_raw Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 2 +- library/ecp_invasive.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 180815292..2ad14e108 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5435,7 +5435,7 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) if (X_Limbs > 2*P255_WIDTH) { X_Limbs = 2*P255_WIDTH; } else if (X_Limbs < P255_WIDTH) { - return 0; + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL); diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index bea002c35..e73bdb1ef 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -243,6 +243,22 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +/** Fast quasi-reduction modulo p255 = 2^255 - 19 + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 510-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (255 bits). + * \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 does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. + */ MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); From d6beda7af973f2d8fa6b0ec6eb903f3ad3176df5 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 22 May 2023 11:23:56 +0100 Subject: [PATCH 08/10] ecp_curves: Extended documentation for CURVE25519. Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 9 ++++++++- library/ecp_invasive.h | 2 -- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 2ad14e108..c9868f39d 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5455,7 +5455,7 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs); } - /* Step 2: Reduce to

> (biL - 1)); @@ -5463,6 +5463,13 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) /* Clear top bit */ X[P255_WIDTH - 1] <<= 1; X[P255_WIDTH - 1] >>= 1; + /* Since the top bit for X has been cleared 0 + 0 + Carry + * will not overflow. + * + * Furthermore for 2p = 2^256-38. When a carry propagation on the highest + * limb occurs, X > 2^255 and all the remaining bits on the limb are zero. + * - If X < 2^255 ==> X < 2p + * - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */ (void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH); mbedtls_free(carry); diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index e73bdb1ef..746eea16e 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -250,8 +250,6 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); * (double the bitlength of the modulus). * Upon return holds the reduced value which is * in range `0 <= X < 2 * N` (where N is the modulus). - * The bitlength of the reduced value is the same as - * that of the modulus (255 bits). * \param[in] X_limbs The length of \p X in limbs. * * \return \c 0 on success. From ec00b500b52a4a8cbe398a76efa20bcbdad6ffea Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 23 May 2023 17:31:01 +0100 Subject: [PATCH 09/10] ecp_curves: Adjusted input checking for `ecp_mod_p255`. Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index c9868f39d..6192f6a64 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5432,9 +5432,7 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs) { - if (X_Limbs > 2*P255_WIDTH) { - X_Limbs = 2*P255_WIDTH; - } else if (X_Limbs < P255_WIDTH) { + if (X_Limbs != 2 * P255_WIDTH) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } From e72bf2da3d66c0a69231fd88e58f41e4c94b6170 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 24 May 2023 15:13:21 +0100 Subject: [PATCH 10/10] ecp_curves: Adjusted the expected limb size for `ecp_mod_p255()`. Signed-off-by: Minos Galanakis --- 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 6192f6a64..4fc4b1d83 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -5421,7 +5421,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) static int ecp_mod_p255(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t expected_width = 2 * ((255 + biL - 1) / biL); + size_t expected_width = 2 * P255_WIDTH; MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); ret = mbedtls_ecp_mod_p255_raw(N->p, expected_width); cleanup: