mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
Allow downloading of large tests from EF github and fix issues with serde
This commit is contained in:
@@ -1,30 +1,39 @@
|
||||
use super::{AggregatePublicKey, Signature};
|
||||
use super::{AggregatePublicKey, Signature, BLS_AGG_SIG_BYTE_SIZE};
|
||||
use bls_aggregates::{
|
||||
AggregatePublicKey as RawAggregatePublicKey, AggregateSignature as RawAggregateSignature,
|
||||
};
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_hex::{encode as hex_encode, PrefixedHexVisitor};
|
||||
use ssz::{
|
||||
decode_ssz_list, hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash,
|
||||
};
|
||||
use ssz::{decode_ssz_list, hash, Decodable, DecodeError, Encodable, SszStream, TreeHash};
|
||||
|
||||
/// A BLS aggregate signature.
|
||||
///
|
||||
/// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ
|
||||
/// serialization).
|
||||
#[derive(Debug, PartialEq, Clone, Default, Eq)]
|
||||
pub struct AggregateSignature(RawAggregateSignature);
|
||||
pub struct AggregateSignature {
|
||||
aggregate_signature: RawAggregateSignature,
|
||||
is_empty: bool,
|
||||
}
|
||||
|
||||
impl AggregateSignature {
|
||||
/// Instantiate a new AggregateSignature.
|
||||
///
|
||||
/// is_empty is false
|
||||
/// AggregateSiganture is point at infinity
|
||||
pub fn new() -> Self {
|
||||
AggregateSignature(RawAggregateSignature::new())
|
||||
Self {
|
||||
aggregate_signature: RawAggregateSignature::new(),
|
||||
is_empty: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add (aggregate) a signature to the `AggregateSignature`.
|
||||
pub fn add(&mut self, signature: &Signature) {
|
||||
self.0.add(signature.as_raw())
|
||||
if !self.is_empty {
|
||||
self.aggregate_signature.add(signature.as_raw())
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify the `AggregateSignature` against an `AggregatePublicKey`.
|
||||
@@ -37,7 +46,11 @@ impl AggregateSignature {
|
||||
domain: u64,
|
||||
aggregate_public_key: &AggregatePublicKey,
|
||||
) -> bool {
|
||||
self.0.verify(msg, domain, aggregate_public_key.as_raw())
|
||||
if self.is_empty {
|
||||
return false;
|
||||
}
|
||||
self.aggregate_signature
|
||||
.verify(msg, domain, aggregate_public_key.as_raw())
|
||||
}
|
||||
|
||||
/// Verify this AggregateSignature against multiple AggregatePublickeys with multiple Messages.
|
||||
@@ -50,6 +63,9 @@ impl AggregateSignature {
|
||||
domain: u64,
|
||||
aggregate_public_keys: &[&AggregatePublicKey],
|
||||
) -> bool {
|
||||
if self.is_empty {
|
||||
return false;
|
||||
}
|
||||
let aggregate_public_keys: Vec<&RawAggregatePublicKey> =
|
||||
aggregate_public_keys.iter().map(|pk| pk.as_raw()).collect();
|
||||
|
||||
@@ -59,14 +75,53 @@ impl AggregateSignature {
|
||||
msg.extend_from_slice(message);
|
||||
}
|
||||
|
||||
self.0
|
||||
self.aggregate_signature
|
||||
.verify_multiple(&msg[..], domain, &aggregate_public_keys[..])
|
||||
}
|
||||
|
||||
/// Return AggregateSiganture as bytes
|
||||
pub fn as_bytes(&self) -> Vec<u8> {
|
||||
if self.is_empty {
|
||||
return vec![0; BLS_AGG_SIG_BYTE_SIZE];
|
||||
}
|
||||
self.aggregate_signature.as_bytes()
|
||||
}
|
||||
|
||||
/// Convert bytes to AggregateSiganture
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
for byte in bytes {
|
||||
if *byte != 0 {
|
||||
let sig =
|
||||
RawAggregateSignature::from_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
|
||||
return Ok(Self {
|
||||
aggregate_signature: sig,
|
||||
is_empty: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(Self::empty_signature())
|
||||
}
|
||||
|
||||
/// Returns if the AggregateSiganture `is_empty`
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.is_empty
|
||||
}
|
||||
|
||||
/// Creates a new AggregateSignature
|
||||
///
|
||||
/// aggregate_signature set to the point infinity
|
||||
/// is_empty set to true
|
||||
pub fn empty_signature() -> Self {
|
||||
Self {
|
||||
aggregate_signature: RawAggregateSignature::new(),
|
||||
is_empty: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for AggregateSignature {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_vec(&self.0.as_bytes());
|
||||
s.append_vec(&self.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,35 +129,43 @@ impl Decodable for AggregateSignature {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
let (sig_bytes, i) = decode_ssz_list(bytes, i)?;
|
||||
let raw_sig =
|
||||
RawAggregateSignature::from_bytes(&sig_bytes).map_err(|_| DecodeError::TooShort)?;
|
||||
Ok((AggregateSignature(raw_sig), i))
|
||||
RawAggregateSignature::from_bytes(&sig_bytes).map_err(|_| DecodeError::Invalid)?;
|
||||
Ok((
|
||||
Self {
|
||||
aggregate_signature: raw_sig,
|
||||
is_empty: false,
|
||||
},
|
||||
i,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for AggregateSignature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&hex_encode(ssz_encode(self)))
|
||||
serializer.serialize_str(&hex_encode(self.as_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for AggregateSignature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(PrefixedHexVisitor)?;
|
||||
let (obj, _) = <_>::ssz_decode(&bytes[..], 0)
|
||||
let agg_sig = AggregateSignature::from_bytes(&bytes[..])
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||
Ok(obj)
|
||||
Ok(agg_sig)
|
||||
}
|
||||
}
|
||||
|
||||
impl TreeHash for AggregateSignature {
|
||||
fn hash_tree_root(&self) -> Vec<u8> {
|
||||
hash(&self.0.as_bytes())
|
||||
hash(&self.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ pub use crate::secret_key::SecretKey;
|
||||
pub use crate::signature::Signature;
|
||||
|
||||
pub const BLS_AGG_SIG_BYTE_SIZE: usize = 96;
|
||||
pub const BLS_SIG_BYTE_SIZE: usize = 96;
|
||||
|
||||
use hashing::hash;
|
||||
use ssz::ssz_encode;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::serde_vistors::HexVisitor;
|
||||
use super::{PublicKey, SecretKey};
|
||||
use super::{PublicKey, SecretKey, BLS_SIG_BYTE_SIZE};
|
||||
use bls_aggregates::Signature as RawSignature;
|
||||
use hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
@@ -63,7 +63,7 @@ impl Signature {
|
||||
/// Returns a new empty signature.
|
||||
pub fn empty_signature() -> Self {
|
||||
// Set RawSignature = infinity
|
||||
let mut empty: Vec<u8> = vec![0; 96];
|
||||
let mut empty: Vec<u8> = vec![0; BLS_SIG_BYTE_SIZE];
|
||||
empty[0] += u8::pow(2, 6) + u8::pow(2, 7);
|
||||
Signature {
|
||||
signature: RawSignature::from_bytes(&empty).unwrap(),
|
||||
@@ -121,6 +121,7 @@ impl TreeHash for Signature {
|
||||
}
|
||||
|
||||
impl Serialize for Signature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
@@ -130,14 +131,15 @@ impl Serialize for Signature {
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Signature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||
let (pubkey, _) = <_>::ssz_decode(&bytes[..], 0)
|
||||
let bytes: Vec<u8> = deserializer.deserialize_str(HexVisitor)?;
|
||||
let signature = Signature::from_bytes(&bytes[..])
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||
Ok(pubkey)
|
||||
Ok(signature)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +167,7 @@ mod tests {
|
||||
|
||||
let sig_as_bytes: Vec<u8> = sig.as_raw().as_bytes();
|
||||
|
||||
assert_eq!(sig_as_bytes.len(), 96);
|
||||
assert_eq!(sig_as_bytes.len(), BLS_SIG_BYTE_SIZE);
|
||||
for (i, one_byte) in sig_as_bytes.iter().enumerate() {
|
||||
if i == 0 {
|
||||
assert_eq!(*one_byte, u8::pow(2, 6) + u8::pow(2, 7));
|
||||
|
||||
Reference in New Issue
Block a user