From fbc9b0eea96df10ad4bc21ee0ce18bca421cfb30 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 12 Jul 2024 08:32:29 -0400 Subject: [PATCH] Update EC keys and ops to use EC_Scalar / EC_AffinePoint internally --- src/lib/pubkey/ec_group/ec_group.cpp | 3 -- src/lib/pubkey/ec_group/ec_group.h | 7 ---- src/lib/pubkey/ecc_key/ecc_key.h | 2 ++ src/lib/pubkey/ecdh/ecdh.cpp | 10 +++--- src/lib/pubkey/ecdsa/ecdsa.cpp | 8 ++--- src/lib/pubkey/ecgdsa/ecgdsa.cpp | 10 ++---- src/lib/pubkey/ecies/ecies.cpp | 3 +- src/lib/pubkey/eckcdsa/eckcdsa.cpp | 16 ++++----- src/lib/pubkey/gost_3410/gost_3410.cpp | 8 ++--- src/lib/pubkey/rfc6979/rfc6979.cpp | 25 ++++++++------ src/lib/pubkey/rfc6979/rfc6979.h | 27 ++++++++------- src/lib/pubkey/sm2/sm2.cpp | 48 +++++++++++++++----------- src/lib/pubkey/sm2/sm2.h | 13 +++++-- src/lib/pubkey/sm2/sm2_enc.cpp | 4 +-- src/tests/test_rfc6979.cpp | 8 ++--- 15 files changed, 98 insertions(+), 94 deletions(-) diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index e7a7cbc265e..a2d7e1fe2cc 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -745,9 +745,6 @@ bool EC_Group::verify_group(RandomNumberGenerator& rng, bool strong) const { return true; } -EC_Group::Mul2Table::Mul2Table(const EC_Group& group, const EC_Point& h) : - EC_Group::Mul2Table(EC_AffinePoint(group, h)) {} - EC_Group::Mul2Table::Mul2Table(const EC_AffinePoint& h) : m_tbl(h._group()->make_mul2_table(h._inner())) {} EC_Group::Mul2Table::~Mul2Table() = default; diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h index a5dc7b1888f..60e23a10efe 100644 --- a/src/lib/pubkey/ec_group/ec_group.h +++ b/src/lib/pubkey/ec_group/ec_group.h @@ -225,13 +225,6 @@ class BOTAN_PUBLIC_API(2, 0) EC_Group final { /// Table for computing g*x + h*y class Mul2Table final { public: - /** - * Internal transition function - * - * @warning this will be removed in 3.6.0, NOT COVERED BY SEMVER - */ - Mul2Table(const EC_Group& group, const EC_Point& h); - /** * Create a table for computing g*x + h*y */ diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h index 567a10abf60..00f41b44a0a 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.h +++ b/src/lib/pubkey/ecc_key/ecc_key.h @@ -101,6 +101,7 @@ class BOTAN_PUBLIC_API(2, 0) EC_PublicKey : public virtual Public_Key { const BigInt& get_int_field(std::string_view field) const override; const EC_AffinePoint& _public_key() const; + protected: /** * Create a public key. @@ -152,6 +153,7 @@ class BOTAN_PUBLIC_API(2, 0) EC_PrivateKey : public virtual EC_PublicKey, const BigInt& get_int_field(std::string_view field) const final; const EC_Scalar& _private_key() const; + protected: /* * If x=0, creates a new private key in the domain diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 638365f2f34..fb3f7d61797 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -32,7 +32,7 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF { ECDH_KA_Operation(const ECDH_PrivateKey& key, std::string_view kdf, RandomNumberGenerator& rng) : PK_Ops::Key_Agreement_with_KDF(kdf), m_group(key.domain()), - m_l_times_priv(mul_cofactor_inv(m_group, key.private_value())), + m_l_times_priv(mul_cofactor_inv(m_group, key._private_key())), m_rng(rng) {} size_t agreed_value_size() const override { return m_group.get_p_bytes(); } @@ -51,18 +51,16 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF { } private: - static EC_Scalar mul_cofactor_inv(const EC_Group& group, const BigInt& bn) { + static EC_Scalar mul_cofactor_inv(const EC_Group& group, const EC_Scalar& x) { // We implement BSI TR-03111 ECKAEG which only matters in the (rare/deprecated) // case of a curve with cofactor. - auto private_key = EC_Scalar::from_bigint(group, bn); - if(group.has_cofactor()) { // We could precompute this but cofactors are rare auto l = group.inverse_mod_order(group.get_cofactor()); - return private_key * EC_Scalar::from_bigint(group, l); + return x * EC_Scalar::from_bigint(group, l); } else { - return private_key; + return x; } } diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 972a7c98adb..ef125563f9f 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -122,12 +122,12 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_Hash { ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, std::string_view padding, RandomNumberGenerator& rng) : PK_Ops::Signature_with_Hash(padding), m_group(ecdsa.domain()), - m_x(EC_Scalar::from_bigint(m_group, ecdsa.private_value())), + m_x(ecdsa._private_key()), m_b(EC_Scalar::random(m_group, rng)), m_b_inv(m_b.invert()) { #if defined(BOTAN_HAS_RFC6979_GENERATOR) m_rfc6979 = std::make_unique( - this->rfc6979_hash_function(), m_group.get_order(), ecdsa.private_value()); + this->rfc6979_hash_function(), m_group.get_order_bits(), ecdsa._private_key()); #endif } @@ -196,12 +196,12 @@ secure_vector ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_Hash { public: ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, std::string_view padding) : - PK_Ops::Verification_with_Hash(padding), m_group(ecdsa.domain()), m_gy_mul(m_group, ecdsa.public_point()) {} + PK_Ops::Verification_with_Hash(padding), m_group(ecdsa.domain()), m_gy_mul(ecdsa._public_key()) {} ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, const AlgorithmIdentifier& alg_id) : PK_Ops::Verification_with_Hash(alg_id, "ECDSA", true), m_group(ecdsa.domain()), - m_gy_mul(m_group, ecdsa.public_point()) {} + m_gy_mul(ecdsa._public_key()) {} bool verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) override; diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index 502e4d30b23..ff15e342bad 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -37,9 +37,7 @@ namespace { class ECGDSA_Signature_Operation final : public PK_Ops::Signature_with_Hash { public: ECGDSA_Signature_Operation(const ECGDSA_PrivateKey& ecgdsa, std::string_view emsa) : - PK_Ops::Signature_with_Hash(emsa), - m_group(ecgdsa.domain()), - m_x(EC_Scalar::from_bigint(m_group, ecgdsa.private_value())) {} + PK_Ops::Signature_with_Hash(emsa), m_group(ecgdsa.domain()), m_x(ecgdsa._private_key()) {} secure_vector raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) override; @@ -84,14 +82,12 @@ secure_vector ECGDSA_Signature_Operation::raw_sign(const uint8_t msg[], class ECGDSA_Verification_Operation final : public PK_Ops::Verification_with_Hash { public: ECGDSA_Verification_Operation(const ECGDSA_PublicKey& ecgdsa, std::string_view padding) : - PK_Ops::Verification_with_Hash(padding), - m_group(ecgdsa.domain()), - m_gy_mul(m_group, ecgdsa.public_point()) {} + PK_Ops::Verification_with_Hash(padding), m_group(ecgdsa.domain()), m_gy_mul(ecgdsa._public_key()) {} ECGDSA_Verification_Operation(const ECGDSA_PublicKey& ecgdsa, const AlgorithmIdentifier& alg_id) : PK_Ops::Verification_with_Hash(alg_id, "ECGDSA"), m_group(ecgdsa.domain()), - m_gy_mul(m_group, ecgdsa.public_point()) {} + m_gy_mul(ecgdsa._public_key()) {} bool verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) override; diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index 681060ed296..877b9440487 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -66,9 +66,8 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF { secure_vector raw_agree(const uint8_t w[], size_t w_len) override { const EC_Group& group = m_key.domain(); - const auto x = EC_Scalar::from_bigint(group, m_key.private_value()); if(auto input_point = EC_AffinePoint::deserialize(group, {w, w_len})) { - return input_point->mul(x, m_rng, m_ws).x_bytes(); + return input_point->mul(m_key._private_key(), m_rng, m_ws).x_bytes(); } else { throw Decoding_Error("ECIES - Invalid elliptic curve point"); } diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp index 728d0d4be72..2dd88ac8215 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -71,8 +71,8 @@ std::unique_ptr eckcdsa_signature_hash(const AlgorithmIdentifier& return HashFunction::create_or_throw(oid_info[1]); } -std::vector eckcdsa_prefix(const EC_Point& point, size_t hash_block_size) { - auto prefix = concat>(point.x_bytes(), point.y_bytes()); +std::vector eckcdsa_prefix(const EC_AffinePoint& point, size_t hash_block_size) { + auto prefix = point.xy_bytes>(); // Either truncate or zero-extend to match the hash block size prefix.resize(hash_block_size); @@ -117,10 +117,10 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature { public: ECKCDSA_Signature_Operation(const ECKCDSA_PrivateKey& eckcdsa, std::string_view padding) : m_group(eckcdsa.domain()), - m_x(EC_Scalar::from_bigint(m_group, eckcdsa.private_value())), + m_x(eckcdsa._private_key()), m_hash(eckcdsa_signature_hash(padding)), m_prefix_used(false) { - m_prefix = eckcdsa_prefix(eckcdsa.public_point(), m_hash->hash_block_size()); + m_prefix = eckcdsa_prefix(eckcdsa._public_key(), m_hash->hash_block_size()); } void update(const uint8_t msg[], size_t msg_len) override { @@ -191,18 +191,18 @@ class ECKCDSA_Verification_Operation final : public PK_Ops::Verification { public: ECKCDSA_Verification_Operation(const ECKCDSA_PublicKey& eckcdsa, std::string_view padding) : m_group(eckcdsa.domain()), - m_gy_mul(m_group, eckcdsa.public_point()), + m_gy_mul(eckcdsa._public_key()), m_hash(eckcdsa_signature_hash(padding)), m_prefix_used(false) { - m_prefix = eckcdsa_prefix(eckcdsa.public_point(), m_hash->hash_block_size()); + m_prefix = eckcdsa_prefix(eckcdsa._public_key(), m_hash->hash_block_size()); } ECKCDSA_Verification_Operation(const ECKCDSA_PublicKey& eckcdsa, const AlgorithmIdentifier& alg_id) : m_group(eckcdsa.domain()), - m_gy_mul(m_group, eckcdsa.public_point()), + m_gy_mul(eckcdsa._public_key()), m_hash(eckcdsa_signature_hash(alg_id)), m_prefix_used(false) { - m_prefix = eckcdsa_prefix(eckcdsa.public_point(), m_hash->hash_block_size()); + m_prefix = eckcdsa_prefix(eckcdsa._public_key(), m_hash->hash_block_size()); } void update(const uint8_t msg[], size_t msg_len) override; diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index ce8a9f610ea..7fe65aa880d 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -117,9 +117,7 @@ EC_Scalar gost_msg_to_scalar(const EC_Group& group, std::span msg class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_Hash { public: GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410, std::string_view emsa) : - PK_Ops::Signature_with_Hash(emsa), - m_group(gost_3410.domain()), - m_x(EC_Scalar::from_bigint(m_group, gost_3410.private_value())) {} + PK_Ops::Signature_with_Hash(emsa), m_group(gost_3410.domain()), m_x(gost_3410._private_key()) {} size_t signature_length() const override { return 2 * m_group.get_order_bytes(); } @@ -200,12 +198,12 @@ std::string gost_hash_from_algid(const AlgorithmIdentifier& alg_id) { class GOST_3410_Verification_Operation final : public PK_Ops::Verification_with_Hash { public: GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost, std::string_view padding) : - PK_Ops::Verification_with_Hash(padding), m_group(gost.domain()), m_gy_mul(m_group, gost.public_point()) {} + PK_Ops::Verification_with_Hash(padding), m_group(gost.domain()), m_gy_mul(gost._public_key()) {} GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost, const AlgorithmIdentifier& alg_id) : PK_Ops::Verification_with_Hash(gost_hash_from_algid(alg_id)), m_group(gost.domain()), - m_gy_mul(m_group, gost.public_point()) {} + m_gy_mul(gost._public_key()) {} bool verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) override; diff --git a/src/lib/pubkey/rfc6979/rfc6979.cpp b/src/lib/pubkey/rfc6979/rfc6979.cpp index cccf3448750..84a39c24172 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.cpp +++ b/src/lib/pubkey/rfc6979/rfc6979.cpp @@ -1,6 +1,6 @@ /* * RFC 6979 Deterministic Nonce Generator -* (C) 2014,2015 Jack Lloyd +* (C) 2014,2015,2024 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -13,20 +13,18 @@ namespace Botan { -RFC6979_Nonce_Generator::RFC6979_Nonce_Generator(std::string_view hash, const BigInt& order, const BigInt& x) : - m_order(order), - m_qlen(m_order.bits()), - m_rlen(m_qlen / 8 + (m_qlen % 8 ? 1 : 0)), - m_rng_in(m_rlen * 2), - m_rng_out(m_rlen) { +RFC6979_Nonce_Generator::~RFC6979_Nonce_Generator() = default; + +RFC6979_Nonce_Generator::RFC6979_Nonce_Generator(std::string_view hash, size_t order_bits, const BigInt& x) : + m_qlen(order_bits), m_rlen((m_qlen + 7) / 8), m_rng_in(m_rlen * 2), m_rng_out(m_rlen) { m_hmac_drbg = std::make_unique(MessageAuthenticationCode::create_or_throw(fmt("HMAC({})", hash))); x.serialize_to(std::span{m_rng_in}.first(m_rlen)); } -RFC6979_Nonce_Generator::~RFC6979_Nonce_Generator() = default; +BigInt RFC6979_Nonce_Generator::nonce_for(const BigInt& order, const BigInt& m) { + BOTAN_DEBUG_ASSERT(order.bits() == m_qlen); -BigInt RFC6979_Nonce_Generator::nonce_for(const BigInt& m) { m.serialize_to(std::span{m_rng_in}.last(m_rlen)); m_hmac_drbg->initialize_with(m_rng_in); @@ -43,12 +41,19 @@ BigInt RFC6979_Nonce_Generator::nonce_for(const BigInt& m) { if(shift > 0) { k >>= shift; } - } while(k == 0 || k >= m_order); + } while(k == 0 || k >= order); return k; } #if defined(BOTAN_HAS_ECC_GROUP) +RFC6979_Nonce_Generator::RFC6979_Nonce_Generator(std::string_view hash, size_t order_bits, const EC_Scalar& scalar) : + m_qlen(order_bits), m_rlen((m_qlen + 7) / 8), m_rng_in(m_rlen * 2), m_rng_out(m_rlen) { + m_hmac_drbg = std::make_unique(MessageAuthenticationCode::create_or_throw(fmt("HMAC({})", hash))); + + scalar.serialize_to(std::span{m_rng_in}.first(m_rlen)); +} + EC_Scalar RFC6979_Nonce_Generator::nonce_for(const EC_Group& group, const EC_Scalar& m) { m.serialize_to(std::span{m_rng_in}.last(m_rlen)); diff --git a/src/lib/pubkey/rfc6979/rfc6979.h b/src/lib/pubkey/rfc6979/rfc6979.h index 8dabc7f269e..32f8637d1c6 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.h +++ b/src/lib/pubkey/rfc6979/rfc6979.h @@ -1,6 +1,6 @@ /* * RFC 6979 Deterministic Nonce Generator -* (C) 2014,2015 Jack Lloyd +* (C) 2014,2015,2024 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -10,7 +10,8 @@ #include #include -#include +#include +#include #if defined(BOTAN_HAS_ECC_GROUP) #include @@ -22,24 +23,24 @@ class HMAC_DRBG; class BOTAN_TEST_API RFC6979_Nonce_Generator final { public: - /** - * Note: keeps persistent reference to order - */ - RFC6979_Nonce_Generator(std::string_view hash, const BigInt& order, const BigInt& x); + RFC6979_Nonce_Generator(std::string_view hash, size_t order_bits, const BigInt& x); - ~RFC6979_Nonce_Generator(); + BigInt nonce_for(const BigInt& group_order, const BigInt& m); #if defined(BOTAN_HAS_ECC_GROUP) + RFC6979_Nonce_Generator(std::string_view hash, size_t order_bits, const EC_Scalar& scalar); + EC_Scalar nonce_for(const EC_Group& group, const EC_Scalar& m); #endif - BigInt nonce_for(const BigInt& m); + ~RFC6979_Nonce_Generator(); private: - const BigInt& m_order; - size_t m_qlen, m_rlen; + size_t m_qlen; + size_t m_rlen; std::unique_ptr m_hmac_drbg; - secure_vector m_rng_in, m_rng_out; + secure_vector m_rng_in; + secure_vector m_rng_out; }; /** @@ -49,8 +50,8 @@ class BOTAN_TEST_API RFC6979_Nonce_Generator final { * @param hash the hash function used to generate h */ inline BigInt generate_rfc6979_nonce(const BigInt& x, const BigInt& q, const BigInt& h, std::string_view hash) { - RFC6979_Nonce_Generator gen(hash, q, x); - return gen.nonce_for(h); + RFC6979_Nonce_Generator gen(hash, q.bits(), x); + return gen.nonce_for(q, h); } } // namespace Botan diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp index bfedd06ef32..2f2c988c243 100644 --- a/src/lib/pubkey/sm2/sm2.cpp +++ b/src/lib/pubkey/sm2/sm2.cpp @@ -47,19 +47,21 @@ bool SM2_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { } SM2_PrivateKey::SM2_PrivateKey(const AlgorithmIdentifier& alg_id, std::span key_bits) : - EC_PrivateKey(alg_id, key_bits) { - m_da_inv = domain().inverse_mod_order(private_value() + 1); -} + EC_PrivateKey(alg_id, key_bits), + m_da_inv((this->_private_key() + EC_Scalar::one(domain())).invert()), + m_da_inv_legacy(m_da_inv.to_bigint()) {} SM2_PrivateKey::SM2_PrivateKey(RandomNumberGenerator& rng, const EC_Group& domain, const BigInt& x) : - EC_PrivateKey(rng, domain, x) { - m_da_inv = domain.inverse_mod_order(private_value() + 1); -} + EC_PrivateKey(rng, domain, x), + m_da_inv((this->_private_key() + EC_Scalar::one(domain)).invert()), + m_da_inv_legacy(m_da_inv.to_bigint()) {} + +namespace { std::vector sm2_compute_za(HashFunction& hash, std::string_view user_id, - const EC_Group& domain, - const EC_Point& pubkey) { + const EC_Group& group, + const EC_AffinePoint& pubkey) { if(user_id.size() >= 8192) { throw Invalid_Argument("SM2 user id too long to represent"); } @@ -70,34 +72,30 @@ std::vector sm2_compute_za(HashFunction& hash, hash.update(get_byte<1>(uid_len)); hash.update(user_id); - const size_t p_bytes = domain.get_p_bytes(); + const size_t p_bytes = group.get_p_bytes(); - hash.update(domain.get_a().serialize(p_bytes)); - hash.update(domain.get_b().serialize(p_bytes)); - hash.update(domain.get_g_x().serialize(p_bytes)); - hash.update(domain.get_g_y().serialize(p_bytes)); + hash.update(group.get_a().serialize(p_bytes)); + hash.update(group.get_b().serialize(p_bytes)); + hash.update(group.get_g_x().serialize(p_bytes)); + hash.update(group.get_g_y().serialize(p_bytes)); hash.update(pubkey.xy_bytes()); return hash.final>(); } -namespace { - /** * SM2 signature operation */ class SM2_Signature_Operation final : public PK_Ops::Signature { public: SM2_Signature_Operation(const SM2_PrivateKey& sm2, std::string_view ident, std::string_view hash) : - m_group(sm2.domain()), - m_x(EC_Scalar::from_bigint(m_group, sm2.private_value())), - m_da_inv(EC_Scalar::from_bigint(m_group, sm2.get_da_inv())) { + m_group(sm2.domain()), m_x(sm2._private_key()), m_da_inv(sm2._get_da_inv()) { if(hash == "Raw") { // m_hash is null, m_za is empty } else { m_hash = HashFunction::create_or_throw(hash); // ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA) - m_za = sm2_compute_za(*m_hash, ident, m_group, sm2.public_point()); + m_za = sm2_compute_za(*m_hash, ident, m_group, sm2._public_key()); m_hash->update(m_za); } } @@ -155,13 +153,13 @@ secure_vector SM2_Signature_Operation::sign(RandomNumberGenerator& rng) class SM2_Verification_Operation final : public PK_Ops::Verification { public: SM2_Verification_Operation(const SM2_PublicKey& sm2, std::string_view ident, std::string_view hash) : - m_group(sm2.domain()), m_gy_mul(m_group, sm2.public_point()) { + m_group(sm2.domain()), m_gy_mul(sm2._public_key()) { if(hash == "Raw") { // m_hash is null, m_za is empty } else { m_hash = HashFunction::create_or_throw(hash); // ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA) - m_za = sm2_compute_za(*m_hash, ident, m_group, sm2.public_point()); + m_za = sm2_compute_za(*m_hash, ident, m_group, sm2._public_key()); m_hash->update(m_za); } } @@ -244,6 +242,14 @@ std::unique_ptr SM2_PublicKey::generate_another(RandomNumberGenerat return std::make_unique(rng, domain()); } +std::vector sm2_compute_za(HashFunction& hash, + std::string_view user_id, + const EC_Group& group, + const EC_Point& point) { + auto apoint = EC_AffinePoint(group, point); + return sm2_compute_za(hash, user_id, group, apoint); +} + std::unique_ptr SM2_PublicKey::create_verification_op(std::string_view params, std::string_view provider) const { if(provider == "base" || provider.empty()) { diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h index ef9d3061aef..9cf3733d55f 100644 --- a/src/lib/pubkey/sm2/sm2.h +++ b/src/lib/pubkey/sm2/sm2.h @@ -96,16 +96,25 @@ class BOTAN_PUBLIC_API(2, 2) SM2_PrivateKey final : public SM2_PublicKey, std::string_view params, std::string_view provider) const override; - const BigInt& get_da_inv() const { return m_da_inv; } + BOTAN_DEPRECATED("Deprecated no replacement") const BigInt& get_da_inv() const { return m_da_inv_legacy; } + + const EC_Scalar& _get_da_inv() const { return m_da_inv; } private: - BigInt m_da_inv; + EC_Scalar m_da_inv; + BigInt m_da_inv_legacy; }; BOTAN_DIAGNOSTIC_POP class HashFunction; +/* +* This is deprecated because it's not clear what it is useful for +* +* Open an issue on GH if you are using this +*/ +BOTAN_DEPRECATED("Deprecated unclear usage") std::vector BOTAN_PUBLIC_API(2, 5) sm2_compute_za(HashFunction& hash, std::string_view user_id, const EC_Group& domain, const EC_Point& pubkey); diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp index c54601333af..7785782b292 100644 --- a/src/lib/pubkey/sm2/sm2_enc.cpp +++ b/src/lib/pubkey/sm2/sm2_enc.cpp @@ -22,7 +22,7 @@ namespace { class SM2_Encryption_Operation final : public PK_Ops::Encryption { public: SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, std::string_view kdf_hash) : - m_group(key.domain()), m_peer(m_group, key.public_point()), m_ws(EC_Point::WORKSPACE_SIZE) { + m_group(key.domain()), m_peer(key._public_key()), m_ws(EC_Point::WORKSPACE_SIZE) { m_hash = HashFunction::create_or_throw(kdf_hash); m_kdf = KDF::create_or_throw(fmt("KDF2({})", kdf_hash)); } @@ -86,7 +86,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption { SM2_Decryption_Operation(const SM2_Encryption_PrivateKey& key, RandomNumberGenerator& rng, std::string_view kdf_hash) : - m_group(key.domain()), m_x(EC_Scalar::from_bigint(m_group, key.private_value())), m_rng(rng) { + m_group(key.domain()), m_x(key._private_key()), m_rng(rng) { m_hash = HashFunction::create_or_throw(kdf_hash); const std::string kdf_name = fmt("KDF2({})", kdf_hash); diff --git a/src/tests/test_rfc6979.cpp b/src/tests/test_rfc6979.cpp index 2ad7eead9c1..4f7d462d749 100644 --- a/src/tests/test_rfc6979.cpp +++ b/src/tests/test_rfc6979.cpp @@ -38,11 +38,11 @@ class RFC6979_KAT_Tests final : public Text_Based_Test { result.test_eq("vector matches", Botan::generate_rfc6979_nonce(X, Q, H, hash), K); - Botan::RFC6979_Nonce_Generator gen(hash, Q, X); + Botan::RFC6979_Nonce_Generator gen(hash, Q.bits(), X); - result.test_eq("vector matches", gen.nonce_for(H), K); - result.test_ne("different output for H+1", gen.nonce_for(H + 1), K); - result.test_eq("vector matches when run again", gen.nonce_for(H), K); + result.test_eq("vector matches", gen.nonce_for(Q, H), K); + result.test_ne("different output for H+1", gen.nonce_for(Q, H + 1), K); + result.test_eq("vector matches when run again", gen.nonce_for(Q, H), K); return result; }