Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some EC_Group usage cleanups #4038

Merged
merged 5 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 15 additions & 44 deletions doc/api_ref/ecc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ during common operations.
Initialize an elliptic curve group from the relevant parameters. This
is used for example to create custom (application-specific) curves.

.. warning::

Currently a cofactor > 1 is accepted. In the future only prime order
subgroups will be allowed.

.. warning::

Currently primes of any size may be provided. In the
future the prime will be allowed to be at most 521 bits.

.. cpp:function:: EC_Group(const std::vector<uint8_t>& ber_encoding)

Initialize an ``EC_Group`` by decoding a DER encoded parameter block.
Expand All @@ -52,14 +62,6 @@ during common operations.
Return the PEM encoding of this group (base64 of DER encoding plus
header/trailer).

.. cpp:function:: bool a_is_minus_3() const

Return true if the ``a`` parameter is congruent to -3 mod p.

.. cpp:function:: bool a_is_zero() const

Return true if the ``a`` parameter is congruent to 0 mod p.

.. cpp:function:: size_t get_p_bits() const

Return size of the prime in bits.
Expand Down Expand Up @@ -108,6 +110,11 @@ during common operations.

Return the cofactor of the curve. In most cases this will be 1.

.. warning::

In a future release all support for elliptic curves group with
a cofactor > 1 will be removed.

.. cpp:function:: BigInt mod_order(const BigInt& x) const

Reduce argument ``x`` modulo the curve order.
Expand Down Expand Up @@ -246,39 +253,3 @@ during common operations.
.. cpp:function:: bool operator==(const EC_Point& other) const

Point equality. This compares the affine representations.

.. cpp:function:: void add(const EC_Point& other, std::vector<BigInt>& workspace)

Point addition, taking a workspace.

.. cpp:function:: void add_affine(const EC_Point& other, std::vector<BigInt>& workspace)

Mixed (Jacobian+affine) addition, taking a workspace.

.. warning::

This function assumes that ``other`` is affine, if this is
not correct the result will be invalid.

.. cpp:function:: void mult2(std::vector<BigInt>& workspace)

Point doubling.

.. cpp:function:: void mult2i(size_t i, std::vector<BigInt>& workspace)

Repeated point doubling.

.. cpp:function:: EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const

Point addition, returning the result.

.. cpp:function:: EC_Point double_of(std::vector<BigInt>& workspace) const

Point doubling, returning the result.

.. cpp:function:: EC_Point zero() const

Return the point at infinity



9 changes: 9 additions & 0 deletions doc/deprecated.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ elliptic curve points.
"brainpool192r1", "brainpool224r1", "brainpool320r1", "x962_p192v2",
"x962_p192v3", "x962_p239v1", "x962_p239v2", "x962_p239v3"

- Currently `EC_Point` offers a wide variety of functionality almost
all of which was intended only for internal implementation. In a
future release, the only operations available for EC_Points will be
to extract the byte encoding of their affine x and y coordinates.

- Currently it is possible to create an EC_Group with cofactor > 1.
None of the builtin groups have composite order, and in the future
it will be impossible to create composite order EC_Groups.

Deprecated Modules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
11 changes: 11 additions & 0 deletions doc/dev_ref/oids.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,14 @@ Values currently assigned are::
camellia-192-siv OBJECT IDENTIFIER ::= { sivModes 7 }
camellia-256-siv OBJECT IDENTIFIER ::= { sivModes 8 }
sm4-128-siv OBJECT IDENTIFIER ::= { sivModes 9 }

ellipticCurve OBJECT IDENTIFIER ::= { randombit 4 }

numsp256d1 OBJECT IDENTIFIER ::= { ellipticCurve 1 }
numsp384d1 OBJECT IDENTIFIER ::= { ellipticCurve 2 }
numsp512d1 OBJECT IDENTIFIER ::= { ellipticCurve 3 }

-- These are just for testing purposes internally in the library
-- and are not included in oids.txt
sm2test OBJECT IDENTIFIER ::= { ellipticCurve 5459250 }
iso18003 OBJECT IDENTIFIER ::= { ellipticCurve 18003 }
2 changes: 1 addition & 1 deletion src/cli/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ class EC_Group_Info final : public Command {
}

