Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Arkworks bls library integration #150

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 15 additions & 7 deletions bridges/snowbridge/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 4 additions & 27 deletions bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ use hex_literal::hex;

use snowbridge_pallet_ethereum_client_fixtures::*;

use primitives::{
fast_aggregate_verify, prepare_aggregate_pubkey, prepare_aggregate_signature,
verify_merkle_branch,
};
use primitives::{fast_aggregate_verify, verify_merkle_branch};
use util::*;

#[benchmarks]
Expand Down Expand Up @@ -76,39 +73,19 @@ mod benchmarks {
Ok(())
}

#[benchmark(extra)]
fn bls_fast_aggregate_verify_pre_aggregated() -> Result<(), BenchmarkError> {
EthereumBeaconClient::<T>::process_checkpoint_update(&make_checkpoint())?;
let update = make_sync_committee_update();
let participant_pubkeys = participant_pubkeys::<T>(&update)?;
let signing_root = signing_root::<T>(&update)?;
let agg_sig =
prepare_aggregate_signature(&update.sync_aggregate.sync_committee_signature).unwrap();
let agg_pub_key = prepare_aggregate_pubkey(&participant_pubkeys).unwrap();

#[block]
{
agg_sig.fast_aggregate_verify_pre_aggregated(signing_root.as_bytes(), &agg_pub_key);
}

Ok(())
}

#[benchmark(extra)]
fn bls_fast_aggregate_verify() -> Result<(), BenchmarkError> {
EthereumBeaconClient::<T>::process_checkpoint_update(&make_checkpoint())?;
let update = make_sync_committee_update();
let current_sync_committee = <CurrentSyncCommittee<T>>::get();
let absent_pubkeys = absent_pubkeys::<T>(&update)?;
let pub_keys = participant_pubkeys::<T>(&update).unwrap();
let signing_root = signing_root::<T>(&update)?;

#[block]
{
fast_aggregate_verify(
&current_sync_committee.aggregate_pubkey,
&absent_pubkeys,
pub_keys,
signing_root,
&update.sync_aggregate.sync_committee_signature,
update.sync_aggregate.sync_committee_signature,
)
.unwrap();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use codec::Decode;
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
use crate::{
decompress_sync_committee_bits, Config, CurrentSyncCommittee, Pallet as EthereumBeaconClient,
Update, ValidatorsRoot, Vec,
};
use primitives::PublicKeyPrepared;
use primitives::{PublicKeyPrepared, SyncCommitteePrepared};
use sp_core::H256;

pub fn participant_pubkeys<T: Config>(
update: &Update,
) -> Result<Vec<PublicKeyPrepared>, &'static str> {
let sync_committee_bits =
decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits);
let current_sync_committee = <CurrentSyncCommittee<T>>::get();
let current_sync_committee: SyncCommitteePrepared<{ crate::config::SYNC_COMMITTEE_SIZE }> =
SyncCommitteePrepared::decode(&mut &<CurrentSyncCommittee<T>>::get()[..]).unwrap();
let pubkeys = EthereumBeaconClient::<T>::find_pubkeys(
&sync_committee_bits,
(*current_sync_committee.pubkeys).as_ref(),
Expand All @@ -21,18 +23,6 @@ pub fn participant_pubkeys<T: Config>(
Ok(pubkeys)
}

pub fn absent_pubkeys<T: Config>(update: &Update) -> Result<Vec<PublicKeyPrepared>, &'static str> {
let sync_committee_bits =
decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits);
let current_sync_committee = <CurrentSyncCommittee<T>>::get();
let pubkeys = EthereumBeaconClient::<T>::find_pubkeys(
&sync_committee_bits,
(*current_sync_committee.pubkeys).as_ref(),
false,
);
Ok(pubkeys)
}

