From 4bfc65f683de16e167c36f3e3e2a7793470805e6 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 17 Jan 2025 05:57:59 -0500 Subject: [PATCH] Modify new EC private key constructors to take EC_Scalar In #4437 new EC private key constructors were added, allowing deprecation of a quite confusing combined keygen/load constructor. However these new constructors take their input as a BigInt rather than the underlying EC_Scalar. Since #4437 has not been included in a release yet we can change these to take EC_Scalar directly, and avoid further entrenchment of BigInt in EC related interfaces. --- src/examples/ecc_raw_private_key.cpp | 14 ++++++++++++-- src/lib/pubkey/ecc_key/ec_key_data.cpp | 3 --- src/lib/pubkey/ecc_key/ec_key_data.h | 2 -- src/lib/pubkey/ecc_key/ecc_key.cpp | 7 ------- src/lib/pubkey/ecc_key/ecc_key.h | 11 +---------- src/lib/pubkey/ecdh/ecdh.h | 14 +++++++------- src/lib/pubkey/ecdsa/ecdsa.h | 14 +++++++------- src/lib/pubkey/ecgdsa/ecgdsa.h | 15 +++++++-------- src/lib/pubkey/eckcdsa/eckcdsa.h | 15 +++++++-------- src/lib/pubkey/sm2/sm2.cpp | 4 ++-- src/lib/pubkey/sm2/sm2.h | 12 ++++++------ 11 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/examples/ecc_raw_private_key.cpp b/src/examples/ecc_raw_private_key.cpp index 8df12530705..5a7d8715c3d 100644 --- a/src/examples/ecc_raw_private_key.cpp +++ b/src/examples/ecc_raw_private_key.cpp @@ -14,13 +14,23 @@ int main() { Botan::hex_decode_locked("D2AC61C35CAEE918E47B0BD5E61DA9B3A5C2964AB317647DEF6DFC042A06C829"); const auto domain = Botan::EC_Group::from_name(curve_name); - const auto private_scalar = Botan::BigInt(private_scalar_bytes); + + // This function will return nullopt if the value is not in the valid range + // for the group. Note this includes the case where the bytestring is not + // exactly of length equal to the group order, here 32 bytes. + const auto private_scalar = Botan::EC_Scalar::deserialize(domain, private_scalar_bytes); + + if(!private_scalar) { + std::cerr << "Private key is invalid\n"; + return 1; + } // This loads the private scalar into an ECDH_PrivateKey. Creating an // ECDSA_PrivateKey would work the same way. - const auto private_key = Botan::ECDH_PrivateKey(domain, private_scalar); + const auto private_key = Botan::ECDH_PrivateKey(domain, private_scalar.value()); const auto public_key = private_key.public_key(); std::cout << "Private Key (PEM):\n\n" << Botan::PKCS8::PEM_encode(private_key) << '\n'; std::cout << "Public Key (PEM):\n\n" << Botan::X509::PEM_encode(*public_key) << '\n'; + return 0; } diff --git a/src/lib/pubkey/ecc_key/ec_key_data.cpp b/src/lib/pubkey/ecc_key/ec_key_data.cpp index 583de99f632..ffea08b3bb3 100644 --- a/src/lib/pubkey/ecc_key/ec_key_data.cpp +++ b/src/lib/pubkey/ecc_key/ec_key_data.cpp @@ -17,9 +17,6 @@ EC_PublicKey_Data::EC_PublicKey_Data(EC_Group group, std::span by #endif } -EC_PrivateKey_Data::EC_PrivateKey_Data(EC_Group group, const BigInt& x) : - m_group(std::move(group)), m_scalar(EC_Scalar::from_bigint(m_group, x)), m_legacy_x(m_scalar.to_bigint()) {} - EC_PrivateKey_Data::EC_PrivateKey_Data(EC_Group group, EC_Scalar x) : m_group(std::move(group)), m_scalar(std::move(x)), m_legacy_x(m_scalar.to_bigint()) {} diff --git a/src/lib/pubkey/ecc_key/ec_key_data.h b/src/lib/pubkey/ecc_key/ec_key_data.h index 7cc0f453d20..81ec019ed04 100644 --- a/src/lib/pubkey/ecc_key/ec_key_data.h +++ b/src/lib/pubkey/ecc_key/ec_key_data.h @@ -49,8 +49,6 @@ class EC_PublicKey_Data final { class EC_PrivateKey_Data final { public: - EC_PrivateKey_Data(EC_Group group, const BigInt& x); - EC_PrivateKey_Data(EC_Group group, EC_Scalar x); EC_PrivateKey_Data(EC_Group group, std::span bytes); diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp index 5d913d85fb7..5968ddb12e4 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -145,13 +145,6 @@ EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, EC_Group ec_group, bool m_domain_encoding = default_encoding_for(domain()); } -EC_PrivateKey::EC_PrivateKey(EC_Group group, const BigInt& bn_scalar, bool with_modular_inverse) { - auto scalar = EC_Scalar::from_bigint(group, bn_scalar); - m_private_key = std::make_shared(std::move(group), std::move(scalar)); - m_public_key = m_private_key->public_key(with_modular_inverse); - m_domain_encoding = default_encoding_for(domain()); -} - EC_PrivateKey::EC_PrivateKey(EC_Group ec_group, EC_Scalar x, bool with_modular_inverse) { m_private_key = std::make_shared(std::move(ec_group), std::move(x)); m_public_key = m_private_key->public_key(with_modular_inverse); diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h index d2f96163c05..3ded3b49304 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.h +++ b/src/lib/pubkey/ecc_key/ecc_key.h @@ -181,7 +181,7 @@ class BOTAN_PUBLIC_API(2, 0) EC_PrivateKey : public virtual EC_PublicKey, * TODO: Remove, once the respective deprecated constructors of the * concrete ECC algorithms is removed. */ - EC_PrivateKey(RandomNumberGenerator& rng, EC_Group domain, const BigInt& x, bool with_modular_inverse = false); + EC_PrivateKey(RandomNumberGenerator& rng, EC_Group group, const BigInt& x, bool with_modular_inverse = false); /** * Creates a new private key @@ -192,15 +192,6 @@ class BOTAN_PUBLIC_API(2, 0) EC_PrivateKey : public virtual EC_PublicKey, */ EC_PrivateKey(RandomNumberGenerator& rng, EC_Group group, bool with_modular_inverse = false); - /** - * Load a EC private key from the secret scalar - * - * If @p with_modular_inverse is set, the public key will be calculated by - * multiplying the base point with the modular inverse of x (as in ECGDSA - * and ECKCDSA), otherwise by multiplying directly with x (as in ECDSA). - */ - EC_PrivateKey(EC_Group group, const BigInt& scalar, bool with_modular_inverse = false); - /** * Load a EC private key from the secret scalar * diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index 6f7b2f2cbb7..ea6db91dcdd 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -88,27 +88,27 @@ class BOTAN_PUBLIC_API(2, 0) ECDH_PrivateKey final : public ECDH_PublicKey, /** * Create a private key from a given secret @p x - * @param domain curve parameters to bu used for this key + * @param group curve parameters to bu used for this key * @param x the private key */ - ECDH_PrivateKey(EC_Group domain, const BigInt& x) : EC_PrivateKey(std::move(domain), x) {} + ECDH_PrivateKey(EC_Group group, EC_Scalar x) : EC_PrivateKey(std::move(group), std::move(x)) {} /** * Create a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key */ - ECDH_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : EC_PrivateKey(rng, std::move(domain)) {} + ECDH_PrivateKey(RandomNumberGenerator& rng, EC_Group group) : EC_PrivateKey(rng, std::move(group)) {} /** * Generate a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key * @param x the private key; if zero, a new random key is generated */ BOTAN_DEPRECATED("Use one of the other constructors") - ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x) {} + ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& group, const BigInt& x) : + EC_PrivateKey(rng, group, x) {} std::unique_ptr public_key() const override; diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index af3c7877a1b..a5ea67a9c02 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -101,27 +101,27 @@ class BOTAN_PUBLIC_API(2, 0) ECDSA_PrivateKey final : public ECDSA_PublicKey, /** * Create a private key from a given secret @p x - * @param domain curve parameters to bu used for this key + * @param group curve parameters to bu used for this key * @param x the private key */ - ECDSA_PrivateKey(EC_Group domain, const BigInt& x) : EC_PrivateKey(std::move(domain), x) {} + ECDSA_PrivateKey(EC_Group group, EC_Scalar x) : EC_PrivateKey(std::move(group), std::move(x)) {} /** * Create a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key */ - ECDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : EC_PrivateKey(rng, std::move(domain)) {} + ECDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group group) : EC_PrivateKey(rng, std::move(group)) {} /** * Create a private key. * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key * @param x the private key (if zero, generate a new random key) */ BOTAN_DEPRECATED("Use one of the other constructors") - ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x) {} + ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& group, const BigInt& x) : + EC_PrivateKey(rng, group, x) {} bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index 111b56686a2..00d633f14bb 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -85,28 +85,27 @@ class BOTAN_PUBLIC_API(2, 0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey, /** * Create a private key from a given secret @p x - * @param domain curve parameters to bu used for this key + * @param group curve parameters to bu used for this key * @param x the private key */ - ECGDSA_PrivateKey(EC_Group domain, const BigInt& x) : EC_PrivateKey(std::move(domain), x, true) {} + ECGDSA_PrivateKey(EC_Group group, EC_Scalar x) : EC_PrivateKey(std::move(group), std::move(x), true) {} /** * Create a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key */ - ECGDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : - EC_PrivateKey(rng, std::move(domain), BigInt::zero(), true) {} + ECGDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group group) : EC_PrivateKey(rng, std::move(group), true) {} /** * Generate a new private key. * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key * @param x the private key (if zero, generate a new random key) */ BOTAN_DEPRECATED("Use one of the other constructors") - ECGDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x, true) {} + ECGDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& group, const BigInt& x) : + EC_PrivateKey(rng, group, x, true) {} std::unique_ptr public_key() const override; diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index 0c5a73f61e2..88538bc7e23 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -84,28 +84,27 @@ class BOTAN_PUBLIC_API(2, 0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey /** * Create a private key from a given secret @p x - * @param domain curve parameters to bu used for this key + * @param group curve parameters to bu used for this key * @param x the private key */ - ECKCDSA_PrivateKey(EC_Group domain, const BigInt& x) : EC_PrivateKey(std::move(domain), x, true) {} + ECKCDSA_PrivateKey(EC_Group group, EC_Scalar x) : EC_PrivateKey(std::move(group), std::move(x), true) {} /** * Create a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key */ - ECKCDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : - EC_PrivateKey(rng, std::move(domain), BigInt::zero(), true) {} + ECKCDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group group) : EC_PrivateKey(rng, std::move(group), true) {} /** * Create a private key. * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key * @param x the private key (if zero, generate a new random key) */ BOTAN_DEPRECATED("Use one of the other constructors") - ECKCDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x, true) {} + ECKCDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& group, const BigInt& x) : + EC_PrivateKey(rng, group, x, true) {} bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp index 50275455ab0..98ca49dd814 100644 --- a/src/lib/pubkey/sm2/sm2.cpp +++ b/src/lib/pubkey/sm2/sm2.cpp @@ -51,8 +51,8 @@ SM2_PrivateKey::SM2_PrivateKey(const AlgorithmIdentifier& alg_id, std::span_private_key() + EC_Scalar::one(domain())).invert()), m_da_inv_legacy(m_da_inv.to_bigint()) {} -SM2_PrivateKey::SM2_PrivateKey(EC_Group group, const BigInt& x) : - EC_PrivateKey(std::move(group), x), +SM2_PrivateKey::SM2_PrivateKey(EC_Group group, EC_Scalar x) : + EC_PrivateKey(std::move(group), std::move(x)), m_da_inv((this->_private_key() + EC_Scalar::one(domain())).invert()), m_da_inv_legacy(m_da_inv.to_bigint()) {} diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h index cce8474ac80..9403ed6007a 100644 --- a/src/lib/pubkey/sm2/sm2.h +++ b/src/lib/pubkey/sm2/sm2.h @@ -87,26 +87,26 @@ class BOTAN_PUBLIC_API(2, 2) SM2_PrivateKey final : public SM2_PublicKey, /** * Create a private key from a given secret @p x - * @param domain curve parameters to bu used for this key + * @param group curve parameters to bu used for this key * @param x the private key */ - SM2_PrivateKey(EC_Group domain, const BigInt& x); + SM2_PrivateKey(EC_Group group, EC_Scalar x); /** * Create a new private key * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key */ - SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group domain); + SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group group); /** * Create a private key. * @param rng a random number generator - * @param domain parameters to used for this key + * @param group parameters to used for this key * @param x the private key (if zero, generate a new random key) */ BOTAN_DEPRECATED("Use one of the other constructors") - SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group domain, const BigInt& x); + SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group group, const BigInt& x); bool check_key(RandomNumberGenerator& rng, bool) const override;