-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GH-2334 Add bls_aggregate_signature and change serialization of bls_s…
…ignature to be affine non-montgomery little-endian
- Loading branch information
Showing
14 changed files
with
228 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,136 @@ | ||
#pragma once | ||
#include <fc/static_variant.hpp> | ||
#include <fc/crypto/elliptic.hpp> | ||
#include <fc/crypto/elliptic_r1.hpp> | ||
#include <fc/crypto/elliptic_webauthn.hpp> | ||
#include <fc/crypto/bls_public_key.hpp> | ||
#include <fc/reflect/reflect.hpp> | ||
#include <fc/reflect/variant.hpp> | ||
#include <fc/exception/exception.hpp> | ||
#include <bls12-381/bls12-381.hpp> | ||
|
||
|
||
namespace fc::crypto::blslib { | ||
|
||
namespace config { | ||
const std::string bls_signature_prefix = "SIG_BLS_"; | ||
}; | ||
|
||
class bls_signature | ||
{ | ||
public: | ||
|
||
bls_signature() = default; | ||
bls_signature( bls_signature&& ) = default; | ||
bls_signature( const bls_signature& ) = default; | ||
explicit bls_signature( const bls12_381::g2& sig ){_sig = sig;} | ||
// Immutable after construction. | ||
// Provides an efficient wrapper around bls12_381::g2. | ||
// Serialization form: | ||
// Non-Montgomery form and little-endian encoding for the field elements. | ||
// Affine form for the group element (the z component is 1 and not included in the serialization). | ||
// Binary serialization encodes x component first followed by y component. | ||
class bls_signature { | ||
public: | ||
bls_signature() = default; | ||
bls_signature(bls_signature&&) = default; | ||
bls_signature(const bls_signature&) = default; | ||
bls_signature& operator=(const bls_signature&) = default; | ||
bls_signature& operator=(bls_signature&&) = default; | ||
|
||
// throws if unable to convert to valid bls12_381::g2 | ||
explicit bls_signature(std::span<const uint8_t, 192> affine_non_montgomery_le); | ||
|
||
// affine non-montgomery base64url with bls_signature_prefix | ||
explicit bls_signature(const std::string& base64urlstr); | ||
|
||
// affine non-montgomery base64url with bls_signature_prefix | ||
std::string to_string() const; | ||
|
||
const bls12_381::g2& jacobian_montgomery_le() const { return _jacobian_montgomery_le; } | ||
const std::array<uint8_t, 192>& affine_non_montgomery_le() const { return _affine_non_montgomery_le; } | ||
|
||
// affine non-montgomery base64url with bls_signature_prefix | ||
explicit bls_signature(const std::string& base64urlstr); | ||
bool equal(const bls_signature& sig) const { | ||
return _jacobian_montgomery_le.equal(sig._jacobian_montgomery_le); | ||
} | ||
|
||
template<typename T> | ||
friend T& operator<<(T& ds, const bls_signature& sig) { | ||
ds.write(reinterpret_cast<const char*>(sig._affine_non_montgomery_le.data()), sig._affine_non_montgomery_le.size()*sizeof(uint8_t)); | ||
return ds; | ||
} | ||
|
||
// Could use FC_REFLECT, but to make it obvious serialization matches bls_aggregate_signature implement via operator | ||
template<typename T> | ||
friend T& operator>>(T& ds, bls_signature& sig) { | ||
ds.read(reinterpret_cast<char*>(sig._affine_non_montgomery_le.data()), sig._affine_non_montgomery_le.size()*sizeof(uint8_t)); | ||
constexpr bool check = true; // check if invalid | ||
constexpr bool raw = false; // non-montgomery | ||
std::optional<bls12_381::g2> g2 = bls12_381::g2::fromAffineBytesLE(sig._affine_non_montgomery_le, check, raw); | ||
FC_ASSERT(g2, "Invalid bls signature ${k}", ("k", sig._affine_non_montgomery_le)); | ||
sig._jacobian_montgomery_le = *g2; | ||
return ds; | ||
} | ||
|
||
private: | ||
std::array<uint8_t, 192> _affine_non_montgomery_le{}; | ||
bls12_381::g2 _jacobian_montgomery_le; // cached g2 | ||
}; | ||
|
||
bls_signature& operator= (const bls_signature& ) = default; | ||
// Serialization form: | ||
// Non-Montgomery form and little-endian encoding for the field elements. | ||
// Affine form for the group element (the z component is 1 and not included in the serialization). | ||
// Binary serialization encodes x component first followed by y component. | ||
class bls_aggregate_signature { | ||
public: | ||
bls_aggregate_signature() = default; | ||
bls_aggregate_signature(bls_aggregate_signature&&) = default; | ||
bls_aggregate_signature(const bls_aggregate_signature&) = default; | ||
bls_aggregate_signature& operator=(const bls_aggregate_signature&) = default; | ||
bls_aggregate_signature& operator=(bls_aggregate_signature&&) = default; | ||
|
||
// affine non-montgomery base64url with bls_signature_prefix | ||
std::string to_string(const yield_function_t& yield = yield_function_t()) const; | ||
// affine non-montgomery base64url with bls_signature_prefix | ||
explicit bls_aggregate_signature(const std::string& base64urlstr); | ||
|
||
bool equal( const bls_signature& sig ) const; | ||
explicit bls_aggregate_signature(const bls_signature& sig) | ||
: _jacobian_montgomery_le(sig.jacobian_montgomery_le()) {} | ||
|
||
bls12_381::g2 _sig; | ||
// aggregate signature into this | ||
void aggregate(const bls_signature& sig) { | ||
_jacobian_montgomery_le.addAssign(sig.jacobian_montgomery_le()); | ||
} | ||
// aggregate signature into this | ||
void aggregate(const bls_aggregate_signature& sig) { | ||
_jacobian_montgomery_le.addAssign(sig.jacobian_montgomery_le()); | ||
} | ||
|
||
}; // bls_signature | ||
// affine non-montgomery base64url with bls_signature_prefix | ||
std::string to_string() const; | ||
|
||
const bls12_381::g2& jacobian_montgomery_le() const { return _jacobian_montgomery_le; } | ||
|
||
bool equal( const bls_aggregate_signature& sig) const { | ||
return _jacobian_montgomery_le.equal(sig._jacobian_montgomery_le); | ||
} | ||
|
||
template<typename T> | ||
friend T& operator<<(T& ds, const bls_aggregate_signature& sig) { | ||
constexpr bool raw = false; | ||
std::array<uint8_t, 192> affine_non_montgomery_le = sig._jacobian_montgomery_le.toAffineBytesLE(raw); | ||
ds.write(reinterpret_cast<const char*>(affine_non_montgomery_le.data()), affine_non_montgomery_le.size()*sizeof(uint8_t)); | ||
return ds; | ||
} | ||
|
||
// Could use FC_REFLECT, but to make it obvious serialization matches bls_signature implement via operator | ||
template<typename T> | ||
friend T& operator>>(T& ds, bls_aggregate_signature& sig) { | ||
std::array<uint8_t, 192> affine_non_montgomery_le; | ||
ds.read(reinterpret_cast<char*>(affine_non_montgomery_le.data()), affine_non_montgomery_le.size()*sizeof(uint8_t)); | ||
constexpr bool check = true; // check if invalid | ||
constexpr bool raw = false; // non-montgomery | ||
std::optional<bls12_381::g2> g2 = bls12_381::g2::fromAffineBytesLE(affine_non_montgomery_le, check, raw); | ||
FC_ASSERT(g2, "Invalid bls aggregate signature ${k}", ("k", affine_non_montgomery_le)); | ||
sig._jacobian_montgomery_le = *g2; | ||
return ds; | ||
} | ||
|
||
private: | ||
bls12_381::g2 _jacobian_montgomery_le; | ||
}; | ||
|
||
} // fc::crypto::blslib | ||
|
||
namespace fc { | ||
void to_variant(const crypto::blslib::bls_signature& var, variant& vo, const yield_function_t& yield = yield_function_t()); | ||
|
||
void to_variant(const crypto::blslib::bls_signature& var, variant& vo); | ||
void from_variant(const variant& var, crypto::blslib::bls_signature& vo); | ||
} // namespace fc | ||
void to_variant(const crypto::blslib::bls_aggregate_signature& var, variant& vo); | ||
void from_variant(const variant& var, crypto::blslib::bls_aggregate_signature& vo); | ||
|
||
FC_REFLECT(bls12_381::fp, (d)) | ||
FC_REFLECT(bls12_381::fp2, (c0)(c1)) | ||
FC_REFLECT(bls12_381::g2, (x)(y)(z)) | ||
FC_REFLECT(crypto::blslib::bls_signature, (_sig) ) | ||
} // namespace fc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.