Skip to content

Commit

Permalink
Split loading and generating ECC private key c'tors
Browse files Browse the repository at this point in the history
All ECC schemes provided a single constructor for both key gen and key
loading. Its behavior depended on the optional x parameter to be non-zero.
  • Loading branch information
reneme committed Nov 18, 2024
1 parent 162a389 commit 370860d
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 19 deletions.
18 changes: 17 additions & 1 deletion src/lib/pubkey/ecdh/ecdh.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,29 @@ class BOTAN_PUBLIC_API(2, 0) ECDH_PrivateKey final : public ECDH_PublicKey,
ECDH_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> 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> public_key() const override;
Expand Down
18 changes: 17 additions & 1 deletion src/lib/pubkey/ecdsa/ecdsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,29 @@ class BOTAN_PUBLIC_API(2, 0) ECDSA_PrivateKey final : public ECDSA_PublicKey,
ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> 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;
Expand Down
19 changes: 18 additions & 1 deletion src/lib/pubkey/ecgdsa/ecgdsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,30 @@ class BOTAN_PUBLIC_API(2, 0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey,
ECGDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> 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> public_key() const override;
Expand Down
19 changes: 18 additions & 1 deletion src/lib/pubkey/eckcdsa/eckcdsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,30 @@ class BOTAN_PUBLIC_API(2, 0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey
ECKCDSA_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> 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;
Expand Down
34 changes: 21 additions & 13 deletions src/lib/pubkey/gost_3410/gost_3410.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t> GOST_3410_PublicKey::public_key_bits() const {
auto bits = public_point().xy_bytes();

Expand Down Expand Up @@ -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<uint8_t> 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");
}

Expand All @@ -86,13 +93,14 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, std:
m_public_key = std::make_shared<EC_PublicKey_Data>(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<Public_Key> GOST_3410_PrivateKey::public_key() const {
return std::make_unique<GOST_3410_PublicKey>(domain(), public_point());
Expand Down
17 changes: 16 additions & 1 deletion src/lib/pubkey/gost_3410/gost_3410.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const uint8_t> 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> public_key() const override;

Expand Down
10 changes: 10 additions & 0 deletions src/lib/pubkey/sm2/sm2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ SM2_PrivateKey::SM2_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<cons
m_da_inv((this->_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()),
Expand Down
17 changes: 16 additions & 1 deletion src/lib/pubkey/sm2/sm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,28 @@ class BOTAN_PUBLIC_API(2, 2) SM2_PrivateKey final : public SM2_PublicKey,
*/
SM2_PrivateKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> 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;

Expand Down

0 comments on commit 370860d

Please sign in to comment.