Skip to content

Commit

Permalink
Add a new bls test (#3235)
Browse files Browse the repository at this point in the history
## Issue Addressed

Which issue # does this PR address?
#2629 

## Proposed Changes

Please list or describe the changes introduced by this PR.

1. ci would dowload the bls test cases from https://github.com/ethereum/bls12-381-tests/
2. all the bls test cases(except eth ones) would use cases in the archive from step one
3. The bls test cases from https://github.com/ethereum/consensus-spec-tests would stay there and no use . For the future , these bls test cases would be remove suggested from ethereum/consensus-spec-tests#25 . So it would do no harm and compatible for future cases.

## Additional Info

Please provide any additional information. For example, future considerations
or information useful for reviewers.


Question: 

I am not sure if I should implement tests about `deserialization_G1`, `deserialization_G2` and `hash_to_G2` for the issue.
  • Loading branch information
zsluedem committed Oct 12, 2022
1 parent 242ae21 commit 9f24213
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 54 deletions.
8 changes: 8 additions & 0 deletions crypto/bls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub mod generics {
pub use crate::generic_secret_key::GenericSecretKey;
pub use crate::generic_signature::GenericSignature;
pub use crate::generic_signature_bytes::GenericSignatureBytes;
pub use crate::generic_signature_set::WrappedSignature;
}

/// Defines all the fundamental BLS points which should be exported by this crate by making
Expand All @@ -109,6 +110,13 @@ macro_rules! define_mod {
pub type AggregatePublicKey =
GenericAggregatePublicKey<bls_variant::PublicKey, bls_variant::AggregatePublicKey>;
pub type Signature = GenericSignature<bls_variant::PublicKey, bls_variant::Signature>;
pub type BlsWrappedSignature<'a> = WrappedSignature<
'a,
bls_variant::PublicKey,
bls_variant::AggregatePublicKey,
bls_variant::Signature,
bls_variant::AggregateSignature,
>;
pub type AggregateSignature = GenericAggregateSignature<
bls_variant::PublicKey,
bls_variant::AggregatePublicKey,
Expand Down
1 change: 1 addition & 0 deletions testing/ef_tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/consensus-spec-tests
.accessed_file_log.txt
/bls12-381-tests
21 changes: 18 additions & 3 deletions testing/ef_tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,38 @@ TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))

REPO_NAME := consensus-spec-tests
OUTPUT_DIR := ./$(REPO_NAME)

BASE_URL := https://github.com/ethereum/$(REPO_NAME)/releases/download/$(TESTS_TAG)

BLS_TEST_REPO_NAME := bls12-381-tests
BLS_TEST_TAG := v0.1.1
BLS_TEST = bls_tests_yaml
BLS_TARBALL = $(patsubst %,%-$(BLS_TEST_TAG).tar.gz,$(BLS_TEST))
BLS_OUTPUT_DIR := $(OUTPUT_DIR)/$(BLS_TEST_REPO_NAME)
BLS_BASE_URL := https://github.com/ethereum/$(BLS_TEST_REPO_NAME)/releases/download/$(BLS_TEST_TAG)

all:
make $(OUTPUT_DIR)
make $(BLS_OUTPUT_DIR)

$(OUTPUT_DIR): $(TARBALLS)
mkdir $(OUTPUT_DIR)
for test_tarball in $^; do \
tar -xzf $$test_tarball -C $(OUTPUT_DIR);\
done

$(BLS_OUTPUT_DIR):
mkdir $(BLS_OUTPUT_DIR)
wget $(BLS_BASE_URL)/$(BLS_TEST).tar.gz -O $(BLS_TARBALL)
tar -xzf $(BLS_TARBALL) -C $(BLS_OUTPUT_DIR)

%-$(TESTS_TAG).tar.gz:
wget $(BASE_URL)/$*.tar.gz -O $@

clean-test-files:
rm -rf $(OUTPUT_DIR)
rm -rf $(OUTPUT_DIR) $(BLS_OUTPUT_DIR)

clean-archives:
rm -f $(TARBALLS)
rm -f $(TARBALLS) $(BLS_TARBALL)

clean: clean-test-files clean-archives

