diff --git a/libraries/libfc/include/fc/crypto/bls_public_key.hpp b/libraries/libfc/include/fc/crypto/bls_public_key.hpp index 63c3467a2a..f7e86b4717 100644 --- a/libraries/libfc/include/fc/crypto/bls_public_key.hpp +++ b/libraries/libfc/include/fc/crypto/bls_public_key.hpp @@ -22,8 +22,9 @@ namespace fc::crypto::blslib { bls_public_key() = default; bls_public_key(bls_public_key&&) = default; bls_public_key(const bls_public_key&) = default; - bls_public_key& operator=(const bls_public_key&) = default; - bls_public_key& operator=(bls_public_key&&) = default; + + // Would prefer to not have this to enforce immutablity. Needed so keys can be copied around. + bls_public_key& operator=(const bls_public_key& rhs); // throws if unable to convert to valid bls12_381::g1 explicit bls_public_key(std::span affine_non_montgomery_le); @@ -54,8 +55,8 @@ namespace fc::crypto::blslib { friend struct fc::has_reflector_init; void reflector_init(); - std::array _affine_non_montgomery_le{}; - bls12_381::g1 _jacobian_montgomery_le; // cached g1 + const std::array _affine_non_montgomery_le{}; + const bls12_381::g1 _jacobian_montgomery_le; // cached g1 }; } // fc::crypto::blslib diff --git a/libraries/libfc/src/crypto/bls_public_key.cpp b/libraries/libfc/src/crypto/bls_public_key.cpp index 884ca5baa6..4baee03b36 100644 --- a/libraries/libfc/src/crypto/bls_public_key.cpp +++ b/libraries/libfc/src/crypto/bls_public_key.cpp @@ -5,33 +5,44 @@ namespace fc::crypto::blslib { - bls_public_key::bls_public_key(std::span affine_non_montgomery_le) { - std::ranges::copy(affine_non_montgomery_le, _affine_non_montgomery_le.begin()); - constexpr bool check = true; // verify - constexpr bool raw = false; // to montgomery - auto g1 = bls12_381::g1::fromAffineBytesLE(affine_non_montgomery_le, check, raw); - FC_ASSERT(g1, "Invalid bls_public_key"); - _jacobian_montgomery_le = *g1; - } - - static std::tuple> pub_parse_base64url(const std::string& base64urlstr) { + inline std::array deserialize_base64url(const std::string& base64urlstr) { auto res = std::mismatch(config::bls_public_key_prefix.begin(), config::bls_public_key_prefix.end(), base64urlstr.begin()); FC_ASSERT(res.first == config::bls_public_key_prefix.end(), "BLS Public Key has invalid format : ${str}", ("str", base64urlstr)); auto data_str = base64urlstr.substr(config::bls_public_key_prefix.size()); - std::array bytes = fc::crypto::blslib::deserialize_base64url>(data_str); - + return fc::crypto::blslib::deserialize_base64url>(data_str); + } + + inline bls12_381::g1 from_affine_bytes_le(const std::array& affine_non_montgomery_le) { constexpr bool check = true; // check if base64urlstr is invalid constexpr bool raw = false; // non-montgomery - std::optional g1 = bls12_381::g1::fromAffineBytesLE(bytes, check, raw); + std::optional g1 = bls12_381::g1::fromAffineBytesLE(affine_non_montgomery_le, check, raw); FC_ASSERT(g1); - return {*g1, bytes}; + return *g1; + } + + inline std::array from_span(std::span affine_non_montgomery_le) { + std::array r; + std::ranges::copy(affine_non_montgomery_le, r.begin()); + return r; + } + + bls_public_key::bls_public_key(std::span affine_non_montgomery_le) + : _affine_non_montgomery_le(from_span(affine_non_montgomery_le)) + , _jacobian_montgomery_le(from_affine_bytes_le(_affine_non_montgomery_le)) { + } + + bls_public_key::bls_public_key(const std::string& base64urlstr) + : _affine_non_montgomery_le(deserialize_base64url(base64urlstr)) + , _jacobian_montgomery_le(from_affine_bytes_le(_affine_non_montgomery_le)) { } - bls_public_key::bls_public_key(const std::string& base64urlstr) { - std::tie(_jacobian_montgomery_le, _affine_non_montgomery_le) = pub_parse_base64url(base64urlstr); + bls_public_key& bls_public_key::operator=(const bls_public_key& rhs) { + const_cast&>(_affine_non_montgomery_le) = rhs._affine_non_montgomery_le; + const_cast(_jacobian_montgomery_le) = rhs._jacobian_montgomery_le; + return *this; } std::string bls_public_key::to_string() const { @@ -45,7 +56,8 @@ namespace fc::crypto::blslib { "FC unpack needs to call reflector_init otherwise unpacked_trx will not be initialized"); std::optional g1 = bls12_381::g1::fromAffineBytesLE(_affine_non_montgomery_le); FC_ASSERT(g1, "Invalid bls public key ${k}", ("k", _affine_non_montgomery_le)); - _jacobian_montgomery_le = *g1; + // reflector_init is private and only called during construction + const_cast(_jacobian_montgomery_le) = *g1; } } // fc::crypto::blslib