aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-01-31 14:03:05 -0500
committerJack Lloyd <[email protected]>2018-01-31 14:03:05 -0500
commite5b9ee2345affb56307070298ded9c2d5e1914be (patch)
tree7311fb0a10a99ccaf8cb82eecdea26d9fbe3d458 /src/lib
parent439d2ead033142365f092c7882bad31e4257ed09 (diff)
Use shared representation of EC_Group
Hide CurveGFp with an eye for eventual removal
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ffi/ffi_pkey_algs.cpp8
-rw-r--r--src/lib/prov/pkcs11/p11_ecc_key.cpp10
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp249
-rw-r--r--src/lib/pubkey/ec_group/ec_group.h92
-rw-r--r--src/lib/pubkey/ecc_key/ecc_key.cpp19
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp18
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp13
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp4
-rw-r--r--src/lib/pubkey/sm2/sm2.cpp6
-rw-r--r--src/lib/pubkey/sm2/sm2_enc.cpp6
-rw-r--r--src/lib/tls/tls_callbacks.cpp2
11 files changed, 304 insertions, 123 deletions
diff --git a/src/lib/ffi/ffi_pkey_algs.cpp b/src/lib/ffi/ffi_pkey_algs.cpp
index a20d7de40..7091708a8 100644
--- a/src/lib/ffi/ffi_pkey_algs.cpp
+++ b/src/lib/ffi/ffi_pkey_algs.cpp
@@ -96,7 +96,7 @@ int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
return BOTAN_FFI_ERROR_NULL_POINTER;
Botan::EC_Group grp(curve_name);
- Botan::PointGFp uncompressed_point(grp.get_curve(), public_x, public_y);
+ Botan::PointGFp uncompressed_point = grp.point(public_x, public_y);
key.reset(new ECPublicKey_t(grp, uncompressed_point));
return BOTAN_FFI_SUCCESS;
}
@@ -149,11 +149,11 @@ Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
else if(field == "base_y")
return ecc->domain().get_base_point().get_affine_y();
else if(field == "p")
- return ecc->domain().get_curve().get_p();
+ return ecc->domain().get_p();
else if(field == "a")
- return ecc->domain().get_curve().get_a();
+ return ecc->domain().get_a();
else if(field == "b")
- return ecc->domain().get_curve().get_b();
+ return ecc->domain().get_b();
else if(field == "cofactor")
return ecc->domain().get_cofactor();
else if(field == "order")
diff --git a/src/lib/prov/pkcs11/p11_ecc_key.cpp b/src/lib/prov/pkcs11/p11_ecc_key.cpp
index df55b9ffb..3a0fa6350 100644
--- a/src/lib/prov/pkcs11/p11_ecc_key.cpp
+++ b/src/lib/prov/pkcs11/p11_ecc_key.cpp
@@ -17,11 +17,11 @@ namespace Botan {
namespace PKCS11 {
namespace {
/// Converts a DER-encoded ANSI X9.62 ECPoint to PointGFp
-PointGFp decode_public_point(const secure_vector<uint8_t>& ec_point_data, const CurveGFp& curve)
+PointGFp decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group)
{
secure_vector<uint8_t> ec_point;
BER_Decoder(ec_point_data).decode(ec_point, OCTET_STRING);
- return OS2ECP(ec_point, curve);
+ return group.OS2ECP(ec_point);
}
}
@@ -44,7 +44,7 @@ PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle)
{
secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
m_domain_params = EC_Group(unlock(ec_parameters));
- m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params.get_curve());
+ m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params);
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
}
@@ -55,7 +55,7 @@ PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImp
secure_vector<uint8_t> ec_point;
BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
- m_public_key = OS2ECP(ec_point, m_domain_params.get_curve());
+ m_public_key = m_domain_params.OS2ECP(ec_point);
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
}
@@ -100,7 +100,7 @@ PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const std::vector<u
this->reset_handle(priv_key_handle);
Object public_key(session, pub_key_handle);
- m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params.get_curve());
+ m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params);
}
size_t PKCS11_EC_PrivateKey::key_length() const
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp
index 6ae8c16d8..8a3ffa718 100644
--- a/src/lib/pubkey/ec_group/ec_group.cpp
+++ b/src/lib/pubkey/ec_group/ec_group.cpp
@@ -2,7 +2,7 @@
* ECC Domain Parameters
*
* (C) 2007 Falko Strenzke, FlexSecure GmbH
-* 2008 Jack Lloyd
+* 2008,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -16,56 +16,42 @@
namespace Botan {
-EC_Group::EC_Group(const OID& domain_oid)
+struct EC_Group_Data
{
- const std::string pem = PEM_for_named_group(OIDS::lookup(domain_oid));
+ CurveGFp m_curve;
+ PointGFp m_base_point;
+ BigInt m_order;
+ BigInt m_cofactor;
+ OID m_oid;
+ size_t m_p_bits, m_p_bytes;
+ };
- if(pem == "")
- {
- throw Lookup_Error("No ECC domain data for '" + domain_oid.as_string() + "'");
- }
+namespace {
- *this = EC_Group(pem);
- m_oid = domain_oid.as_string();
- }
+std::shared_ptr<EC_Group_Data> lookup_EC_group_by_oid(const OID& oid);
-EC_Group::EC_Group(const std::string& str)
+std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len)
{
- if(str == "")
- return; // no initialization / uninitialized
-
- try
- {
- std::vector<uint8_t> ber =
- unlock(PEM_Code::decode_check_label(str, "EC PARAMETERS"));
-
- *this = EC_Group(ber);
- }
- catch(Decoding_Error) // hmm, not PEM?
- {
- *this = EC_Group(OIDS::lookup(str));
- }
- }
-
-EC_Group::EC_Group(const std::vector<uint8_t>& ber_data)
- {
- BER_Decoder ber(ber_data);
+ BER_Decoder ber(bits, len);
BER_Object obj = ber.get_next_object();
if(obj.type() == NULL_TAG)
- throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters");
+ {
+ throw Decoding_Error("Cannot handle ImplicitCA ECC parameters");
+ }
else if(obj.type() == OBJECT_ID)
{
OID dom_par_oid;
- BER_Decoder(ber_data).decode(dom_par_oid);
- *this = EC_Group(dom_par_oid);
+ BER_Decoder(bits, len).decode(dom_par_oid);
+ return lookup_EC_group_by_oid(dom_par_oid);
}
else if(obj.type() == SEQUENCE)
{
+ std::shared_ptr<EC_Group_Data> data = std::make_shared<EC_Group_Data>();
BigInt p, a, b;
std::vector<uint8_t> sv_base_point;
- BER_Decoder(ber_data)
+ BER_Decoder(bits, len)
.start_cons(SEQUENCE)
.decode_and_check<size_t>(1, "Unknown ECC param version code")
.start_cons(SEQUENCE)
@@ -78,16 +64,166 @@ EC_Group::EC_Group(const std::vector<uint8_t>& ber_data)
.decode_octet_string_bigint(b)
.end_cons()
.decode(sv_base_point, OCTET_STRING)
- .decode(m_order)
- .decode(m_cofactor)
+ .decode(data->m_order)
+ .decode(data->m_cofactor)
.end_cons()
.verify_end();
- m_curve = CurveGFp(p, a, b);
- m_base_point = OS2ECP(sv_base_point, m_curve);
+ data->m_curve = CurveGFp(p, a, b);
+ data->m_base_point = Botan::OS2ECP(sv_base_point, data->m_curve);
+
+ data->m_p_bits = p.bits();
+ data->m_p_bytes = p.bytes();
+ return data;
}
else
+ {
throw Decoding_Error("Unexpected tag while decoding ECC domain params");
+ }
+ }
+
+std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const std::string& pem)
+ {
+ secure_vector<uint8_t> ber = PEM_Code::decode_check_label(pem, "EC PARAMETERS");
+ return BER_decode_EC_group(ber.data(), ber.size());
+ }
+
+std::shared_ptr<EC_Group_Data> lookup_EC_group_by_oid(const OID& oid)
+ {
+ if(oid.empty())
+ throw Invalid_Argument("lookup_EC_group_by_oid with empty oid");
+
+ const std::string oid_name = OIDS::oid2str(oid);
+ if(oid_name.empty())
+ throw Invalid_Argument("Unknown EC group OID " + oid.as_string());
+
+ const std::string pem = EC_Group::PEM_for_named_group(oid_name);
+ if(pem.empty())
+ throw Invalid_Argument("EC group OID (" + oid_name + ") is not known");
+ std::shared_ptr<EC_Group_Data> data = BER_decode_EC_group(pem);
+ data->m_oid = oid;
+ return data;
+ }
+
+}
+
+EC_Group::EC_Group(const OID& domain_oid)
+ {
+ this->m_data = lookup_EC_group_by_oid(domain_oid);
+ }
+
+EC_Group::EC_Group(const std::string& str)
+ {
+ if(str == "")
+ return; // no initialization / uninitialized
+
+ try
+ {
+ OID oid = OIDS::lookup(str);
+ if(oid.empty() == false)
+ m_data = lookup_EC_group_by_oid(oid);
+ }
+ catch(Invalid_OID)
+ {
+ }
+
+ if(m_data == nullptr)
+ {
+ // OK try it as PEM ...
+ this->m_data = BER_decode_EC_group(str);
+ }
+ }
+
+EC_Group::EC_Group(const CurveGFp& curve,
+ const PointGFp& base_point,
+ const BigInt& order,
+ const BigInt& cofactor)
+ {
+ m_data.reset(new EC_Group_Data);
+
+ m_data->m_curve = curve;
+ m_data->m_base_point = base_point;
+ m_data->m_order = order;
+ m_data->m_cofactor = cofactor;
+ m_data->m_p_bits = curve.get_p().bits();
+ m_data->m_p_bytes = curve.get_p().bytes();
+ }
+
+EC_Group::EC_Group(const std::vector<uint8_t>& ber)
+ {
+ m_data = BER_decode_EC_group(ber.data(), ber.size());
+ }
+
+const EC_Group_Data& EC_Group::data() const
+ {
+ if(m_data == nullptr)
+ throw Invalid_State("EC_Group uninitialized");
+ return *m_data;
+ }
+
+const CurveGFp& EC_Group::get_curve() const
+ {
+ return data().m_curve;
+ }
+
+size_t EC_Group::get_p_bits() const
+ {
+ return data().m_p_bits;
+ }
+
+size_t EC_Group::get_p_bytes() const
+ {
+ return data().m_p_bytes;
+ }
+
+const BigInt& EC_Group::get_p() const
+ {
+ return data().m_curve.get_p();
+ }
+
+const BigInt& EC_Group::get_a() const
+ {
+ return data().m_curve.get_a();
+ }
+
+const BigInt& EC_Group::get_b() const
+ {
+ return data().m_curve.get_b();
+ }
+
+const PointGFp& EC_Group::get_base_point() const
+ {
+ return data().m_base_point;
+ }
+
+const BigInt& EC_Group::get_order() const
+ {
+ return data().m_order;
+ }
+
+const BigInt& EC_Group::get_cofactor() const
+ {
+ return data().m_cofactor;
+ }
+
+const OID& EC_Group::get_curve_oid() const
+ {
+ return data().m_oid;
+ }
+
+PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
+ {
+ return Botan::OS2ECP(bits, len, get_curve());
+ }
+
+PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
+ {
+ return PointGFp(get_curve(), x, y);
+ }
+
+PointGFp EC_Group::zero_point() const
+ {
+ return PointGFp(get_curve());
}
std::vector<uint8_t>
@@ -96,36 +232,37 @@ EC_Group::DER_encode(EC_Group_Encoding form) const
if(form == EC_DOMPAR_ENC_EXPLICIT)
{
const size_t ecpVers1 = 1;
- OID curve_type("1.2.840.10045.1.1");
+ OID curve_type("1.2.840.10045.1.1"); // prime field
- const size_t p_bytes = m_curve.get_p().bytes();
+ const size_t p_bytes = get_p_bytes();
return DER_Encoder()
.start_cons(SEQUENCE)
.encode(ecpVers1)
.start_cons(SEQUENCE)
.encode(curve_type)
- .encode(m_curve.get_p())
+ .encode(get_p())
.end_cons()
.start_cons(SEQUENCE)
- .encode(BigInt::encode_1363(m_curve.get_a(), p_bytes),
+ .encode(BigInt::encode_1363(get_a(), p_bytes),
OCTET_STRING)
- .encode(BigInt::encode_1363(m_curve.get_b(), p_bytes),
+ .encode(BigInt::encode_1363(get_b(), p_bytes),
OCTET_STRING)
.end_cons()
- .encode(EC2OSP(m_base_point, PointGFp::UNCOMPRESSED), OCTET_STRING)
- .encode(m_order)
- .encode(m_cofactor)
+ .encode(EC2OSP(get_base_point(), PointGFp::UNCOMPRESSED), OCTET_STRING)
+ .encode(get_order())
+ .encode(get_cofactor())
.end_cons()
.get_contents_unlocked();
}
else if(form == EC_DOMPAR_ENC_OID)
{
- if(get_oid().empty())
+ const OID oid = get_curve_oid();
+ if(oid.empty())
{
throw Encoding_Error("Cannot encode EC_Group as OID because OID not set");
}
- return DER_Encoder().encode(OID(get_oid())).get_contents_unlocked();
+ return DER_Encoder().encode(oid).get_contents_unlocked();
}
else if(form == EC_DOMPAR_ENC_IMPLICITCA)
return DER_Encoder().encode_null().get_contents_unlocked();
@@ -143,9 +280,9 @@ bool EC_Group::verify_group(RandomNumberGenerator& rng,
bool) const
{
//compute the discriminant
- Modular_Reducer p(m_curve.get_p());
- BigInt discriminant = p.multiply(4, m_curve.get_a());
- discriminant += p.multiply(27, m_curve.get_b());
+ Modular_Reducer p(get_p());
+ BigInt discriminant = p.multiply(4, get_a());
+ discriminant += p.multiply(27, get_b());
discriminant = p.reduce(discriminant);
//check the discriminant
if(discriminant == 0)
@@ -153,26 +290,26 @@ bool EC_Group::verify_group(RandomNumberGenerator& rng,
return false;
}
//check for valid cofactor
- if(m_cofactor < 1)
+ if(get_cofactor() < 1)
{
return false;
}
//check if the base point is on the curve
- if(!m_base_point.on_the_curve())
+ if(!get_base_point().on_the_curve())
{
return false;
}
- if((m_base_point * m_cofactor).is_zero())
+ if((get_base_point() * get_cofactor()).is_zero())
{
return false;
}
//check if order is prime
- if(!is_prime(m_order, rng, 128))
+ if(!is_prime(get_order(), rng, 128))
{
return false;
}
//check if order of the base point is correct
- if(!(m_base_point * m_order).is_zero())
+ if(!(get_base_point() * get_order()).is_zero())
{
return false;
}
diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h
index 18ffed12c..3da38a7da 100644
--- a/src/lib/pubkey/ec_group/ec_group.h
+++ b/src/lib/pubkey/ec_group/ec_group.h
@@ -13,6 +13,7 @@
#include <botan/point_gfp.h>
#include <botan/curve_gfp.h>
#include <botan/asn1_oid.h>
+#include <memory>
#include <set>
namespace Botan {
@@ -26,6 +27,8 @@ enum EC_Group_Encoding {
EC_DOMPAR_ENC_OID = 2
};
+struct EC_Group_Data;
+
/**
* Class representing an elliptic curve
*/
@@ -43,13 +46,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
EC_Group(const CurveGFp& curve,
const PointGFp& base_point,
const BigInt& order,
- const BigInt& cofactor) :
- m_curve(curve),
- m_base_point(base_point),
- m_order(order),
- m_cofactor(cofactor),
- m_oid("")
- {}
+ const BigInt& cofactor);
/**
* Decode a BER encoded ECC domain parameter set
@@ -68,7 +65,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
* from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
* @param pem_or_oid PEM-encoded data, or an OID
*/
- EC_Group(const std::string& pem_or_oid = "");
+ explicit EC_Group(const std::string& pem_or_oid = "");
/**
* Create the DER encoding of this domain
@@ -87,41 +84,90 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
* Return domain parameter curve
* @result domain parameter curve
*/
- const CurveGFp& get_curve() const { return m_curve; }
+ const CurveGFp& BOTAN_DEPRECATED("Avoid CurveGFp") get_curve() const;
+
+ /**
+ * Return the size of p in bits (same as get_p().bits())
+ */
+ size_t get_p_bits() const;
+
+ /**
+ * Return the size of p in bits (same as get_p().bytes())
+ */
+ size_t get_p_bytes() const;
+
+ /**
+ * Return the prime modulus of the field
+ */
+ const BigInt& get_p() const;
+
+ /**
+ * Return the a parameter of the elliptic curve equation
+ */
+ const BigInt& get_a() const;
+
+ /**
+ * Return the b parameter of the elliptic curve equation
+ */
+ const BigInt& get_b() const;
/**
* Return group base point
* @result base point
*/
- const PointGFp& get_base_point() const { return m_base_point; }
+ const PointGFp& get_base_point() const;
/**
* Return the order of the base point
* @result order of the base point
*/
- const BigInt& get_order() const { return m_order; }
+ const BigInt& get_order() const;
+
+ /**
+ * Return the OID of these domain parameters
+ * @result the OID as a string
+ */
+ std::string BOTAN_DEPRECATED("Use get_curve_oid") get_oid() const { return get_curve_oid().as_string(); }
+
+ /**
+ * Return the OID of these domain parameters
+ * @result the OID
+ */
+ const OID& get_curve_oid() const;
/**
* Return the cofactor
* @result the cofactor
*/
- const BigInt& get_cofactor() const { return m_cofactor; }
+ const BigInt& get_cofactor() const;
- bool initialized() const { return !m_base_point.is_zero(); }
+ /**
+ * Return a point on this curve with the affine values x, y
+ */
+ PointGFp point(const BigInt& x, const BigInt& y) const;
/**
- * Return the OID of these domain parameters
- * @result the OID
+ * Return the zero (or infinite) point on this curve
*/
- std::string get_oid() const { return m_oid; }
-
+ PointGFp zero_point() const;
+
+ PointGFp OS2ECP(const uint8_t bits[], size_t len) const;
+
+ template<typename Alloc>
+ PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
+ {
+ return this->OS2ECP(vec.data(), vec.size());
+ }
+
+ bool initialized() const { return (m_data != nullptr); }
+
/**
* Verify EC_Group domain
* @returns true if group is valid. false otherwise
*/
bool verify_group(RandomNumberGenerator& rng,
- bool strong = false) const;
-
+ bool strong = false) const;
+
bool operator==(const EC_Group& other) const
{
return ((get_curve() == other.get_curve()) &&
@@ -140,11 +186,11 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
*/
static const std::set<std::string>& known_named_groups();
+ static void add_named_group(const std::string& name, const OID& oid, const EC_Group& group);
+
private:
- CurveGFp m_curve;
- PointGFp m_base_point;
- BigInt m_order, m_cofactor;
- std::string m_oid;
+ const EC_Group_Data& data() const;
+ std::shared_ptr<EC_Group_Data> m_data;
};
inline bool operator!=(const EC_Group& lhs,
diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp
index 34062c362..17b6e6484 100644
--- a/src/lib/pubkey/ecc_key/ecc_key.cpp
+++ b/src/lib/pubkey/ecc_key/ecc_key.cpp
@@ -19,7 +19,7 @@ namespace Botan {
size_t EC_PublicKey::key_length() const
{
- return domain().get_curve().get_p().bits();
+ return domain().get_p_bits();
}
size_t EC_PublicKey::estimated_strength() const
@@ -31,20 +31,23 @@ EC_PublicKey::EC_PublicKey(const EC_Group& dom_par,
const PointGFp& pub_point) :
m_domain_params(dom_par), m_public_key(pub_point)
{
- if (!dom_par.get_oid().empty())
+ if (!dom_par.get_curve_oid().empty())
m_domain_encoding = EC_DOMPAR_ENC_OID;
else
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
+
+#if 0
if(domain().get_curve() != public_point().get_curve())
throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor");
+#endif
}
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id,
const std::vector<uint8_t>& key_bits) :
m_domain_params{EC_Group(alg_id.get_parameters())},
- m_public_key{OS2ECP(key_bits, domain().get_curve())}
+ m_public_key{domain().OS2ECP(key_bits)}
{
- if (!domain().get_oid().empty())
+ if (!domain().get_curve_oid().empty())
m_domain_encoding = EC_DOMPAR_ENC_OID;
else
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
@@ -101,7 +104,7 @@ void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form)
form != EC_DOMPAR_ENC_OID)
throw Invalid_Argument("Invalid encoding form for EC-key object specified");
- if((form == EC_DOMPAR_ENC_OID) && (m_domain_params.get_oid() == ""))
+ if((form == EC_DOMPAR_ENC_OID) && (m_domain_params.get_curve_oid().empty()))
throw Invalid_Argument("Invalid encoding form OID specified for "
"EC-key object whose corresponding domain "
"parameters are without oid");
@@ -126,7 +129,7 @@ EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
bool with_modular_inverse)
{
m_domain_params = ec_group;
- if (!ec_group.get_oid().empty())
+ if (!ec_group.get_curve_oid().empty())
m_domain_encoding = EC_DOMPAR_ENC_OID;
else
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
@@ -165,7 +168,7 @@ EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
m_domain_params = EC_Group(alg_id.get_parameters());
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
- if (!domain().get_oid().empty())
+ if (!domain().get_curve_oid().empty())
m_domain_encoding = EC_DOMPAR_ENC_OID;
else
m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
@@ -191,7 +194,7 @@ EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
}
else
{
- m_public_key = OS2ECP(public_key_bits, domain().get_curve());
+ m_public_key = domain().OS2ECP(public_key_bits);
// OS2ECP verifies that the point is on the curve
}
}
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index c05f22d1b..1850696e1 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -28,27 +28,23 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) :
PK_Ops::Key_Agreement_with_KDF(kdf),
- m_curve(key.domain().get_curve()),
- m_cofactor(key.domain().get_cofactor()),
- m_order(key.domain().get_order()),
+ m_domain(key.domain()),
m_rng(rng)
{
- m_l_times_priv = inverse_mod(m_cofactor, m_order) * key.private_value();
+ m_l_times_priv = inverse_mod(m_domain.get_cofactor(), m_domain.get_order()) * key.private_value();
}
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
- PointGFp point = OS2ECP(w, w_len, m_curve);
- PointGFp S = m_cofactor * point;
- Blinded_Point_Multiply blinder(S, m_order);
+ PointGFp point = m_domain.OS2ECP(w, w_len);
+ PointGFp S = m_domain.get_cofactor() * point;
+ Blinded_Point_Multiply blinder(S, m_domain.get_order());
S = blinder.blinded_multiply(m_l_times_priv, m_rng);
BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
- return BigInt::encode_1363(S.get_affine_x(), m_curve.get_p().bytes());
+ return BigInt::encode_1363(S.get_affine_x(), m_domain.get_p_bytes());
}
private:
- const CurveGFp& m_curve;
- const BigInt& m_cofactor;
- const BigInt& m_order;
+ const EC_Group& m_domain;
BigInt m_l_times_priv;
RandomNumberGenerator& m_rng;
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
index e2d574dcf..cd09b4c52 100644
--- a/src/lib/pubkey/ecies/ecies.cpp
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -66,12 +66,11 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
- const CurveGFp& curve = m_key.domain().get_curve();
- PointGFp point = OS2ECP(w, w_len, curve);
+ PointGFp point = m_key.domain().OS2ECP(w, w_len);
Blinded_Point_Multiply blinder(point, m_key.domain().get_order());
PointGFp S = blinder.blinded_multiply(m_key.private_value(), m_rng);
BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
- return BigInt::encode_1363(S.get_affine_x(), curve.get_p().bytes());
+ return BigInt::encode_1363(S.get_affine_x(), m_key.domain().get_p_bytes());
}
private:
@@ -241,7 +240,7 @@ ECIES_Encryptor::ECIES_Encryptor(const PK_Key_Agreement_Key& private_key,
{
// ISO 18033: step d
// convert only if necessary; m_eph_public_key_bin has been initialized with the uncompressed format
- m_eph_public_key_bin = unlock(EC2OSP(OS2ECP(m_eph_public_key_bin, m_params.domain().get_curve()),
+ m_eph_public_key_bin = unlock(EC2OSP(m_params.domain().OS2ECP(m_eph_public_key_bin),
static_cast<uint8_t>(ecies_params.compression_type())));
}
}
@@ -311,7 +310,7 @@ ECIES_Decryptor::ECIES_Decryptor(const PK_Key_Agreement_Key& key,
// ISO 18033: "If v > 1 and CheckMode = 0, then we must have gcd(u, v) = 1." (v = index, u= order)
if(!ecies_params.check_mode())
{
- Botan::BigInt cofactor = m_params.domain().get_cofactor();
+ const Botan::BigInt& cofactor = m_params.domain().get_cofactor();
if(cofactor > 1 && Botan::gcd(cofactor, m_params.domain().get_order()) != 1)
{
throw Invalid_Argument("ECIES: gcd of cofactor and order must be 1 if check_mode is 0");
@@ -324,7 +323,7 @@ ECIES_Decryptor::ECIES_Decryptor(const PK_Key_Agreement_Key& key,
*/
secure_vector<uint8_t> ECIES_Decryptor::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const
{
- size_t point_size = m_params.domain().get_curve().get_p().bytes();
+ size_t point_size = m_params.domain().get_p_bytes();
if(m_params.compression_type() != PointGFp::COMPRESSED)
{
point_size *= 2; // uncompressed and hybrid contains x AND y
@@ -345,7 +344,7 @@ secure_vector<uint8_t> ECIES_Decryptor::do_decrypt(uint8_t& valid_mask, const ui
const std::vector<uint8_t> mac_data(in + in_len - mac->output_length(), in + in_len);
// ISO 18033: step a
- PointGFp other_public_key = OS2ECP(other_public_key_bin, m_params.domain().get_curve());
+ PointGFp other_public_key = m_params.domain().OS2ECP(other_public_key_bin);
// ISO 18033: step b
if(m_params.check_mode() && !other_public_key.on_the_curve())
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index acd127a2d..f005a349b 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -41,7 +41,7 @@ AlgorithmIdentifier GOST_3410_PublicKey::algorithm_identifier() const
{
std::vector<uint8_t> params =
DER_Encoder().start_cons(SEQUENCE)
- .encode(OID(domain().get_oid()))
+ .encode(domain().get_curve_oid())
.end_cons()
.get_contents_unlocked();
@@ -73,7 +73,7 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id,
BigInt x(bits.data(), part_size);
BigInt y(&bits[part_size], part_size);
- m_public_key = PointGFp(domain().get_curve(), x, y);
+ m_public_key = domain().point(x, y);
BOTAN_ASSERT(m_public_key.on_the_curve(),
"Loaded GOST 34.10 public key is on the curve");
diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp
index 28f455ba3..652985ec9 100644
--- a/src/lib/pubkey/sm2/sm2.cpp
+++ b/src/lib/pubkey/sm2/sm2.cpp
@@ -54,10 +54,10 @@ std::vector<uint8_t> sm2_compute_za(HashFunction& hash,
hash.update(get_byte(1, uid_len));
hash.update(user_id);
- const size_t p_bytes = domain.get_curve().get_p().bytes();
+ const size_t p_bytes = domain.get_p_bytes();
- hash.update(BigInt::encode_1363(domain.get_curve().get_a(), p_bytes));
- hash.update(BigInt::encode_1363(domain.get_curve().get_b(), p_bytes));
+ hash.update(BigInt::encode_1363(domain.get_a(), p_bytes));
+ hash.update(BigInt::encode_1363(domain.get_b(), p_bytes));
hash.update(BigInt::encode_1363(domain.get_base_point().get_affine_x(), p_bytes));
hash.update(BigInt::encode_1363(domain.get_base_point().get_affine_y(), p_bytes));
hash.update(BigInt::encode_1363(pubkey.get_affine_x(), p_bytes));
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp
index b697daf1e..9ba278060 100644
--- a/src/lib/pubkey/sm2/sm2_enc.cpp
+++ b/src/lib/pubkey/sm2/sm2_enc.cpp
@@ -46,7 +46,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
{
public:
SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, const std::string& kdf_hash) :
- m_p_bytes(key.domain().get_curve().get_p().bytes()),
+ m_p_bytes(key.domain().get_p_bytes()),
m_order(key.domain().get_order()),
m_base_point(key.domain().get_base_point(), m_order),
m_public_point(key.public_point(), m_order),
@@ -135,7 +135,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
size_t ciphertext_len) override
{
const BigInt& cofactor = m_key.domain().get_cofactor();
- const size_t p_bytes = m_key.domain().get_curve().get_p().bytes();
+ const size_t p_bytes = m_key.domain().get_p_bytes();
valid_mask = 0x00;
@@ -160,7 +160,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
.end_cons()
.verify_end();
- const PointGFp C1(m_key.domain().get_curve(), x1, y1);
+ const PointGFp C1 = m_key.domain().point(x1, y1);
if(!C1.on_the_curve())
return secure_vector<uint8_t>();
diff --git a/src/lib/tls/tls_callbacks.cpp b/src/lib/tls/tls_callbacks.cpp
index 7a64291c8..b3b1b79bb 100644
--- a/src/lib/tls/tls_callbacks.cpp
+++ b/src/lib/tls/tls_callbacks.cpp
@@ -164,7 +164,7 @@ std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh
else
{
EC_Group group(OIDS::lookup(curve_name));
- ECDH_PublicKey peer_key(group, OS2ECP(peer_public_value, group.get_curve()));
+ ECDH_PublicKey peer_key(group, group.OS2ECP(peer_public_value));
policy.check_peer_key_acceptable(peer_key);
ECDH_PrivateKey priv_key(rng, group);
PK_Key_Agreement ka(priv_key, rng, "Raw");