Expand Down
8 changes: 7 additions & 1 deletion testing/ef_tests/check_all_files_accessed.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@
# One of the EF researchers likes to pack the tarballs on a Mac
".*\.DS_Store.*",
# More Mac weirdness.
"tests/mainnet/bellatrix/operations/deposit/pyspec_tests/deposit_with_previous_fork_version__valid_ineffective/._meta.yaml"
"tests/mainnet/bellatrix/operations/deposit/pyspec_tests/deposit_with_previous_fork_version__valid_ineffective/._meta.yaml",
# bls tests are moved to bls12-381-tests directory
"tests/general/phase0/bls",
# some bls tests are not included now
"bls12-381-tests/deserialization_G1",
"bls12-381-tests/deserialization_G2",
"bls12-381-tests/hash_to_G2"
]

def normalize_path(path):
Expand Down
2 changes: 2 additions & 0 deletions testing/ef_tests/src/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use types::ForkName;

mod bls_aggregate_sigs;
mod bls_aggregate_verify;
mod bls_batch_verify;
mod bls_eth_aggregate_pubkeys;
mod bls_eth_fast_aggregate_verify;
mod bls_fast_aggregate_verify;
Expand All @@ -29,6 +30,7 @@ mod transition;
pub use self::fork_choice::*;
pub use bls_aggregate_sigs::*;
pub use bls_aggregate_verify::*;
pub use bls_batch_verify::*;
pub use bls_eth_aggregate_pubkeys::*;
pub use bls_eth_fast_aggregate_verify::*;
pub use bls_fast_aggregate_verify::*;
Expand Down
8 changes: 2 additions & 6 deletions testing/ef_tests/src/cases/bls_aggregate_sigs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, Signature};
use serde_derive::Deserialize;

Expand All @@ -10,13 +10,9 @@ pub struct BlsAggregateSigs {
pub output: String,
}

impl BlsCase for BlsAggregateSigs {}
impl_bls_load_case!(BlsAggregateSigs);

impl Case for BlsAggregateSigs {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let mut aggregate_signature = AggregateSignature::infinity();

Expand Down
8 changes: 2 additions & 6 deletions testing/ef_tests/src/cases/bls_aggregate_verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use types::Hash256;
Expand All @@ -18,13 +18,9 @@ pub struct BlsAggregateVerify {
pub output: bool,
}

impl BlsCase for BlsAggregateVerify {}
impl_bls_load_case!(BlsAggregateVerify);

impl Case for BlsAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let messages = self
.input
Expand Down
67 changes: 67 additions & 0 deletions testing/ef_tests/src/cases/bls_batch_verify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use super::*;
use crate::case_result::compare_result;
use crate::impl_bls_load_case;
use bls::{verify_signature_sets, BlsWrappedSignature, PublicKeyBytes, Signature, SignatureSet};
use serde_derive::Deserialize;
use std::borrow::Cow;
use std::str::FromStr;
use types::Hash256;

#[derive(Debug, Clone, Deserialize)]
pub struct BlsBatchVerifyInput {
pubkeys: Vec<PublicKeyBytes>,
messages: Vec<String>,
signatures: Vec<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BlsBatchVerify {
pub input: BlsBatchVerifyInput,
pub output: bool,
}

impl_bls_load_case!(BlsBatchVerify);

impl Case for BlsBatchVerify {
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let messages = self
.input
.messages
.iter()
.map(|s| Hash256::from_str(s).map_err(|e| Error::FailedToParseTest(format!("{:?}", e))))
.collect::<Result<Vec<_>, _>>()?;

let pubkeys = self
.input
.pubkeys
.iter()
.map(|pkb| {
pkb.decompress()
.map_err(|_| Error::FailedToParseTest("pubkeys parse error".to_string()))
})
.collect::<Result<Vec<_>, _>>()?;

let signatures = self
.input
.signatures
.iter()
.map(|s| {
Signature::from_str(s).map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))
})
.collect::<Result<Vec<_>, _>>()?;

let signature_set = messages
.iter()
.zip(pubkeys.iter())
.zip(signatures.iter())
.map(|((&message, pubkey), signature)| {
let wraped_signature = BlsWrappedSignature::from(signature);
SignatureSet::single_pubkey(wraped_signature, Cow::Borrowed(pubkey), message)
})
.collect::<Vec<_>>();

let signature_valid = verify_signature_sets(signature_set.iter());

compare_result::<bool, ()>(&Ok(signature_valid), &Some(self.output))
}
}
4 changes: 2 additions & 2 deletions testing/ef_tests/src/cases/bls_eth_aggregate_pubkeys.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{AggregatePublicKey, PublicKeyBytes};
use serde_derive::Deserialize;

