diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index 2c43cc7565d..288a3d98c55 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -77,13 +77,29 @@ class BOTAN_PUBLIC_API(2, 0) ECDH_PrivateKey final : public ECDH_PublicKey, ECDH_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : EC_PrivateKey(alg_id, key_bits) {} + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + ECDH_PrivateKey(const EC_Group& domain, const BigInt& x) : + EC_PrivateKey(domain, EC_Scalar::from_bigint(domain, x)) {} + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + ECDH_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : EC_PrivateKey(rng, std::move(domain)) {} + /** * Generate a new private key * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key; if zero, a new random key is generated */ - ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = BigInt::zero()) : + BOTAN_DEPRECATED("Use one of the other constructors") + ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : EC_PrivateKey(rng, domain, 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 9376938a9d9..8f08ca54cfd 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -90,13 +90,29 @@ class BOTAN_PUBLIC_API(2, 0) ECDSA_PrivateKey final : public ECDSA_PublicKey, ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : EC_PrivateKey(alg_id, key_bits) {} + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + ECDSA_PrivateKey(const EC_Group& domain, const BigInt& x) : + EC_PrivateKey(domain, EC_Scalar::from_bigint(domain, x)) {} + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + ECDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : EC_PrivateKey(rng, std::move(domain)) {} + /** * Create a private key. * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key (if zero, generate a new random key) */ - ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = BigInt::zero()) : + BOTAN_DEPRECATED("Use one of the other constructors") + ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : EC_PrivateKey(rng, domain, 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 7b176c6c173..cfc51087901 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -74,13 +74,30 @@ class BOTAN_PUBLIC_API(2, 0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey, ECGDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : EC_PrivateKey(alg_id, key_bits, true) {} + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + ECGDSA_PrivateKey(const EC_Group& domain, const BigInt& x) : + EC_PrivateKey(domain, EC_Scalar::from_bigint(domain, x), true) {} + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + ECGDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : + EC_PrivateKey(rng, std::move(domain), BigInt::zero(), true) {} + /** * Generate a new private key. * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key (if zero, generate a new random key) */ - ECGDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = BigInt::zero()) : + 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) {} std::unique_ptr public_key() const override; diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index 365481539df..ff4733b31cd 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -73,13 +73,30 @@ class BOTAN_PUBLIC_API(2, 0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey ECKCDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : EC_PrivateKey(alg_id, key_bits, true) {} + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + ECKCDSA_PrivateKey(const EC_Group& domain, const BigInt& x) : + EC_PrivateKey(domain, EC_Scalar::from_bigint(domain, x), true) {} + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + ECKCDSA_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : + EC_PrivateKey(rng, std::move(domain), BigInt::zero(), true) {} + /** * Create a private key. * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key (if zero, generate a new random key) */ - ECKCDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = BigInt::zero()) : + 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) {} bool check_key(RandomNumberGenerator& rng, bool) const override; diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index 1747b321fd3..53619e665d4 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -17,6 +17,18 @@ namespace Botan { +namespace { + +EC_Group check_domain(EC_Group domain) { + const size_t p_bits = domain.get_p_bits(); + if(p_bits != 256 && p_bits != 512) { + throw Decoding_Error(fmt("GOST-34.10-2012 is not defined for parameters of size {}", p_bits)); + } + return domain; +} + +} // namespace + std::vector GOST_3410_PublicKey::public_key_bits() const { auto bits = public_point().xy_bytes(); @@ -60,17 +72,12 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, std: // The parameters also includes hash and cipher OIDs BER_Decoder(alg_id.parameters()).start_sequence().decode(ecc_param_id); - auto group = EC_Group::from_OID(ecc_param_id); - - const size_t p_bits = group.get_p_bits(); - if(p_bits != 256 && p_bits != 512) { - throw Decoding_Error(fmt("GOST-34.10-2012 is not defined for parameters of size {}", p_bits)); - } + auto group = check_domain(EC_Group::from_OID(ecc_param_id)); std::vector bits; BER_Decoder(key_bits).decode(bits, ASN1_Type::OctetString); - if(bits.size() != 2 * (p_bits / 8)) { + if(bits.size() != 2 * (group.get_p_bits() / 8)) { throw Decoding_Error("GOST-34.10-2012 invalid encoding of public key"); } @@ -86,13 +93,14 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, std: m_public_key = std::make_shared(std::move(group), encoding); } +GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Group& domain, const BigInt& x) : + EC_PrivateKey(check_domain(domain), EC_Scalar::from_bigint(domain, x)) {} + +GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, EC_Group domain) : + EC_PrivateKey(rng, check_domain(std::move(domain))) {} + GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x) { - const size_t p_bits = domain.get_p_bits(); - if(p_bits != 256 && p_bits != 512) { - throw Decoding_Error(fmt("GOST-34.10-2012 is not defined for parameters of size {}", p_bits)); - } -} + EC_PrivateKey(rng, check_domain(domain), x) {} std::unique_ptr GOST_3410_PrivateKey::public_key() const { return std::make_unique(domain(), public_point()); diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index 74283ff83fb..45e89d0f3df 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -82,13 +82,28 @@ class BOTAN_PUBLIC_API(2, 0) GOST_3410_PrivateKey final : public GOST_3410_Publi GOST_3410_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : EC_PrivateKey(alg_id, key_bits) {} + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + GOST_3410_PrivateKey(const EC_Group& domain, const BigInt& x); + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + GOST_3410_PrivateKey(RandomNumberGenerator& rng, EC_Group domain); + /** * Generate a new private key * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key; if zero, a new random key is generated */ - GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x = BigInt::zero()); + BOTAN_DEPRECATED("Use one of the other constructors") + GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x); std::unique_ptr public_key() const override; diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp index 8f1db0ad8d3..10c1dba64b1 100644 --- a/src/lib/pubkey/sm2/sm2.cpp +++ b/src/lib/pubkey/sm2/sm2.cpp @@ -51,6 +51,16 @@ 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(const EC_Group& group, const BigInt& x) : + EC_PrivateKey(group, EC_Scalar::from_bigint(group, x)), + m_da_inv((this->_private_key() + EC_Scalar::one(domain())).invert()), + m_da_inv_legacy(m_da_inv.to_bigint()) {} + +SM2_PrivateKey::SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group group) : + EC_PrivateKey(rng, std::move(group)), + m_da_inv((this->_private_key() + EC_Scalar::one(domain())).invert()), + m_da_inv_legacy(m_da_inv.to_bigint()) {} + SM2_PrivateKey::SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group group, const BigInt& x) : EC_PrivateKey(rng, std::move(group), x), m_da_inv((this->_private_key() + EC_Scalar::one(domain())).invert()), diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h index 2f4e540ac7a..04e5aa0d16b 100644 --- a/src/lib/pubkey/sm2/sm2.h +++ b/src/lib/pubkey/sm2/sm2.h @@ -76,13 +76,28 @@ class BOTAN_PUBLIC_API(2, 2) SM2_PrivateKey final : public SM2_PublicKey, */ SM2_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits); + /** + * Create a private key from a given secret @p x + * @param domain curve parameters to bu used for this key + * @param x the private key + */ + SM2_PrivateKey(const EC_Group& domain, const BigInt& x); + + /** + * Create a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + */ + SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group domain); + /** * Create a private key. * @param rng a random number generator * @param domain parameters to used for this key * @param x the private key (if zero, generate a new random key) */ - SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group domain, const BigInt& x = BigInt::zero()); + BOTAN_DEPRECATED("Use one of the other constructors") + SM2_PrivateKey(RandomNumberGenerator& rng, EC_Group domain, const BigInt& x); bool check_key(RandomNumberGenerator& rng, bool) const override;