void go() override {
Botan::EC_Group ec_group(get_arg("name"));
const auto ec_group = Botan::EC_Group::from_name(get_arg("name"));

if(flag_set("pem")) {
output() << ec_group.PEM_encode();
Expand Down
41 changes: 5 additions & 36 deletions src/cli/speed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,8 +722,6 @@ class Speed final : public Command {
#if defined(BOTAN_HAS_ECC_GROUP)
else if(algo == "ecc_mult") {
bench_ecc_mult(ecc_groups, msec);
} else if(algo == "ecc_ops") {
bench_ecc_ops(ecc_groups, msec);
} else if(algo == "ecc_init") {
bench_ecc_init(ecc_groups, msec);
} else if(algo == "os2ecp") {
Expand Down Expand Up @@ -1084,42 +1082,13 @@ class Speed final : public Command {
}

#if defined(BOTAN_HAS_ECC_GROUP)
void bench_ecc_ops(const std::vector<std::string>& groups, const std::chrono::milliseconds runtime) {
for(const std::string& group_name : groups) {
const Botan::EC_Group ec_group(group_name);

auto add_timer = make_timer(group_name + " add");
auto addf_timer = make_timer(group_name + " addf");
auto dbl_timer = make_timer(group_name + " dbl");

const Botan::EC_Point& base_point = ec_group.get_base_point();

// create a non-affine point
const auto random_k = Botan::BigInt::from_u64(0x4E6F537465707E);
Botan::EC_Point non_affine_pt = ec_group.get_base_point() * random_k;
Botan::EC_Point pt = ec_group.get_base_point();

std::vector<Botan::BigInt> ws(Botan::EC_Point::WORKSPACE_SIZE);

while(add_timer->under(runtime) && addf_timer->under(runtime) && dbl_timer->under(runtime)) {
dbl_timer->run([&]() { pt.mult2(ws); });
add_timer->run([&]() { pt.add(non_affine_pt, ws); });
addf_timer->run([&]() { pt.add_affine(base_point, ws); });
}

record_result(dbl_timer);
record_result(add_timer);
record_result(addf_timer);
}
}

void bench_ecc_init(const std::vector<std::string>& groups, const std::chrono::milliseconds runtime) {
for(std::string group_name : groups) {
auto timer = make_timer(group_name + " initialization");

while(timer->under(runtime)) {
Botan::EC_Group::clear_registered_curve_data();
timer->run([&]() { Botan::EC_Group group(group_name); });
timer->run([&]() { Botan::EC_Group::from_name(group_name); });
}

record_result(timer);
Expand All @@ -1128,7 +1097,7 @@ class Speed final : public Command {

void bench_ecc_mult(const std::vector<std::string>& groups, const std::chrono::milliseconds runtime) {
for(const std::string& group_name : groups) {
const Botan::EC_Group ec_group(group_name);
const auto ec_group = Botan::EC_Group::from_name(group_name);

auto mult_timer = make_timer(group_name + " Montgomery ladder");
auto blinded_mult_timer = make_timer(group_name + " blinded comb");
Expand Down Expand Up @@ -1165,7 +1134,7 @@ class Speed final : public Command {
auto uncmp_timer = make_timer("OS2ECP uncompressed " + group_name);
auto cmp_timer = make_timer("OS2ECP compressed " + group_name);

const Botan::EC_Group ec_group(group_name);
const auto ec_group = Botan::EC_Group::from_name(group_name);

while(uncmp_timer->under(runtime) && cmp_timer->under(runtime)) {
const Botan::BigInt k(rng(), 256);
Expand All @@ -1190,7 +1159,7 @@ class Speed final : public Command {
auto h2c_ro_timer = make_timer(group_name + "-RO", "", "hash to curve");
auto h2c_nu_timer = make_timer(group_name + "-NU", "", "hash to curve");

const Botan::EC_Group group(group_name);
const auto group = Botan::EC_Group::from_name(group_name);

while(h2c_ro_timer->under(runtime)) {
std::vector<uint8_t> input(32);
Expand Down Expand Up @@ -1803,7 +1772,7 @@ class Speed final : public Command {
const std::string& /*unused*/,
std::chrono::milliseconds msec) {
for(const std::string& group_name : groups) {
Botan::EC_Group group(group_name);
const auto group = Botan::EC_Group::from_name(group_name);
auto recovery_timer = make_timer("ECDSA recovery " + group_name);

while(recovery_timer->under(msec)) {
Expand Down
6 changes: 4 additions & 2 deletions src/cli/timing_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,9 @@ class ECDSA_Timing_Test final : public Timing_Test {
};

ECDSA_Timing_Test::ECDSA_Timing_Test(const std::string& ecgroup) :
m_group(ecgroup), m_privkey(timing_test_rng(), m_group), m_x(m_privkey.private_value()) {
m_group(Botan::EC_Group::from_name(ecgroup)),
m_privkey(timing_test_rng(), m_group),
m_x(m_privkey.private_value()) {
m_b = m_group.random_scalar(timing_test_rng());
m_b_inv = m_group.inverse_mod_order(m_b);
}
Expand Down Expand Up @@ -296,7 +298,7 @@ ticks ECDSA_Timing_Test::measure_critical_function(const std::vector<uint8_t>& i

class ECC_Mul_Timing_Test final : public Timing_Test {
public:
explicit ECC_Mul_Timing_Test(const std::string& ecgroup) : m_group(ecgroup) {}
explicit ECC_Mul_Timing_Test(const std::string& ecgroup) : m_group(Botan::EC_Group::from_name(ecgroup)) {}

ticks measure_critical_function(const std::vector<uint8_t>& input) override;

Expand Down
2 changes: 1 addition & 1 deletion src/examples/ecdh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ int main() {
Botan::AutoSeeded_RNG rng;

// ec domain and KDF
Botan::EC_Group domain("secp521r1");
const auto domain = Botan::EC_Group::from_name("secp521r1");
const std::string kdf = "KDF2(SHA-256)";

// the two parties generate ECDH keys
Expand Down
3 changes: 2 additions & 1 deletion src/examples/ecdsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
int main() {
Botan::AutoSeeded_RNG rng;
// Generate ECDSA keypair
Botan::ECDSA_PrivateKey key(rng, Botan::EC_Group("secp521r1"));
const auto group = Botan::EC_Group::from_name("secp521r1");
Botan::ECDSA_PrivateKey key(rng, group);

const std::string message("This is a tasty burger!");

Expand Down
6 changes: 3 additions & 3 deletions src/examples/pkcs11_ecdh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ int main() {
Botan::AutoSeeded_RNG rng;

// create private key in software
Botan::ECDH_PrivateKey priv_key_sw(rng, Botan::EC_Group("secp256r1"));
Botan::ECDH_PrivateKey priv_key_sw(rng, Botan::EC_Group::from_name("secp256r1"));
priv_key_sw.set_parameter_encoding(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID);

// set import properties
Expand Down Expand Up @@ -81,13 +81,13 @@ int main() {

Botan::PKCS11::PKCS11_ECDH_PrivateKey priv_key2(
session,
Botan::EC_Group("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID),
Botan::EC_Group::from_name("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID),
priv_generate_props);

/************ generate ECDH key pair *************/

Botan::PKCS11::EC_PublicKeyGenerationProperties pub_generate_props(
Botan::EC_Group("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID));
Botan::EC_Group::from_name("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID));

pub_generate_props.set_label(label + "_PUB_KEY");
pub_generate_props.set_token(true);
Expand Down
6 changes: 3 additions & 3 deletions src/examples/pkcs11_ecdsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int main() {
// create private key in software
Botan::AutoSeeded_RNG rng;

Botan::ECDSA_PrivateKey priv_key_sw(rng, Botan::EC_Group("secp256r1"));
Botan::ECDSA_PrivateKey priv_key_sw(rng, Botan::EC_Group::from_name("secp256r1"));
priv_key_sw.set_parameter_encoding(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID);

// set the private key import properties
Expand Down Expand Up @@ -78,13 +78,13 @@ int main() {

Botan::PKCS11::PKCS11_ECDSA_PrivateKey pk(
session,
Botan::EC_Group("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID),
Botan::EC_Group::from_name("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID),
priv_generate_props);

/************ generate PKCS#11 ECDSA key pair *************/

Botan::PKCS11::EC_PublicKeyGenerationProperties pub_generate_props(
Botan::EC_Group("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID));
Botan::EC_Group::from_name("secp256r1").DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID));

pub_generate_props.set_label("BOTAN_TEST_ECDSA_PUB_KEY");
pub_generate_props.set_token(true);
Expand Down
12 changes: 6 additions & 6 deletions src/examples/tls_custom_curves_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Callbacks : public Botan::TLS::Callbacks {
if(std::holds_alternative<Botan::TLS::Group_Params>(group) &&
std::get<Botan::TLS::Group_Params>(group) == Botan::TLS::Group_Params(0xFE00)) {
// generate a private key of my custom curve
const Botan::EC_Group ec_group("numsp256d1");
const auto ec_group = Botan::EC_Group::from_name("numsp256d1");
return std::make_unique<Botan::ECDH_PrivateKey>(rng, ec_group);
} else {
// no custom curve used: up-call the default implementation
Expand All @@ -51,7 +51,7 @@ class Callbacks : public Botan::TLS::Callbacks {
if(std::holds_alternative<Botan::TLS::Group_Params>(group) &&
std::get<Botan::TLS::Group_Params>(group) == Botan::TLS::Group_Params(0xFE00)) {
// perform a key agreement on my custom curve
const Botan::EC_Group ec_group("numsp256d1");
const auto ec_group = Botan::EC_Group::from_name("numsp256d1");
Botan::ECDH_PublicKey peer_key(ec_group, ec_group.OS2ECP(public_value));
Botan::PK_Key_Agreement ka(private_key, rng, "Raw");
return ka.derive_key(0, peer_key.public_value()).bits_of();
Expand Down Expand Up @@ -104,16 +104,16 @@ int main() {
const Botan::BigInt a("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40");
const Botan::BigInt b("0x25581");
const Botan::BigInt n("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE43C8275EA265C6020AB20294751A825");
const Botan::BigInt cofactor(1);

const Botan::BigInt g_x("0x01");
const Botan::BigInt g_y("0x696F1853C1E466D7FC82C96CCEEEDD6BD02C2F9375894EC10BF46306C2B56C77");

// You should assign your own OID
const Botan::OID oid("1.3.6.1.4.1.25258.0.0.0");
// This is an OID reserved in Botan's private arc for numsp256d1
// If you use some other curve you should create your own OID
const Botan::OID oid("1.3.6.1.4.1.25258.4.1");

// create EC_Group object to register the curve
Botan::EC_Group numsp256d1(p, a, b, g_x, g_y, n, cofactor, oid);
Botan::EC_Group numsp256d1(oid, p, a, b, g_x, g_y, n);

if(!numsp256d1.verify_group(*rng)) {
return 1;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/ffi/ffi_pkey_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key, const Botan::BigInt& s
}

Botan::Null_RNG null_rng;
Botan::EC_Group grp(curve_name);
const auto grp = Botan::EC_Group::from_name(curve_name);
key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
return BOTAN_FFI_SUCCESS;
}
Expand All @@ -102,7 +102,7 @@ int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
return BOTAN_FFI_ERROR_NULL_POINTER;
}

Botan::EC_Group grp(curve_name);
const auto grp = Botan::EC_Group::from_name(curve_name);
Botan::EC_Point uncompressed_point = grp.point(public_x, public_y);
key.reset(new ECPublicKey_t(grp, uncompressed_point));
return BOTAN_FFI_SUCCESS;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/prov/pkcs11/p11_ecc_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session,
}

size_t PKCS11_EC_PrivateKey::key_length() const {
return m_domain_params.get_order().bits();
return m_domain_params.get_order_bits();
}

std::vector<uint8_t> PKCS11_EC_PrivateKey::raw_public_key_bits() const {
Expand Down
Loading
Loading