From 1d207aa0d809a49ea77d5d6cf7c1446e76543eee Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sun, 26 Jan 2025 21:09:02 +0100 Subject: [PATCH] LibCrypto: De-templetize and move `SECPxxxr1` methods out of line --- Libraries/LibCrypto/CMakeLists.txt | 1 + Libraries/LibCrypto/Curves/SECPxxxr1.cpp | 184 +++++++++++++++++ Libraries/LibCrypto/Curves/SECPxxxr1.h | 245 ++++------------------- 3 files changed, 228 insertions(+), 202 deletions(-) create mode 100644 Libraries/LibCrypto/Curves/SECPxxxr1.cpp diff --git a/Libraries/LibCrypto/CMakeLists.txt b/Libraries/LibCrypto/CMakeLists.txt index aa5c328a82a..d79ab85241a 100644 --- a/Libraries/LibCrypto/CMakeLists.txt +++ b/Libraries/LibCrypto/CMakeLists.txt @@ -28,6 +28,7 @@ set(SOURCES Curves/Curve25519.cpp Curves/Ed25519.cpp Curves/Ed448.cpp + Curves/SECPxxxr1.cpp Curves/X25519.cpp Curves/X448.cpp Hash/BLAKE2b.cpp diff --git a/Libraries/LibCrypto/Curves/SECPxxxr1.cpp b/Libraries/LibCrypto/Curves/SECPxxxr1.cpp new file mode 100644 index 00000000000..2641087bff8 --- /dev/null +++ b/Libraries/LibCrypto/Curves/SECPxxxr1.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2025, Altomani Gianluca + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include +#include +#include + +namespace Crypto::Curves { + +ErrorOr SECPxxxr1::generate_private_key_scalar() +{ + auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_Q_keygen(nullptr, nullptr, "EC", m_curve_name))); + + auto priv_bn = TRY(OpenSSL_BN::create()); + auto* priv_bn_ptr = priv_bn.ptr(); + OPENSSL_TRY(EVP_PKEY_get_bn_param(key.ptr(), OSSL_PKEY_PARAM_PRIV_KEY, &priv_bn_ptr)); + + return TRY(openssl_bignum_to_unsigned_big_integer(priv_bn)); +} + +ErrorOr SECPxxxr1::generate_public_key_point(UnsignedBigInteger scalar) +{ + auto* group = EC_GROUP_new_by_curve_name(EC_curve_nist2nid(m_curve_name)); + ScopeGuard const free_group = [&] { EC_GROUP_free(group); }; + + auto scalar_int = TRY(unsigned_big_integer_to_openssl_bignum(scalar)); + + auto* r = EC_POINT_new(group); + ScopeGuard const free_r = [&] { EC_POINT_free(r); }; + + OPENSSL_TRY(EC_POINT_mul(group, r, scalar_int.ptr(), nullptr, nullptr, nullptr)); + + auto x = TRY(OpenSSL_BN::create()); + auto y = TRY(OpenSSL_BN::create()); + + OPENSSL_TRY(EC_POINT_get_affine_coordinates(group, r, x.ptr(), y.ptr(), nullptr)); + + return SECPxxxr1Point { + TRY(openssl_bignum_to_unsigned_big_integer(x)), + TRY(openssl_bignum_to_unsigned_big_integer(y)), + m_scalar_size, + }; +} + +ErrorOr SECPxxxr1::compute_coordinate_point(UnsignedBigInteger scalar, SECPxxxr1Point point) +{ + auto* group = EC_GROUP_new_by_curve_name(EC_curve_nist2nid(m_curve_name)); + ScopeGuard const free_group = [&] { EC_GROUP_free(group); }; + + auto scalar_int = TRY(unsigned_big_integer_to_openssl_bignum(scalar)); + + auto qx = TRY(unsigned_big_integer_to_openssl_bignum(point.x)); + auto qy = TRY(unsigned_big_integer_to_openssl_bignum(point.y)); + + auto* q = EC_POINT_new(group); + ScopeGuard const free_q = [&] { EC_POINT_free(q); }; + + OPENSSL_TRY(EC_POINT_set_affine_coordinates(group, q, qx.ptr(), qy.ptr(), nullptr)); + + auto* r = EC_POINT_new(group); + ScopeGuard const free_r = [&] { EC_POINT_free(r); }; + + OPENSSL_TRY(EC_POINT_mul(group, r, nullptr, q, scalar_int.ptr(), nullptr)); + + auto rx = TRY(OpenSSL_BN::create()); + auto ry = TRY(OpenSSL_BN::create()); + + OPENSSL_TRY(EC_POINT_get_affine_coordinates(group, r, rx.ptr(), ry.ptr(), nullptr)); + + return SECPxxxr1Point { + TRY(openssl_bignum_to_unsigned_big_integer(rx)), + TRY(openssl_bignum_to_unsigned_big_integer(ry)), + m_scalar_size, + }; +} + +ErrorOr SECPxxxr1::verify_point(ReadonlyBytes hash, SECPxxxr1Point pubkey, SECPxxxr1Signature signature) +{ + auto ctx_import = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr))); + + OPENSSL_TRY(EVP_PKEY_fromdata_init(ctx_import.ptr())); + + auto* params_bld = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_new()); + ScopeGuard const free_params_bld = [&] { OSSL_PARAM_BLD_free(params_bld); }; + + OPENSSL_TRY(OSSL_PARAM_BLD_push_utf8_string(params_bld, OSSL_PKEY_PARAM_GROUP_NAME, m_curve_name, strlen(m_curve_name))); + + auto pubkey_bytes = TRY(pubkey.to_uncompressed()); + OPENSSL_TRY(OSSL_PARAM_BLD_push_octet_string(params_bld, OSSL_PKEY_PARAM_PUB_KEY, pubkey_bytes.data(), pubkey_bytes.size())); + + auto* params = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_to_param(params_bld)); + ScopeGuard const free_params = [&] { OSSL_PARAM_free(params); }; + + auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_new())); + auto* key_ptr = key.ptr(); + OPENSSL_TRY(EVP_PKEY_fromdata(ctx_import.ptr(), &key_ptr, EVP_PKEY_PUBLIC_KEY, params)); + + auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); + + OPENSSL_TRY(EVP_PKEY_verify_init(ctx.ptr())); + + auto* sig_obj = OPENSSL_TRY_PTR(ECDSA_SIG_new()); + ScopeGuard const free_sig_obj = [&] { ECDSA_SIG_free(sig_obj); }; + + auto r = TRY(unsigned_big_integer_to_openssl_bignum(signature.r)); + auto s = TRY(unsigned_big_integer_to_openssl_bignum(signature.s)); + + // Let sig_obj own a copy of r and s + OPENSSL_TRY(ECDSA_SIG_set0(sig_obj, BN_dup(r.ptr()), BN_dup(s.ptr()))); + + u8* sig = nullptr; + ScopeGuard const free_sig = [&] { OPENSSL_free(sig); }; + + auto sig_len = TRY([&] -> ErrorOr { + auto ret = i2d_ECDSA_SIG(sig_obj, &sig); + if (ret <= 0) { + OPENSSL_TRY(ret); + VERIFY_NOT_REACHED(); + } + return ret; + }()); + + auto ret = EVP_PKEY_verify(ctx.ptr(), sig, sig_len, hash.data(), hash.size()); + if (ret == 1) + return true; + if (ret == 0) + return false; + OPENSSL_TRY(ret); + VERIFY_NOT_REACHED(); +} + +ErrorOr SECPxxxr1::sign_scalar(ReadonlyBytes hash, UnsignedBigInteger private_key) +{ + auto ctx_import = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr))); + + OPENSSL_TRY(EVP_PKEY_fromdata_init(ctx_import.ptr())); + + auto d = TRY(unsigned_big_integer_to_openssl_bignum(private_key)); + + auto* params_bld = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_new()); + ScopeGuard const free_params_bld = [&] { OSSL_PARAM_BLD_free(params_bld); }; + + OPENSSL_TRY(OSSL_PARAM_BLD_push_utf8_string(params_bld, OSSL_PKEY_PARAM_GROUP_NAME, m_curve_name, strlen(m_curve_name))); + OPENSSL_TRY(OSSL_PARAM_BLD_push_BN(params_bld, OSSL_PKEY_PARAM_PRIV_KEY, d.ptr())); + + auto* params = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_to_param(params_bld)); + ScopeGuard const free_params = [&] { OSSL_PARAM_free(params); }; + + auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_new())); + auto* key_ptr = key.ptr(); + OPENSSL_TRY(EVP_PKEY_fromdata(ctx_import.ptr(), &key_ptr, EVP_PKEY_KEYPAIR, params)); + + auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); + + OPENSSL_TRY(EVP_PKEY_sign_init(ctx.ptr())); + + size_t sig_len = 0; + OPENSSL_TRY(EVP_PKEY_sign(ctx.ptr(), nullptr, &sig_len, hash.data(), hash.size())); + + auto sig = TRY(ByteBuffer::create_uninitialized(sig_len)); + OPENSSL_TRY(EVP_PKEY_sign(ctx.ptr(), sig.data(), &sig_len, hash.data(), hash.size())); + + auto const* sig_data = sig.data(); + auto* sig_obj = OPENSSL_TRY_PTR(d2i_ECDSA_SIG(nullptr, &sig_data, sig.size())); + ScopeGuard const free_sig_obj = [&] { ECDSA_SIG_free(sig_obj); }; + + // Duplicate r and s so that sig_obj can own them + auto r = TRY(OpenSSL_BN::wrap(BN_dup(OPENSSL_TRY_PTR(ECDSA_SIG_get0_r(sig_obj))))); + auto s = TRY(OpenSSL_BN::wrap(BN_dup(OPENSSL_TRY_PTR(ECDSA_SIG_get0_s(sig_obj))))); + + return SECPxxxr1Signature { + TRY(openssl_bignum_to_unsigned_big_integer(r)), + TRY(openssl_bignum_to_unsigned_big_integer(s)), + m_scalar_size, + }; +} + +} diff --git a/Libraries/LibCrypto/Curves/SECPxxxr1.h b/Libraries/LibCrypto/Curves/SECPxxxr1.h index 7bf9758ffab..a581ab3d097 100644 --- a/Libraries/LibCrypto/Curves/SECPxxxr1.h +++ b/Libraries/LibCrypto/Curves/SECPxxxr1.h @@ -14,11 +14,6 @@ #include #include -#include -#include -#include -#include - namespace { // Used by ASN1 macros static String s_error_string; @@ -26,10 +21,6 @@ static String s_error_string; namespace Crypto::Curves { -struct SECPxxxr1CurveParameters { - char const* name; -}; - struct SECPxxxr1Point { UnsignedBigInteger x; UnsignedBigInteger y; @@ -138,36 +129,31 @@ struct SECPxxxr1Signature { } }; -template class SECPxxxr1 : public EllipticCurve { - static constexpr size_t KEY_BIT_SIZE = bit_size; - static constexpr size_t KEY_BYTE_SIZE = ceil_div(KEY_BIT_SIZE, 8ull); - static constexpr size_t POINT_BYTE_SIZE = 1 + 2 * KEY_BYTE_SIZE; - public: - size_t key_size() override { return POINT_BYTE_SIZE; } + size_t key_size() override { return 1 + (2 * m_scalar_size); } + + ErrorOr generate_private_key_scalar(); + ErrorOr generate_public_key_point(UnsignedBigInteger scalar); + ErrorOr compute_coordinate_point(UnsignedBigInteger scalar, SECPxxxr1Point point); + ErrorOr verify_point(ReadonlyBytes hash, SECPxxxr1Point pubkey, SECPxxxr1Signature signature); + ErrorOr sign_scalar(ReadonlyBytes hash, UnsignedBigInteger private_key); + + ErrorOr derive_premaster_key_point(SECPxxxr1Point shared_point) + { + return shared_point; + } ErrorOr generate_private_key() override { auto key = TRY(generate_private_key_scalar()); - auto buffer = TRY(ByteBuffer::create_uninitialized(KEY_BYTE_SIZE)); + auto buffer = TRY(ByteBuffer::create_uninitialized(m_scalar_size)); auto buffer_bytes = buffer.bytes(); auto size = key.export_data(buffer_bytes); return buffer.slice(0, size); } - ErrorOr generate_private_key_scalar() - { - auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_Q_keygen(nullptr, nullptr, "EC", CURVE_PARAMETERS.name))); - - auto priv_bn = TRY(OpenSSL_BN::create()); - auto* priv_bn_ptr = priv_bn.ptr(); - OPENSSL_TRY(EVP_PKEY_get_bn_param(key.ptr(), OSSL_PKEY_PARAM_PRIV_KEY, &priv_bn_ptr)); - - return TRY(openssl_bignum_to_unsigned_big_integer(priv_bn)); - } - ErrorOr generate_public_key(ReadonlyBytes a) override { auto a_int = UnsignedBigInteger::import_data(a); @@ -175,70 +161,14 @@ public: return point.to_uncompressed(); } - ErrorOr generate_public_key_point(UnsignedBigInteger scalar) - { - auto* group = EC_GROUP_new_by_curve_name(EC_curve_nist2nid(CURVE_PARAMETERS.name)); - ScopeGuard const free_group = [&] { EC_GROUP_free(group); }; - - auto scalar_int = TRY(unsigned_big_integer_to_openssl_bignum(scalar)); - - auto* r = EC_POINT_new(group); - ScopeGuard const free_r = [&] { EC_POINT_free(r); }; - - OPENSSL_TRY(EC_POINT_mul(group, r, scalar_int.ptr(), nullptr, nullptr, nullptr)); - - auto x = TRY(OpenSSL_BN::create()); - auto y = TRY(OpenSSL_BN::create()); - - OPENSSL_TRY(EC_POINT_get_affine_coordinates(group, r, x.ptr(), y.ptr(), nullptr)); - - return SECPxxxr1Point { - TRY(openssl_bignum_to_unsigned_big_integer(x)), - TRY(openssl_bignum_to_unsigned_big_integer(y)), - KEY_BYTE_SIZE, - }; - } - ErrorOr compute_coordinate(ReadonlyBytes scalar_bytes, ReadonlyBytes point_bytes) override { auto scalar = UnsignedBigInteger::import_data(scalar_bytes); auto point = TRY(SECPxxxr1Point::from_uncompressed(point_bytes)); - auto result = TRY(compute_coordinate_point(scalar, { point.x, point.y, KEY_BYTE_SIZE })); + auto result = TRY(compute_coordinate_point(scalar, { point.x, point.y, m_scalar_size })); return result.to_uncompressed(); } - ErrorOr compute_coordinate_point(UnsignedBigInteger scalar, SECPxxxr1Point point) - { - auto* group = EC_GROUP_new_by_curve_name(EC_curve_nist2nid(CURVE_PARAMETERS.name)); - ScopeGuard const free_group = [&] { EC_GROUP_free(group); }; - - auto scalar_int = TRY(unsigned_big_integer_to_openssl_bignum(scalar)); - - auto qx = TRY(unsigned_big_integer_to_openssl_bignum(point.x)); - auto qy = TRY(unsigned_big_integer_to_openssl_bignum(point.y)); - - auto* q = EC_POINT_new(group); - ScopeGuard const free_q = [&] { EC_POINT_free(q); }; - - OPENSSL_TRY(EC_POINT_set_affine_coordinates(group, q, qx.ptr(), qy.ptr(), nullptr)); - - auto* r = EC_POINT_new(group); - ScopeGuard const free_r = [&] { EC_POINT_free(r); }; - - OPENSSL_TRY(EC_POINT_mul(group, r, nullptr, q, scalar_int.ptr(), nullptr)); - - auto rx = TRY(OpenSSL_BN::create()); - auto ry = TRY(OpenSSL_BN::create()); - - OPENSSL_TRY(EC_POINT_get_affine_coordinates(group, r, rx.ptr(), ry.ptr(), nullptr)); - - return SECPxxxr1Point { - TRY(openssl_bignum_to_unsigned_big_integer(rx)), - TRY(openssl_bignum_to_unsigned_big_integer(ry)), - KEY_BYTE_SIZE, - }; - } - ErrorOr derive_premaster_key(ReadonlyBytes shared_point_bytes) override { auto shared_point = TRY(SECPxxxr1Point::from_uncompressed(shared_point_bytes)); @@ -246,141 +176,52 @@ public: return premaster_key_point.to_uncompressed(); } - ErrorOr derive_premaster_key_point(SECPxxxr1Point shared_point) - { - return shared_point; - } - - ErrorOr verify_point(ReadonlyBytes hash, SECPxxxr1Point pubkey, SECPxxxr1Signature signature) - { - auto ctx_import = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr))); - - OPENSSL_TRY(EVP_PKEY_fromdata_init(ctx_import.ptr())); - - auto* params_bld = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_new()); - ScopeGuard const free_params_bld = [&] { OSSL_PARAM_BLD_free(params_bld); }; - - OPENSSL_TRY(OSSL_PARAM_BLD_push_utf8_string(params_bld, OSSL_PKEY_PARAM_GROUP_NAME, CURVE_PARAMETERS.name, strlen(CURVE_PARAMETERS.name))); - - auto pubkey_bytes = TRY(pubkey.to_uncompressed()); - OPENSSL_TRY(OSSL_PARAM_BLD_push_octet_string(params_bld, OSSL_PKEY_PARAM_PUB_KEY, pubkey_bytes.data(), pubkey_bytes.size())); - - auto* params = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_to_param(params_bld)); - ScopeGuard const free_params = [&] { OSSL_PARAM_free(params); }; - - auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_new())); - auto* key_ptr = key.ptr(); - OPENSSL_TRY(EVP_PKEY_fromdata(ctx_import.ptr(), &key_ptr, EVP_PKEY_PUBLIC_KEY, params)); - - auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); - - OPENSSL_TRY(EVP_PKEY_verify_init(ctx.ptr())); - - auto* sig_obj = OPENSSL_TRY_PTR(ECDSA_SIG_new()); - ScopeGuard const free_sig_obj = [&] { ECDSA_SIG_free(sig_obj); }; - - auto r = TRY(unsigned_big_integer_to_openssl_bignum(signature.r)); - auto s = TRY(unsigned_big_integer_to_openssl_bignum(signature.s)); - - // Let sig_obj own a copy of r and s - OPENSSL_TRY(ECDSA_SIG_set0(sig_obj, BN_dup(r.ptr()), BN_dup(s.ptr()))); - - u8* sig = nullptr; - ScopeGuard const free_sig = [&] { OPENSSL_free(sig); }; - - auto sig_len = TRY([&] -> ErrorOr { - auto ret = i2d_ECDSA_SIG(sig_obj, &sig); - if (ret <= 0) { - OPENSSL_TRY(ret); - VERIFY_NOT_REACHED(); - } - return ret; - }()); - - auto ret = EVP_PKEY_verify(ctx.ptr(), sig, sig_len, hash.data(), hash.size()); - if (ret == 1) - return true; - if (ret == 0) - return false; - OPENSSL_TRY(ret); - VERIFY_NOT_REACHED(); - } - ErrorOr verify(ReadonlyBytes hash, ReadonlyBytes pubkey, SECPxxxr1Signature signature) { auto pubkey_point = TRY(SECPxxxr1Point::from_uncompressed(pubkey)); return verify_point(hash, pubkey_point, signature); } - ErrorOr sign_scalar(ReadonlyBytes hash, UnsignedBigInteger private_key) - { - auto ctx_import = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr))); - - OPENSSL_TRY(EVP_PKEY_fromdata_init(ctx_import.ptr())); - - auto d = TRY(unsigned_big_integer_to_openssl_bignum(private_key)); - - auto* params_bld = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_new()); - ScopeGuard const free_params_bld = [&] { OSSL_PARAM_BLD_free(params_bld); }; - - OPENSSL_TRY(OSSL_PARAM_BLD_push_utf8_string(params_bld, OSSL_PKEY_PARAM_GROUP_NAME, CURVE_PARAMETERS.name, strlen(CURVE_PARAMETERS.name))); - OPENSSL_TRY(OSSL_PARAM_BLD_push_BN(params_bld, OSSL_PKEY_PARAM_PRIV_KEY, d.ptr())); - - auto* params = OPENSSL_TRY_PTR(OSSL_PARAM_BLD_to_param(params_bld)); - ScopeGuard const free_params = [&] { OSSL_PARAM_free(params); }; - - auto key = TRY(OpenSSL_PKEY::wrap(EVP_PKEY_new())); - auto* key_ptr = key.ptr(); - OPENSSL_TRY(EVP_PKEY_fromdata(ctx_import.ptr(), &key_ptr, EVP_PKEY_KEYPAIR, params)); - - auto ctx = TRY(OpenSSL_PKEY_CTX::wrap(EVP_PKEY_CTX_new_from_pkey(nullptr, key.ptr(), nullptr))); - - OPENSSL_TRY(EVP_PKEY_sign_init(ctx.ptr())); - - size_t sig_len = 0; - OPENSSL_TRY(EVP_PKEY_sign(ctx.ptr(), nullptr, &sig_len, hash.data(), hash.size())); - - auto sig = TRY(ByteBuffer::create_uninitialized(sig_len)); - OPENSSL_TRY(EVP_PKEY_sign(ctx.ptr(), sig.data(), &sig_len, hash.data(), hash.size())); - - auto const* sig_data = sig.data(); - auto* sig_obj = OPENSSL_TRY_PTR(d2i_ECDSA_SIG(nullptr, &sig_data, sig.size())); - ScopeGuard const free_sig_obj = [&] { ECDSA_SIG_free(sig_obj); }; - - // Duplicate r and s so that sig_obj can own them - auto r = TRY(OpenSSL_BN::wrap(BN_dup(OPENSSL_TRY_PTR(ECDSA_SIG_get0_r(sig_obj))))); - auto s = TRY(OpenSSL_BN::wrap(BN_dup(OPENSSL_TRY_PTR(ECDSA_SIG_get0_s(sig_obj))))); - - return SECPxxxr1Signature { - TRY(openssl_bignum_to_unsigned_big_integer(r)), - TRY(openssl_bignum_to_unsigned_big_integer(s)), - KEY_BYTE_SIZE, - }; - } - ErrorOr sign(ReadonlyBytes hash, ReadonlyBytes private_key_bytes) { auto signature = TRY(sign_scalar(hash, UnsignedBigInteger::import_data(private_key_bytes.data(), private_key_bytes.size()))); return signature; } + +protected: + SECPxxxr1(char const* curve_name, size_t scalar_size) + : m_curve_name(curve_name) + , m_scalar_size(scalar_size) + { + } + +private: + char const* m_curve_name; + size_t m_scalar_size; }; -// SECP256r1 curve -static constexpr SECPxxxr1CurveParameters SECP256r1_CURVE_PARAMETERS { - .name = "P-256", +class SECP256r1 : public SECPxxxr1 { +public: + SECP256r1() + : SECPxxxr1("P-256", 32) + { + } }; -using SECP256r1 = SECPxxxr1<256, SECP256r1_CURVE_PARAMETERS>; -// SECP384r1 curve -static constexpr SECPxxxr1CurveParameters SECP384r1_CURVE_PARAMETERS { - .name = "P-384", +class SECP384r1 : public SECPxxxr1 { +public: + SECP384r1() + : SECPxxxr1("P-384", 48) + { + } }; -using SECP384r1 = SECPxxxr1<384, SECP384r1_CURVE_PARAMETERS>; -// SECP521r1 curve -static constexpr SECPxxxr1CurveParameters SECP521r1_CURVE_PARAMETERS { - .name = "P-521", +class SECP521r1 : public SECPxxxr1 { +public: + SECP521r1() + : SECPxxxr1("P-521", 66) + { + } }; -using SECP521r1 = SECPxxxr1<521, SECP521r1_CURVE_PARAMETERS>; }