diff options
author | Jack Lloyd <[email protected]> | 2018-02-01 13:20:40 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-02-01 13:20:40 -0500 |
commit | e70879bf0f3c1705cd6d4f0b4cef1f5d990c5b51 (patch) | |
tree | 1b3c344250cd0def213afb0b58c5ed1f9dc5b0d8 /src | |
parent | 0c84944402d03436c6982b370ace2d519add9751 (diff) | |
parent | 5213f9a5ed5c39b28d5226183231cf1121c59235 (diff) |
Merge GH #1435 Use shared_ptr representation for EC_Group
Diffstat (limited to 'src')
-rw-r--r-- | src/cli/pubkey.cpp | 6 | ||||
-rw-r--r-- | src/cli/speed.cpp | 7 | ||||
-rw-r--r-- | src/fuzzer/os2ecp.cpp | 2 | ||||
-rw-r--r-- | src/lib/ffi/ffi_pkey_algs.cpp | 8 | ||||
-rw-r--r-- | src/lib/prov/pkcs11/p11_ecc_key.cpp | 10 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 311 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.h | 128 | ||||
-rw-r--r-- | src/lib/pubkey/ecc_key/ecc_key.cpp | 19 | ||||
-rw-r--r-- | src/lib/pubkey/ecc_key/info.txt | 1 | ||||
-rw-r--r-- | src/lib/pubkey/ecdh/ecdh.cpp | 18 | ||||
-rw-r--r-- | src/lib/pubkey/ecies/ecies.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/gost_3410/gost_3410.cpp | 4 | ||||
-rw-r--r-- | src/lib/pubkey/sm2/sm2.cpp | 6 | ||||
-rw-r--r-- | src/lib/pubkey/sm2/sm2_enc.cpp | 6 | ||||
-rw-r--r-- | src/lib/tls/tls_callbacks.cpp | 2 | ||||
-rw-r--r-- | src/tests/test_ecdsa.cpp | 2 | ||||
-rw-r--r-- | src/tests/test_ecies.cpp | 5 | ||||
-rw-r--r-- | src/tests/test_gost_3410.cpp | 2 | ||||
-rw-r--r-- | src/tests/test_sm2.cpp | 8 | ||||
-rw-r--r-- | src/tests/unit_ecc.cpp | 140 | ||||
-rw-r--r-- | src/tests/unit_ecdsa.cpp | 28 |
21 files changed, 480 insertions, 246 deletions
diff --git a/src/cli/pubkey.cpp b/src/cli/pubkey.cpp index ffe1470dc..0e515d2ea 100644 --- a/src/cli/pubkey.cpp +++ b/src/cli/pubkey.cpp @@ -340,9 +340,9 @@ class EC_Group_Info final : public Command } else { - output() << "P = " << std::hex << group.get_curve().get_p() << "\n" - << "A = " << std::hex << group.get_curve().get_a() << "\n" - << "B = " << std::hex << group.get_curve().get_b() << "\n" + output() << "P = " << std::hex << group.get_p() << "\n" + << "A = " << std::hex << group.get_a() << "\n" + << "B = " << std::hex << group.get_b() << "\n" << "G = " << group.get_base_point().get_affine_x() << "," << group.get_base_point().get_affine_y() << "\n"; } diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index 04b8cc3ff..7dbc7922c 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -1215,7 +1215,7 @@ class Speed final : public Command Timer mult_timer(group_name + " scalar mult"); Timer blinded_mult_timer(group_name + " blinded scalar mult"); - const Botan::BigInt scalar(rng(), group.get_curve().get_p().bits()); + const Botan::BigInt scalar(rng(), group.get_p_bits()); const Botan::PointGFp& base_point = group.get_base_point(); Botan::Blinded_Point_Multiply scalar_mult(base_point, group.get_order(), 4); @@ -1242,7 +1242,6 @@ class Speed final : public Command for(std::string group_name : groups) { const Botan::EC_Group group(group_name); - const Botan::CurveGFp& curve = group.get_curve(); while(uncmp_timer.under(runtime) && cmp_timer.under(runtime)) { @@ -1251,8 +1250,8 @@ class Speed final : public Command const Botan::secure_vector<uint8_t> os_cmp = Botan::EC2OSP(p, Botan::PointGFp::COMPRESSED); const Botan::secure_vector<uint8_t> os_uncmp = Botan::EC2OSP(p, Botan::PointGFp::UNCOMPRESSED); - uncmp_timer.run([&]() { OS2ECP(os_uncmp, curve); }); - cmp_timer.run([&]() { OS2ECP(os_cmp, curve); }); + uncmp_timer.run([&]() { group.OS2ECP(os_uncmp); }); + cmp_timer.run([&]() { group.OS2ECP(os_cmp); }); } record_result(uncmp_timer); diff --git a/src/fuzzer/os2ecp.cpp b/src/fuzzer/os2ecp.cpp index dba6dbdfe..cb4a50b47 100644 --- a/src/fuzzer/os2ecp.cpp +++ b/src/fuzzer/os2ecp.cpp @@ -13,7 +13,7 @@ void check_os2ecp(const Botan::EC_Group& group, const uint8_t in[], size_t len) { try { - Botan::PointGFp point = Botan::OS2ECP(in, len, group.get_curve()); + Botan::PointGFp point = group.OS2ECP(in, len); } catch(Botan::Exception& e) {} } 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..93747a166 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,84 @@ 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> new_EC_group_data(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& g_x, + const BigInt& g_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid = OID()) + { + std::shared_ptr<EC_Group_Data> data = std::make_shared<EC_Group_Data>(); + + data->m_curve = CurveGFp(p, a, b); + data->m_base_point = PointGFp(data->m_curve, g_x, g_y); + data->m_order = order; + data->m_cofactor = cofactor; + data->m_oid = oid; + + data->m_p_bits = p.bits(); + data->m_p_bytes = p.bytes(); + return data; } -EC_Group::EC_Group(const std::string& str) +std::shared_ptr<EC_Group_Data> new_EC_group_data(const BigInt& p, + const BigInt& a, + const BigInt& b, + const std::vector<uint8_t>& base_point, + const BigInt& order, + const BigInt& cofactor, + const OID& oid = OID()) { - if(str == "") - return; // no initialization / uninitialized + std::shared_ptr<EC_Group_Data> data = std::make_shared<EC_Group_Data>(); - try - { - std::vector<uint8_t> ber = - unlock(PEM_Code::decode_check_label(str, "EC PARAMETERS")); + data->m_curve = CurveGFp(p, a, b); + data->m_base_point = Botan::OS2ECP(base_point, data->m_curve); + data->m_order = order; + data->m_cofactor = cofactor; + data->m_oid = oid; - *this = EC_Group(ber); - } - catch(Decoding_Error) // hmm, not PEM? - { - *this = EC_Group(OIDS::lookup(str)); - } + data->m_p_bits = p.bits(); + data->m_p_bytes = p.bytes(); + return data; } -EC_Group::EC_Group(const std::vector<uint8_t>& ber_data) +std::shared_ptr<EC_Group_Data> lookup_EC_group_by_oid(const OID& oid); + +std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len) { - 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) { - BigInt p, a, b; + BigInt p, a, b, order, cofactor; 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 +106,181 @@ 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(order) + .decode(cofactor) .end_cons() .verify_end(); - m_curve = CurveGFp(p, a, b); - m_base_point = OS2ECP(sv_base_point, m_curve); + return new_EC_group_data(p, a, b, sv_base_point, order, cofactor); } 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() + { + } + +EC_Group::~EC_Group() + { + // shared_ptr possibly freed here + } + +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 BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& base_x, + const BigInt& base_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid) + { + m_data = new_EC_group_data(p, a, b, base_x, base_y, order, cofactor, oid); + } + +EC_Group::EC_Group(const CurveGFp& curve, + const PointGFp& base_point, + const BigInt& order, + const BigInt& cofactor) + { + m_data = new_EC_group_data(curve.get_p(), + curve.get_a(), + curve.get_b(), + base_point.get_affine_x(), + base_point.get_affine_y(), + order, + cofactor); + } + +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, data().m_curve); + } + +PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const + { + return PointGFp(data().m_curve, x, y); + } + +PointGFp EC_Group::zero_point() const + { + return PointGFp(data().m_curve); } std::vector<uint8_t> @@ -96,36 +289,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(); @@ -139,13 +333,28 @@ std::string EC_Group::PEM_encode() const return PEM_Code::encode(der, "EC PARAMETERS"); } +bool EC_Group::operator==(const EC_Group& other) const + { + if(m_data == other.m_data) + return true; // same shared rep + + /* + * No point comparing order/cofactor as they are uniquely determined + * by the curve equation (p,a,b) and the base point. + */ + return (get_p() == other.get_p() && + get_a() == other.get_a() && + get_b() == other.get_b() && + get_base_point() == other.get_base_point()); + } + 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 +362,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..0e6b57b5a 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 */ @@ -40,16 +43,31 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final * @param order the order of the base point * @param cofactor the cofactor */ + BOTAN_DEPRECATED("Use version taking all BigInts") 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); + + /** + * Construct Domain paramers from specified parameters + * @param p the elliptic curve p + * @param a the elliptic curve a param + * @param b the elliptic curve b param + * @param base_x the x coordinate of the base point + * @param base_y the y coordinate of the base point + * @param order the order of the base point + * @param cofactor the cofactor + * @param oid an optional OID used to identify this curve + */ + EC_Group(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& base_x, + const BigInt& base_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid = OID()); /** * Decode a BER encoded ECC domain parameter set @@ -68,7 +86,14 @@ 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 an uninitialized EC_Group + */ + EC_Group(); + + ~EC_Group(); /** * Create the DER encoding of this domain @@ -87,48 +112,91 @@ 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; } + BOTAN_DEPRECATED("Avoid CurveGFp") const 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 operator==(const EC_Group& other) const - { - return ((get_curve() == other.get_curve()) && - (get_base_point() == other.get_base_point()) && - (get_order() == other.get_order()) && - (get_cofactor() == other.get_cofactor())); - } + bool strong = false) const; + + bool operator==(const EC_Group& other) const; /** * Return PEM representation of named EC group @@ -140,11 +208,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/ecc_key/info.txt b/src/lib/pubkey/ecc_key/info.txt index ac345a089..f46c9bb54 100644 --- a/src/lib/pubkey/ecc_key/info.txt +++ b/src/lib/pubkey/ecc_key/info.txt @@ -5,7 +5,6 @@ ECC_PUBLIC_KEY_CRYPTO -> 20131128 <requires> asn1 bigint -ec_gfp ec_group numbertheory </requires> 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"); diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index 36ca72942..2105250cb 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -104,7 +104,7 @@ class ECDSA_Invalid_Key_Tests final : public Text_Based_Test try { - public_point.reset(new Botan::PointGFp(group.get_curve(), x, y)); + public_point.reset(new Botan::PointGFp(group.point(x, y))); } catch(Botan::Invalid_Argument&) { diff --git a/src/tests/test_ecies.cpp b/src/tests/test_ecies.cpp index 5c5af0a41..2ce931bae 100644 --- a/src/tests/test_ecies.cpp +++ b/src/tests/test_ecies.cpp @@ -127,12 +127,11 @@ class ECIES_ISO_Tests final : public Text_Based_Test const std::vector<uint8_t> c0 = get_req_bin(vars, "C0"); // expected encoded (ephemeral) public key const std::vector<uint8_t> k = get_req_bin(vars, "K"); // expected derived secret - const Botan::CurveGFp curve(p, a, b); - const Botan::EC_Group domain(curve, Botan::PointGFp(curve, gx, gy), mu, nu); + const Botan::EC_Group domain(p, a, b, gx, gy, mu, nu); // keys of bob const Botan::ECDH_PrivateKey other_private_key(Test::rng(), domain, x); - const Botan::PointGFp other_public_key_point(curve, hx, hy); + const Botan::PointGFp other_public_key_point = domain.point(hx, hy); const Botan::ECDH_PublicKey other_public_key(domain, other_public_key_point); // (ephemeral) keys of alice diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp index a1443a7ae..fe9e91f58 100644 --- a/src/tests/test_gost_3410.cpp +++ b/src/tests/test_gost_3410.cpp @@ -30,7 +30,7 @@ class GOST_3410_2001_Verification_Tests final : public PK_Signature_Verification { const std::string group_id = get_req_str(vars, "Group"); Botan::EC_Group group(Botan::OIDS::lookup(group_id)); - const Botan::PointGFp public_point = Botan::OS2ECP(get_req_bin(vars, "Pubkey"), group.get_curve()); + const Botan::PointGFp public_point = group.OS2ECP(get_req_bin(vars, "Pubkey")); std::unique_ptr<Botan::Public_Key> key(new Botan::GOST_3410_PublicKey(group, public_point)); return key; diff --git a/src/tests/test_sm2.cpp b/src/tests/test_sm2.cpp index 16b82b792..c4ddf6ddf 100644 --- a/src/tests/test_sm2.cpp +++ b/src/tests/test_sm2.cpp @@ -51,9 +51,7 @@ class SM2_Signature_KAT_Tests final : public PK_Signature_Generation_Test const BigInt cofactor = get_req_bn(vars, "Cofactor"); const BigInt x = get_req_bn(vars, "x"); - Botan::CurveGFp curve(p, a, b); - Botan::PointGFp base_point(curve, xG, yG); - Botan::EC_Group domain(curve, base_point, order, cofactor); + Botan::EC_Group domain(p, a, b, xG, yG, order, cofactor); Botan::Null_RNG null_rng; std::unique_ptr<Botan::Private_Key> key(new Botan::SM2_Signature_PrivateKey(null_rng, domain, x)); @@ -97,9 +95,7 @@ class SM2_Encryption_KAT_Tests final : public PK_Encryption_Decryption_Test const BigInt cofactor = get_req_bn(vars, "Cofactor"); const BigInt x = get_req_bn(vars, "x"); - Botan::CurveGFp curve(p, a, b); - Botan::PointGFp base_point(curve, xG, yG); - Botan::EC_Group domain(curve, base_point, order, cofactor); + Botan::EC_Group domain(p, a, b, xG, yG, order, cofactor); Botan::Null_RNG null_rng; std::unique_ptr<Botan::Private_Key> key(new Botan::SM2_Encryption_PrivateKey(null_rng, domain, x)); diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp index b9355e6f0..8d8cdb538 100644 --- a/src/tests/unit_ecc.cpp +++ b/src/tests/unit_ecc.cpp @@ -17,7 +17,6 @@ #include <botan/point_gfp.h> #include <botan/ec_group.h> #include <botan/reducer.h> - #include <botan/oids.h> #include <botan/hex.h> #include <botan/data_src.h> #include <botan/x509_key.h> @@ -83,9 +82,9 @@ Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigIn } Botan::PointGFp create_random_point(Botan::RandomNumberGenerator& rng, - const Botan::CurveGFp& curve) + const Botan::EC_Group& group) { - const Botan::BigInt& p = curve.get_p(); + const Botan::BigInt& p = group.get_p(); Botan::Modular_Reducer mod_p(p); @@ -93,14 +92,14 @@ Botan::PointGFp create_random_point(Botan::RandomNumberGenerator& rng, { const Botan::BigInt x = Botan::BigInt::random_integer(rng, 1, p); const Botan::BigInt x3 = mod_p.multiply(x, mod_p.square(x)); - const Botan::BigInt ax = mod_p.multiply(curve.get_a(), x); - const Botan::BigInt y = mod_p.reduce(x3 + ax + curve.get_b()); + const Botan::BigInt ax = mod_p.multiply(group.get_a(), x); + const Botan::BigInt y = mod_p.reduce(x3 + ax + group.get_b()); const Botan::BigInt sqrt_y = ressol(y, p); if(sqrt_y > 1) { BOTAN_ASSERT_EQUAL(mod_p.square(sqrt_y), y, "Square root is correct"); - Botan::PointGFp point(curve, x, sqrt_y); + Botan::PointGFp point = group.point(x, sqrt_y); return point; } } @@ -276,7 +275,9 @@ Test::Result test_groups() for(auto const& group_name : named_groups) { const Botan::EC_Group group(group_name); - result.confirm("EC_Group is known", !group.get_oid().empty()); + result.confirm("EC_Group is known", !group.get_curve_oid().empty()); + result.test_eq("EC_Group has correct bit size", group.get_p().bits(), group.get_p_bits()); + result.test_eq("EC_Group has byte size", group.get_p().bytes(), group.get_p_bytes()); } return result; } @@ -289,11 +290,10 @@ Test::Result test_coordinates() const Botan::BigInt exp_affine_y("1373093393927139016463695321221277758035357890939"); // precalculation - const Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + const Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); - const Botan::PointGFp point_exp(curve, exp_affine_x, exp_affine_y); + const Botan::PointGFp point_exp = secp160r1.point(exp_affine_x, exp_affine_y); result.confirm("Point is on the curve", point_exp.on_the_curve()); const Botan::PointGFp p1 = p_G * 2; @@ -319,7 +319,7 @@ Test::Result test_point_transformation() Test::Result result("ECC Unit"); // get a valid point - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); + Botan::EC_Group dom_pars("secp160r1"); Botan::PointGFp p = dom_pars.get_base_point() * Test::rng().next_nonzero_byte(); // get a copy @@ -337,7 +337,7 @@ Test::Result test_point_mult() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); Botan::BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982"); @@ -352,7 +352,7 @@ Test::Result test_point_negative() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); const Botan::PointGFp p1 = p_G * 2; @@ -371,12 +371,10 @@ Test::Result test_zeropoint() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); - Botan::PointGFp p1(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::PointGFp p1 = secp160r1.point(Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p1.on_the_curve()); @@ -391,20 +389,19 @@ Test::Result test_zeropoint_enc_dec() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); - Botan::PointGFp p(curve); + Botan::PointGFp p = secp160r1.zero_point(); result.confirm("zero point is zero", p.is_zero()); std::vector<uint8_t> sv_p = unlock(EC2OSP(p, Botan::PointGFp::UNCOMPRESSED)); - result.test_eq("encoded/decode rt works", OS2ECP(sv_p, curve), p); + result.test_eq("encoded/decode rt works", secp160r1.OS2ECP(sv_p), p); sv_p = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED)); - result.test_eq("encoded/decode compressed rt works", OS2ECP(sv_p, curve), p); + result.test_eq("encoded/decode compressed rt works", secp160r1.OS2ECP(sv_p), p); sv_p = unlock(EC2OSP(p, Botan::PointGFp::HYBRID)); - result.test_eq("encoded/decode hybrid rt works", OS2ECP(sv_p, curve), p); + result.test_eq("encoded/decode hybrid rt works", secp160r1.OS2ECP(sv_p), p); return result; } @@ -412,17 +409,15 @@ Test::Result test_calc_with_zeropoint() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); - Botan::PointGFp p(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::PointGFp p = secp160r1.point(Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p.on_the_curve()); result.confirm("point is not zero", !p.is_zero()); - Botan::PointGFp zero(curve); + Botan::PointGFp zero = secp160r1.zero_point(); result.confirm("zero point is zero", zero.is_zero()); Botan::PointGFp res = p + zero; @@ -441,8 +436,7 @@ Test::Result test_add_point() Test::Result result("ECC Unit"); // precalculation - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); Botan::PointGFp p0 = p_G; @@ -450,9 +444,8 @@ Test::Result test_add_point() p1 += p0; - Botan::PointGFp expected(curve, - Botan::BigInt("704859595002530890444080436569091156047721708633"), - Botan::BigInt("1147993098458695153857594941635310323215433166682")); + Botan::PointGFp expected = secp160r1.point(Botan::BigInt("704859595002530890444080436569091156047721708633"), + Botan::BigInt("1147993098458695153857594941635310323215433166682")); result.test_eq("point addition", p1, expected); return result; @@ -462,8 +455,7 @@ Test::Result test_sub_point() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); Botan::PointGFp p0 = p_G; @@ -471,9 +463,8 @@ Test::Result test_sub_point() p1 -= p0; - Botan::PointGFp expected(curve, - Botan::BigInt("425826231723888350446541592701409065913635568770"), - Botan::BigInt("203520114162904107873991457957346892027982641970")); + Botan::PointGFp expected = secp160r1.point(Botan::BigInt("425826231723888350446541592701409065913635568770"), + Botan::BigInt("203520114162904107873991457957346892027982641970")); result.test_eq("point subtraction", p1, expected); return result; @@ -483,8 +474,7 @@ Test::Result test_mult_point() { Test::Result result("ECC Unit"); - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); Botan::PointGFp p0 = p_G; @@ -494,7 +484,7 @@ Test::Result test_mult_point() const Botan::BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250")); const Botan::BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656")); - Botan::PointGFp expected(curve, exp_mult_x, exp_mult_y); + Botan::PointGFp expected = secp160r1.point(exp_mult_x, exp_mult_y); result.test_eq("point mult", p1, expected); return result; @@ -505,8 +495,7 @@ Test::Result test_basic_operations() Test::Result result("ECC Unit"); // precalculation - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); const Botan::PointGFp& p_G = secp160r1.get_base_point(); const Botan::PointGFp p0 = p_G; @@ -516,16 +505,14 @@ Test::Result test_basic_operations() result.test_eq("p1 affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939")); const Botan::PointGFp simplePlus = p1 + p0; - const Botan::PointGFp exp_simplePlus(curve, - Botan::BigInt("704859595002530890444080436569091156047721708633"), - Botan::BigInt("1147993098458695153857594941635310323215433166682")); + const Botan::PointGFp exp_simplePlus = secp160r1.point(Botan::BigInt("704859595002530890444080436569091156047721708633"), + Botan::BigInt("1147993098458695153857594941635310323215433166682")); result.test_eq("point addition", simplePlus, exp_simplePlus); const Botan::PointGFp simpleMinus = p1 - p0; - const Botan::PointGFp exp_simpleMinus(curve, - Botan::BigInt("425826231723888350446541592701409065913635568770"), - Botan::BigInt("203520114162904107873991457957346892027982641970")); + const Botan::PointGFp exp_simpleMinus= secp160r1.point(Botan::BigInt("425826231723888350446541592701409065913635568770"), + Botan::BigInt("203520114162904107873991457957346892027982641970")); result.test_eq("point subtraction", simpleMinus, exp_simpleMinus); @@ -544,12 +531,11 @@ Test::Result test_enc_dec_compressed_160() Test::Result result("ECC Unit"); // Test for compressed conversion (02/03) 160bit - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); const std::vector<uint8_t> G_comp = Botan::hex_decode("024A96B5688EF573284664698968C38BB913CBFC82"); - const Botan::PointGFp p = Botan::OS2ECP(G_comp, curve); + const Botan::PointGFp p = secp160r1.OS2ECP(G_comp); std::vector<uint8_t> sv_result = unlock(Botan::EC2OSP(p, Botan::PointGFp::COMPRESSED)); @@ -692,11 +678,11 @@ Test::Result test_gfp_store_restore() Test::Result result("ECC Unit"); // generate point - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); + Botan::EC_Group dom_pars("secp160r1"); Botan::PointGFp p = dom_pars.get_base_point(); std::vector<uint8_t> sv_mes = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED)); - Botan::PointGFp new_p = Botan::OS2ECP(sv_mes, dom_pars.get_curve()); + Botan::PointGFp new_p = dom_pars.OS2ECP(sv_mes); result.test_eq("original and restored points are same", p, new_p); return result; @@ -732,12 +718,10 @@ Test::Result test_more_zeropoint() // by Falko - Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1")); - const Botan::CurveGFp& curve = secp160r1.get_curve(); + Botan::EC_Group secp160r1("secp160r1"); - Botan::PointGFp p1(curve, - Botan::BigInt("16984103820118642236896513183038186009872590470"), - Botan::BigInt("1373093393927139016463695321221277758035357890939")); + Botan::PointGFp p1 = secp160r1.point(Botan::BigInt("16984103820118642236896513183038186009872590470"), + Botan::BigInt("1373093393927139016463695321221277758035357890939")); result.confirm("point is on the curve", p1.on_the_curve()); Botan::PointGFp minus_p1 = -p1; @@ -747,12 +731,12 @@ Test::Result test_more_zeropoint() result.confirm("point is zero", shouldBeZero.is_zero()); Botan::BigInt y1 = p1.get_affine_y(); - y1 = curve.get_p() - y1; + y1 = secp160r1.get_p() - y1; result.test_eq("minus point x", minus_p1.get_affine_x(), p1.get_affine_x()); result.test_eq("minus point y", minus_p1.get_affine_y(), y1); - Botan::PointGFp zero(curve); + Botan::PointGFp zero = secp160r1.zero_point(); result.confirm("zero point is on the curve", zero.on_the_curve()); result.test_eq("addition of zero does nothing", p1, p1 + zero); @@ -764,7 +748,7 @@ Test::Result test_mult_by_order() Test::Result result("ECC Unit"); // generate point - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); + Botan::EC_Group dom_pars("secp160r1"); Botan::PointGFp p = dom_pars.get_base_point(); Botan::PointGFp shouldBeZero = p * dom_pars.get_order(); @@ -776,10 +760,10 @@ Test::Result test_point_swap() { Test::Result result("ECC Unit"); - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); + Botan::EC_Group dom_pars("secp160r1"); - Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve())); - Botan::PointGFp b(create_random_point(Test::rng(), dom_pars.get_curve())); + Botan::PointGFp a(create_random_point(Test::rng(), dom_pars)); + Botan::PointGFp b(create_random_point(Test::rng(), dom_pars)); b *= Botan::BigInt(Test::rng(), 20); Botan::PointGFp c(a); @@ -800,12 +784,12 @@ Test::Result test_mult_sec_mass() { Test::Result result("ECC Unit"); - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); + Botan::EC_Group dom_pars("secp160r1"); for(int i = 0; i < 50; i++) { try { - Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve())); + Botan::PointGFp a(create_random_point(Test::rng(), dom_pars)); Botan::BigInt scal(Botan::BigInt(Test::rng(), 40)); Botan::PointGFp b = a * scal; Botan::PointGFp c(a); @@ -822,23 +806,6 @@ Test::Result test_mult_sec_mass() return result; } -Test::Result test_curve_cp_ctor() - { - Test::Result result("ECC Unit"); - - try - { - Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8")); - Botan::CurveGFp curve(dom_pars.get_curve()); - } - catch(std::exception& e) - { - result.test_failure("curve_cp_ctor", e.what()); - } - - return result; - } - class ECC_Unit_Tests final : public Test { public: @@ -869,7 +836,6 @@ class ECC_Unit_Tests final : public Test results.push_back(test_mult_by_order()); results.push_back(test_point_swap()); results.push_back(test_mult_sec_mass()); - results.push_back(test_curve_cp_ctor()); return results; } diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp index 5d137bacf..081b686e6 100644 --- a/src/tests/unit_ecdsa.cpp +++ b/src/tests/unit_ecdsa.cpp @@ -233,20 +233,20 @@ Test::Result test_unusual_curve() Test::Result result("ECDSA Unit"); //calc a curve which is not in the registry - const std::string G_secp_comp = - "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7"; - const Botan::BigInt - bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); - const Botan::BigInt - bi_a_secp("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); - const Botan::BigInt - bi_b_secp("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); - Botan::BigInt bi_order_g("0x0e1a16196e6000000000bc7f1618d867b15bb86474418f"); - Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - Botan::PointGFp p_G = Botan::OS2ECP(Botan::hex_decode(G_secp_comp), curve); - - Botan::EC_Group dom_params(curve, p_G, bi_order_g, Botan::BigInt(1)); - if(!result.confirm("point is on curve", p_G.on_the_curve())) + const Botan::BigInt p("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809"); + const Botan::BigInt a("0x0a377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe"); + const Botan::BigInt b("0x0a9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7"); + const Botan::BigInt order_g("0x0e1a16196e6000000000bc7f1618d867b15bb86474418f"); + const Botan::BigInt cofactor = 1; + + const BigInt Gx("1503931002566715881584977704503341991763310127581173321974500299341775226206001860606586625324214456299149080935147329869147994265934715820"); + const BigInt Gy("1774988776970033741491814582357926984496972046739476148938345272681378523636129776486407268230155403536112014267092770854858769258781598199"); + + Botan::EC_Group dom_params(p, a, b, Gx, Gy, order_g, cofactor); + + Botan::PointGFp p_G = dom_params.point(Gx, Gy); + + if(!result.confirm("G is on curve", p_G.on_the_curve())) { return result; } |