Expand All @@ -10,7 +10,7 @@ pub struct BlsEthAggregatePubkeys {
pub output: Option<PublicKeyBytes>,
}

impl BlsCase for BlsEthAggregatePubkeys {}
impl_bls_load_case!(BlsEthAggregatePubkeys, "data.yaml");

impl Case for BlsEthAggregatePubkeys {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions testing/ef_tests/src/cases/bls_eth_fast_aggregate_verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
Expand All @@ -20,7 +20,7 @@ pub struct BlsEthFastAggregateVerify {
pub output: bool,
}

impl BlsCase for BlsEthFastAggregateVerify {}
impl_bls_load_case!(BlsEthFastAggregateVerify, "data.yaml");

impl Case for BlsEthFastAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
Expand Down
8 changes: 2 additions & 6 deletions testing/ef_tests/src/cases/bls_fast_aggregate_verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{AggregateSignature, PublicKeyBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
Expand All @@ -20,13 +20,9 @@ pub struct BlsFastAggregateVerify {
pub output: bool,
}

impl BlsCase for BlsFastAggregateVerify {}
impl_bls_load_case!(BlsFastAggregateVerify);

impl Case for BlsFastAggregateVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let message = Hash256::from_slice(
&hex::decode(&self.input.message[2..])
Expand Down
8 changes: 2 additions & 6 deletions testing/ef_tests/src/cases/bls_sign_msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::SecretKey;
use serde_derive::Deserialize;
use types::Hash256;
Expand All @@ -17,13 +17,9 @@ pub struct BlsSign {
pub output: Option<String>,
}

impl BlsCase for BlsSign {}
impl_bls_load_case!(BlsSign);

impl Case for BlsSign {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
// Convert private_key and message to required types
let sk = hex::decode(&self.input.privkey[2..])
Expand Down
8 changes: 2 additions & 6 deletions testing/ef_tests/src/cases/bls_verify_msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::case_result::compare_result;
use crate::cases::common::BlsCase;
use crate::impl_bls_load_case;
use bls::{PublicKeyBytes, Signature, SignatureBytes};
use serde_derive::Deserialize;
use std::convert::TryInto;
Expand All @@ -19,13 +19,9 @@ pub struct BlsVerify {
pub output: bool,
}

impl BlsCase for BlsVerify {}
impl_bls_load_case!(BlsVerify);

impl Case for BlsVerify {
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
fork_name == ForkName::Base
}

fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
let message = hex::decode(&self.input.message[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;
Expand Down
34 changes: 21 additions & 13 deletions testing/ef_tests/src/cases/common.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
use crate::cases::LoadCase;
use crate::decode::yaml_decode_file;
use crate::error::Error;
use serde_derive::Deserialize;
use ssz::Encode;
use ssz_derive::{Decode, Encode};
use std::convert::TryFrom;
use std::fmt::Debug;
use std::path::Path;
use tree_hash::TreeHash;
use types::ForkName;

/// Trait for all BLS cases to eliminate some boilerplate.
pub trait BlsCase: serde::de::DeserializeOwned {}

impl<T: BlsCase> LoadCase for T {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
yaml_decode_file(&path.join("data.yaml"))
}
}

/// Macro to wrap U128 and U256 so they deserialize correctly.
macro_rules! uint_wrapper {
($wrapper_name:ident, $wrapped_type:ty) => {
Expand Down Expand Up @@ -80,3 +67,24 @@ pub fn previous_fork(fork_name: ForkName) -> ForkName {
ForkName::Merge => ForkName::Altair, // TODO: Check this when tests are released..
}
}

#[macro_export]
macro_rules! impl_bls_load_case {
($case_name:ident) => {
use $crate::decode::yaml_decode_file;
impl LoadCase for $case_name {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
yaml_decode_file(&path)
}
}
};

($case_name:ident, $sub_path_name:expr) => {
use $crate::decode::yaml_decode_file;
impl LoadCase for $case_name {
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
yaml_decode_file(&path.join($sub_path_name))
}
}
};
}
Loading

0 comments on commit 9f24213

Please sign in to comment.