use super::*; use crate::case_result::compare_result; use crate::impl_bls_load_case; use bls::{AggregateSignature, PublicKeyBytes}; use serde::Deserialize; use types::Hash256; #[derive(Debug, Clone, Deserialize)] pub struct BlsFastAggregateVerifyInput { pub pubkeys: Vec, #[serde(alias = "messages")] pub message: String, pub signature: String, } #[derive(Debug, Clone, Deserialize)] pub struct BlsFastAggregateVerify { pub input: BlsFastAggregateVerifyInput, pub output: bool, } impl_bls_load_case!(BlsFastAggregateVerify); impl Case for BlsFastAggregateVerify { fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> { let message = Hash256::from_slice( &hex::decode(&self.input.message[2..]) .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?, ); let pubkeys_result = self .input .pubkeys .iter() .map(|pkb| pkb.try_into()) .collect::, _>>(); let pubkeys = match pubkeys_result { Ok(pubkeys) => pubkeys, Err(bls::Error::InvalidInfinityPublicKey) if !self.output => { return Ok(()); } Err(e) => return Err(Error::FailedToParseTest(format!("{:?}", e))), }; let pubkey_refs = pubkeys.iter().collect::>(); let signature_ok = hex::decode(&self.input.signature[2..]) .ok() .and_then(|bytes: Vec| AggregateSignature::deserialize(&bytes).ok()) .map(|signature| signature.fast_aggregate_verify(message, &pubkey_refs)) .unwrap_or(false); compare_result::(&Ok(signature_ok), &Some(self.output)) } }