pub fn signing_root<T: Config>(update: &Update) -> Result<H256, &'static str> {
let validators_root = <ValidatorsRoot<T>>::get();
let signing_root = EthereumBeaconClient::<T>::signing_root(
Expand Down
35 changes: 21 additions & 14 deletions bridges/snowbridge/pallets/ethereum-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ use frame_support::{
};
use frame_system::ensure_signed;
use primitives::{
fast_aggregate_verify, verify_merkle_branch, verify_receipt_proof, BeaconHeader, BlsError,
CompactBeaconState, ForkData, ForkVersion, ForkVersions, PublicKeyPrepared, SigningData,
fast_aggregate_verify, verify_merkle_branch, verify_receipt_proof, ArkScaleProjective,
BeaconHeader, BlsError, CompactBeaconState, ForkData, ForkVersion, ForkVersions,
PublicKeyPrepared, SigningData,
};
use snowbridge_core::{BasicOperatingMode, RingBufferMap};
use sp_core::H256;
Expand Down Expand Up @@ -168,11 +169,13 @@ pub mod pallet {

/// Sync committee for current period
#[pallet::storage]
pub type CurrentSyncCommittee<T: Config> = StorageValue<_, SyncCommitteePrepared, ValueQuery>;
#[pallet::unbounded]
pub(super) type CurrentSyncCommittee<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;

/// Sync committee for next period
#[pallet::storage]
pub type NextSyncCommittee<T: Config> = StorageValue<_, SyncCommitteePrepared, ValueQuery>;
#[pallet::unbounded]
pub(super) type NextSyncCommittee<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;

/// The current operating mode of the pallet.
#[pallet::storage]
Expand Down Expand Up @@ -271,7 +274,7 @@ pub mod pallet {
let sync_committee_prepared: SyncCommitteePrepared = (&update.current_sync_committee)
.try_into()
.map_err(|_| <Error<T>>::BLSPreparePublicKeysFailed)?;
<CurrentSyncCommittee<T>>::set(sync_committee_prepared);
<CurrentSyncCommittee<T>>::set(sync_committee_prepared.encode());
<NextSyncCommittee<T>>::kill();
InitialCheckpointRoot::<T>::set(header_root);

Expand Down Expand Up @@ -380,7 +383,10 @@ pub mod pallet {
.hash_tree_root()
.map_err(|_| Error::<T>::SyncCommitteeHashTreeRootFailed)?;
if update_attested_period == store_period && <NextSyncCommittee<T>>::exists() {
let next_committee_root = <NextSyncCommittee<T>>::get().root;
let next_sync_committee =
SyncCommitteePrepared::decode(&mut &<NextSyncCommittee<T>>::get()[..])
.map_err(|_| Error::<T>::BLSPreparePublicKeysFailed)?;
let next_committee_root = next_sync_committee.root;
ensure!(
sync_committee_root == next_committee_root,
Error::<T>::InvalidSyncCommitteeUpdate
Expand Down Expand Up @@ -409,8 +415,10 @@ pub mod pallet {
} else {
<NextSyncCommittee<T>>::get()
};
let absent_pubkeys =
Self::find_pubkeys(&participation, (*sync_committee.pubkeys).as_ref(), false);
let sync_committee = SyncCommitteePrepared::decode(&mut &sync_committee[..])
.map_err(|_| Error::<T>::BLSPreparePublicKeysFailed)?;
let pubkeys =
Self::find_pubkeys(&participation, (*sync_committee.pubkeys).as_ref(), true);
let signing_root = Self::signing_root(
&update.attested_header,
Self::validators_root(),
Expand All @@ -420,10 +428,9 @@ pub mod pallet {
// suggested start from the full set aggregate_pubkey then subtracting the absolute
// minority that did not participate.
fast_aggregate_verify(
&sync_committee.aggregate_pubkey,
&absent_pubkeys,
pubkeys,
signing_root,
&update.sync_aggregate.sync_committee_signature,
update.sync_aggregate.sync_committee_signature,
)
.map_err(|e| Error::<T>::BLSVerificationFailed(e))?;

Expand Down Expand Up @@ -451,10 +458,10 @@ pub mod pallet {
update_finalized_period == store_period,
<Error<T>>::InvalidSyncCommitteeUpdate
);
<NextSyncCommittee<T>>::set(sync_committee_prepared);
<NextSyncCommittee<T>>::set(sync_committee_prepared.encode());
} else if update_finalized_period == store_period + 1 {
<CurrentSyncCommittee<T>>::set(<NextSyncCommittee<T>>::get());
<NextSyncCommittee<T>>::set(sync_committee_prepared);
<NextSyncCommittee<T>>::set(sync_committee_prepared.encode());
}
log::info!(
target: LOG_TARGET,
Expand Down Expand Up @@ -617,7 +624,7 @@ pub mod pallet {
let mut pubkeys: Vec<PublicKeyPrepared> = Vec::new();
for (bit, pubkey) in sync_committee_bits.iter().zip(sync_committee_pubkeys.iter()) {
if *bit == u8::from(participant) {
pubkeys.push(pubkey.clone());
pubkeys.push(ArkScaleProjective::from(pubkey.0));
}
}
pubkeys
Expand Down
12 changes: 6 additions & 6 deletions bridges/snowbridge/pallets/ethereum-client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ fn find_absent_keys() {
false,
);
assert_eq!(pubkeys.len(), 2);
assert_eq!(pubkeys[0], sync_committee_prepared.pubkeys[0]);
assert_eq!(pubkeys[1], sync_committee_prepared.pubkeys[7]);
assert_eq!(pubkeys[0].0, sync_committee_prepared.pubkeys[0].0);
assert_eq!(pubkeys[1].0, sync_committee_prepared.pubkeys[7].0);
});
}

Expand All @@ -280,10 +280,10 @@ fn find_present_keys() {
true,
);
assert_eq!(pubkeys.len(), 4);
assert_eq!(pubkeys[0], sync_committee_prepared.pubkeys[1]);
assert_eq!(pubkeys[1], sync_committee_prepared.pubkeys[8]);
assert_eq!(pubkeys[2], sync_committee_prepared.pubkeys[26]);
assert_eq!(pubkeys[3], sync_committee_prepared.pubkeys[30]);
assert_eq!(pubkeys[0].0, sync_committee_prepared.pubkeys[1].0);
assert_eq!(pubkeys[1].0, sync_committee_prepared.pubkeys[8].0);
assert_eq!(pubkeys[2].0, sync_committee_prepared.pubkeys[26].0);
assert_eq!(pubkeys[3].0, sync_committee_prepared.pubkeys[30].0);
});
}

Expand Down
16 changes: 16 additions & 0 deletions bridges/snowbridge/primitives/beacon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,27 @@ byte-slice-cast = { version = "1.2.1", default-features = false }
snowbridge-ethereum = { path = "../ethereum", default-features = false }
milagro-bls = { package = "snowbridge-milagro-bls", version = "1.5.4", default-features = false }

# ark libs
ark-bls12-381 = { version = "0.4.0", default-features = false, features = ["curve"] }
ark-bls12-381-ext = { version = "0.4.1", default-features = false }
ark-ec = { version = "0.4.2", default-features = false }
ark-ff = { version = "0.4.2", default-features = false }
ark-serialize = { version = "0.4.1", default-features = false, features = ["derive"] }
sha2 = { version = "0.10.6", default-features = false }
ark-scale = { version = "0.0.12", features = ["hazmat"], default-features = false }

[dev-dependencies]
hex-literal = { version = "0.4.1" }

[features]
default = ["std"]
std = [
"ark-bls12-381-ext/std",
"ark-bls12-381/std",
"ark-ec/std",
"ark-ff/std",
"ark-scale/std",
"ark-serialize/std",
"byte-slice-cast/std",
"codec/std",
"frame-support/std",
Expand All @@ -45,6 +60,7 @@ std = [
"rlp/std",
"scale-info/std",
"serde",
"sha2/std",
"snowbridge-ethereum/std",
"sp-core/std",
"sp-io/std",
Expand Down
Loading
Loading