Skip to content

Commit

Permalink
Merge pull request #194 from skalenetwork/feature/bls-aggregated-sign…
Browse files Browse the repository at this point in the history
…atures-alt-bn128

Feature/bls aggregated signatures alt bn128
  • Loading branch information
olehnikolaiev authored Jan 19, 2023
2 parents d06966f + 502b5c3 commit d9f468f
Show file tree
Hide file tree
Showing 18 changed files with 523 additions and 218 deletions.
7 changes: 2 additions & 5 deletions bls/BLSPrivateKeyShare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,8 @@ BLSPrivateKeyShare::generateSampleKeys( size_t _requiredSigners, size_t _totalSi
std::vector< libff::alt_bn128_Fr > skeys = dkg_obj.SecretKeyContribution( pol );

libff::alt_bn128_Fr common_skey = pol.at( 0 );
std::shared_ptr< BLSPublicKey > pkey_ptr = std::make_shared< BLSPublicKey >(
common_skey,
_requiredSigners,
_totalSigners
);
std::shared_ptr< BLSPublicKey > pkey_ptr =
std::make_shared< BLSPublicKey >( common_skey, _requiredSigners, _totalSigners );

for ( size_t i = 0; i < _totalSigners; ++i ) {
std::string key_str = libBLS::ThresholdUtils::fieldElementToString( skeys.at( i ) );
Expand Down
6 changes: 2 additions & 4 deletions bls/BLSPublicKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ BLSPublicKey::BLSPublicKey( const std::shared_ptr< std::vector< std::string > >
}
}

BLSPublicKey::BLSPublicKey( const libff::alt_bn128_G2& pkey, size_t t, size_t n )
: t( t ), n( n ) {
BLSPublicKey::BLSPublicKey( const libff::alt_bn128_G2& pkey, size_t t, size_t n ) : t( t ), n( n ) {
libBLS::ThresholdUtils::initCurve();

// do not check signers for compatibility
Expand All @@ -63,8 +62,7 @@ BLSPublicKey::BLSPublicKey( const libff::alt_bn128_G2& pkey, size_t t, size_t n
}
}

BLSPublicKey::BLSPublicKey(const libff::alt_bn128_Fr& skey, size_t t, size_t n )
: t( t ), n( n ) {
BLSPublicKey::BLSPublicKey( const libff::alt_bn128_Fr& skey, size_t t, size_t n ) : t( t ), n( n ) {
// do not check signers for compatibility
// libBLS::ThresholdUtils::checkSigners( t, n );

Expand Down
105 changes: 103 additions & 2 deletions bls/bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Bls::Bls( const size_t t, const size_t n ) : t_( t ), n_( n ) {
}

std::pair< libff::alt_bn128_Fr, libff::alt_bn128_G2 > Bls::KeyGeneration() {
// generate secret and public KeysRecover
// generate sample secret and public keys
libff::alt_bn128_Fr secret_key =
libff::alt_bn128_Fr::random_element(); // secret key generation

Expand Down Expand Up @@ -141,6 +141,43 @@ libff::alt_bn128_G1 Bls::HashBytes(
return hash;
}

libff::alt_bn128_G1 Bls::HashPublicKeyToG1( const libff::alt_bn128_G2& elem ) {
auto serialized_elem_vector = ThresholdUtils::G2ToString( elem, 16 );

std::string serialized_elem = std::accumulate(
serialized_elem_vector.begin(), serialized_elem_vector.end(), std::string( "" ) );

std::string hashed_pubkey = cryptlite::sha256::hash_hex( serialized_elem );

auto hash_bytes_arr = std::make_shared< std::array< uint8_t, 32 > >();

uint64_t bin_len;
if ( !ThresholdUtils::hex2carray( hashed_pubkey.c_str(), &bin_len, hash_bytes_arr->data() ) ) {
throw std::runtime_error( "Invalid hash" );
}

return ThresholdUtils::HashtoG1( hash_bytes_arr );
}

std::pair< libff::alt_bn128_G1, std::string > Bls::HashPublicKeyToG1WithHint(
const libff::alt_bn128_G2& elem ) {
auto serialized_elem_vector = ThresholdUtils::G2ToString( elem, 16 );

std::string serialized_elem = std::accumulate(
serialized_elem_vector.begin(), serialized_elem_vector.end(), std::string( "" ) );

std::string hashed_pubkey = cryptlite::sha256::hash_hex( serialized_elem );

auto hash_bytes_arr = std::make_shared< std::array< uint8_t, 32 > >();

uint64_t bin_len;
if ( !ThresholdUtils::hex2carray( hashed_pubkey.c_str(), &bin_len, hash_bytes_arr->data() ) ) {
throw std::runtime_error( "Invalid hash" );
}

return Bls::HashtoG1withHint( hash_bytes_arr );
}

libff::alt_bn128_G1 Bls::Signing(
const libff::alt_bn128_G1 hash, const libff::alt_bn128_Fr secret_key ) {
// sign a message with its hash and secret key
Expand All @@ -162,6 +199,48 @@ libff::alt_bn128_G1 Bls::Signing(
return sign;
}

libff::alt_bn128_G1 Bls::CoreSignAggregated(
const std::string& message, const libff::alt_bn128_Fr secret_key ) {
libff::alt_bn128_G1 hash = ThresholdUtils::HashtoG1( message );

return secret_key * hash;
}

libff::alt_bn128_G1 Bls::Aggregate( const std::vector< libff::alt_bn128_G1 >& signatures ) {
libff::alt_bn128_G1 res = libff::alt_bn128_G1::zero();

for ( const auto& signature : signatures ) {
if ( !ThresholdUtils::ValidateKey( signature ) ) {
throw ThresholdUtils::IsNotWellFormed(
"One of the signatures to be aggregated is malicious" );
}

res = res + signature;
}

return res;
}

bool Bls::CoreVerify( const libff::alt_bn128_G2& public_key, const std::string& message,
const libff::alt_bn128_G1& signature ) {
if ( !ThresholdUtils::ValidateKey( public_key ) || !ThresholdUtils::ValidateKey( signature ) ) {
throw ThresholdUtils::IsNotWellFormed( "Either signature or public key is malicious" );
}

libff::alt_bn128_G1 hash = ThresholdUtils::HashtoG1( message );

return libff::alt_bn128_ate_reduced_pairing( hash, public_key ) ==
libff::alt_bn128_ate_reduced_pairing( signature, libff::alt_bn128_G2::one() );
}

bool Bls::FastAggregateVerify( const std::vector< libff::alt_bn128_G2 >& public_keys,
const std::string& message, const libff::alt_bn128_G1& signature ) {
libff::alt_bn128_G2 sum =
std::accumulate( public_keys.begin(), public_keys.end(), libff::alt_bn128_G2::zero() );

return CoreVerify( sum, message, signature );
}

bool Bls::Verification( const std::string& to_be_hashed, const libff::alt_bn128_G1 sign,
const libff::alt_bn128_G2 public_key ) {
// verifies that a given signature corresponds to given public key
Expand Down Expand Up @@ -239,7 +318,7 @@ bool Bls::AggregatedVerification(
throw ThresholdUtils::IsNotWellFormed( "Error, public key is invalid" );
}

if ( !ThresholdUtils::isG2( public_key ) ) {
if ( !ThresholdUtils::ValidateKey( public_key ) ) {
throw ThresholdUtils::IsNotWellFormed( "Error, public key is not member of G2" );
}

Expand Down Expand Up @@ -298,4 +377,26 @@ libff::alt_bn128_G1 Bls::SignatureRecover( const std::vector< libff::alt_bn128_G
return sign; // first element is hash of a receiving message
}

libff::alt_bn128_G1 Bls::PopProve( const libff::alt_bn128_Fr& secret_key ) {
libff::alt_bn128_G2 public_key = secret_key * libff::alt_bn128_G2::one();

libff::alt_bn128_G1 hash = HashPublicKeyToG1( public_key );

libff::alt_bn128_G1 ret = secret_key * hash;

return ret;
}

bool Bls::PopVerify( const libff::alt_bn128_G2& public_key, const libff::alt_bn128_G1& prove ) {
if ( !ThresholdUtils::ValidateKey( prove ) || !ThresholdUtils::ValidateKey( public_key ) ) {
throw ThresholdUtils::IsNotWellFormed(
"incorrect input data to verify proof of possession" );
}

libff::alt_bn128_G1 hash = HashPublicKeyToG1( public_key );

return libff::alt_bn128_ate_reduced_pairing( hash, public_key ) ==
libff::alt_bn128_ate_reduced_pairing( prove, libff::alt_bn128_G2::one() );
}

} // namespace libBLS
23 changes: 22 additions & 1 deletion bls/bls.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Bls {
public:
Bls( const size_t t, const size_t n );

std::pair< libff::alt_bn128_Fr, libff::alt_bn128_G2 > KeyGeneration();
static std::pair< libff::alt_bn128_Fr, libff::alt_bn128_G2 > KeyGeneration();

static libff::alt_bn128_G1 Hashing( const std::string& message,
std::string ( *hash_func )( const std::string& str ) = cryptlite::sha256::hash_hex );
Expand All @@ -54,9 +54,25 @@ class Bls {
static std::pair< libff::alt_bn128_G1, std::string > HashtoG1withHint(
std::shared_ptr< std::array< uint8_t, 32 > > );

static libff::alt_bn128_G1 HashPublicKeyToG1( const libff::alt_bn128_G2& elem );

static std::pair< libff::alt_bn128_G1, std::string > HashPublicKeyToG1WithHint(
const libff::alt_bn128_G2& elem );

static libff::alt_bn128_G1 Signing(
const libff::alt_bn128_G1 hash, const libff::alt_bn128_Fr secret_key );

static libff::alt_bn128_G1 CoreSignAggregated(
const std::string& message, const libff::alt_bn128_Fr secret_key );

static libff::alt_bn128_G1 Aggregate( const std::vector< libff::alt_bn128_G1 >& signatures );

static bool CoreVerify( const libff::alt_bn128_G2& public_key, const std::string& message,
const libff::alt_bn128_G1& signature );

static bool FastAggregateVerify( const std::vector< libff::alt_bn128_G2 >& public_keys,
const std::string& message, const libff::alt_bn128_G1& signature );

static bool Verification( const std::string& to_be_hashed, const libff::alt_bn128_G1 sign,
const libff::alt_bn128_G2 public_key );

Expand All @@ -74,6 +90,11 @@ class Bls {
libff::alt_bn128_G1 SignatureRecover( const std::vector< libff::alt_bn128_G1 >& shares,
const std::vector< libff::alt_bn128_Fr >& coeffs );

static libff::alt_bn128_G1 PopProve( const libff::alt_bn128_Fr& secret_key );

static bool PopVerify(
const libff::alt_bn128_G2& public_key, const libff::alt_bn128_G1& prove );

private:
const size_t t_ = 0;

Expand Down
7 changes: 1 addition & 6 deletions dkg/dkg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ bool Dkg::Verification( size_t idx, libff::alt_bn128_Fr share,
// idx-th node verifies that share corresponds to the verification vector
libff::alt_bn128_G2 value = libff::alt_bn128_G2::zero();
for ( size_t i = 0; i < this->t_; ++i ) {
if ( !this->isG2( verification_vector[i] ) ) {
if ( !ThresholdUtils::ValidateKey( verification_vector[i] ) ) {
return false;
}
value = value + power( libff::alt_bn128_Fr( idx + 1 ), i ) * verification_vector[i];
Expand All @@ -134,9 +134,4 @@ size_t Dkg::GetN() const {
return this->n_;
}

bool Dkg::isG2( const libff::alt_bn128_G2& point ) {
return point.is_well_formed() &&
libff::alt_bn128_G2::order() * point == libff::alt_bn128_G2::zero();
}

} // namespace libBLS
2 changes: 0 additions & 2 deletions dkg/dkg.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ class Dkg {

size_t GetN() const;

static bool isG2( const libff::alt_bn128_G2& point );

private:
const size_t t_ = 0;

Expand Down
8 changes: 4 additions & 4 deletions test/test_TE_wrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE( ExceptionsTest ) {

{
// 1 coord of public key share is not a number
std::vector< std::string > pkey_str( {"123", "abc"} );
std::vector< std::string > pkey_str( { "123", "abc" } );
BOOST_REQUIRE_THROW(
TEPublicKeyShare( std::make_shared< std::vector< std::string > >( pkey_str ), 1,
num_signed, num_all ),
Expand All @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE( ExceptionsTest ) {

{
// wrong formated public key share
std::vector< std::string > pkey_str( {"0", "0", "0", "0"} );
std::vector< std::string > pkey_str( { "0", "0", "0", "0" } );
BOOST_REQUIRE_THROW(
TEPublicKeyShare( std::make_shared< std::vector< std::string > >( pkey_str ), 1,
num_signed, num_all ),
Expand All @@ -364,7 +364,7 @@ BOOST_AUTO_TEST_CASE( ExceptionsTest ) {

{
// one component public key share
std::vector< std::string > pkey_str( {"1232450"} );
std::vector< std::string > pkey_str( { "1232450" } );
BOOST_REQUIRE_THROW(
TEPublicKeyShare( std::make_shared< std::vector< std::string > >( pkey_str ), 1,
num_signed, num_all ),
Expand Down Expand Up @@ -465,7 +465,7 @@ BOOST_AUTO_TEST_CASE( ExceptionsTest ) {

{
// wrong formated public key
std::vector< std::string > pkey_str( {"0", "0", "0", "0"} );
std::vector< std::string > pkey_str( { "0", "0", "0", "0" } );
BOOST_REQUIRE_THROW(
TEPublicKey(
std::make_shared< std::vector< std::string > >( pkey_str ), num_signed, num_all ),
Expand Down
Loading

0 comments on commit d9f468f

Please sign in to comment.