Upgrade BLS to new SSZ
This commit is contained in:
parent
ebbeb03349
commit
5550d14d62
@ -1,4 +1,4 @@
|
||||
use super::{AggregatePublicKey, Signature, BLS_AGG_SIG_BYTE_SIZE};
|
||||
use super::*;
|
||||
use bls_aggregates::{
|
||||
AggregatePublicKey as RawAggregatePublicKey, AggregateSignature as RawAggregateSignature,
|
||||
};
|
||||
@ -6,7 +6,7 @@ use cached_tree_hash::cached_tree_hash_ssz_encoding_as_vector;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_hex::{encode as hex_encode, HexVisitor};
|
||||
use ssz::{decode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use ssz::{Decodable, DecodeError};
|
||||
use tree_hash::tree_hash_ssz_encoding_as_vector;
|
||||
|
||||
/// A BLS aggregate signature.
|
||||
@ -99,8 +99,12 @@ impl AggregateSignature {
|
||||
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)?;
|
||||
let sig = RawAggregateSignature::from_bytes(&bytes).map_err(|_| {
|
||||
DecodeError::BytesInvalid(
|
||||
format!("Invalid AggregateSignature bytes: {:?}", bytes).to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
return Ok(Self {
|
||||
aggregate_signature: sig,
|
||||
is_empty: false,
|
||||
@ -127,22 +131,11 @@ impl AggregateSignature {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for AggregateSignature {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for AggregateSignature {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_AGG_SIG_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
let agg_sig = AggregateSignature::from_bytes(&bytes[i..(i + BLS_AGG_SIG_BYTE_SIZE)])
|
||||
.map_err(|_| DecodeError::Invalid)?;
|
||||
Ok((agg_sig, i + BLS_AGG_SIG_BYTE_SIZE))
|
||||
}
|
||||
}
|
||||
impl_ssz!(
|
||||
AggregateSignature,
|
||||
BLS_AGG_SIG_BYTE_SIZE,
|
||||
"AggregateSignature"
|
||||
);
|
||||
|
||||
impl Serialize for AggregateSignature {
|
||||
/// Serde serialization is compliant the Ethereum YAML test format.
|
||||
@ -161,8 +154,9 @@ impl<'de> Deserialize<'de> for AggregateSignature {
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||
let agg_sig = decode(&bytes[..])
|
||||
let agg_sig = AggregateSignature::from_ssz_bytes(&bytes)
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||
|
||||
Ok(agg_sig)
|
||||
}
|
||||
}
|
||||
@ -174,7 +168,7 @@ cached_tree_hash_ssz_encoding_as_vector!(AggregateSignature, 96);
|
||||
mod tests {
|
||||
use super::super::{Keypair, Signature};
|
||||
use super::*;
|
||||
use ssz::{decode, ssz_encode};
|
||||
use ssz::Encodable;
|
||||
|
||||
#[test]
|
||||
pub fn test_ssz_round_trip() {
|
||||
@ -183,8 +177,8 @@ mod tests {
|
||||
let mut original = AggregateSignature::new();
|
||||
original.add(&Signature::new(&[42, 42], 0, &keypair.sk));
|
||||
|
||||
let bytes = ssz_encode(&original);
|
||||
let decoded = decode::<AggregateSignature>(&bytes).unwrap();
|
||||
let bytes = original.as_ssz_bytes();
|
||||
let decoded = AggregateSignature::from_ssz_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
|
@ -59,25 +59,11 @@ impl FakeAggregateSignature {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FakeAggregateSignature {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for FakeAggregateSignature {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_AGG_SIG_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
Ok((
|
||||
FakeAggregateSignature {
|
||||
bytes: bytes[i..(i + BLS_AGG_SIG_BYTE_SIZE)].to_vec(),
|
||||
},
|
||||
i + BLS_AGG_SIG_BYTE_SIZE,
|
||||
))
|
||||
}
|
||||
}
|
||||
impl_ssz!(
|
||||
FakeAggregateSignature,
|
||||
BLS_AGG_SIG_BYTE_SIZE,
|
||||
"FakeAggregateSignature"
|
||||
);
|
||||
|
||||
impl Serialize for FakeAggregateSignature {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
@ -55,25 +55,7 @@ impl FakeSignature {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for FakeSignature {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for FakeSignature {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_SIG_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
Ok((
|
||||
FakeSignature {
|
||||
bytes: bytes[i..(i + BLS_SIG_BYTE_SIZE)].to_vec(),
|
||||
},
|
||||
i + BLS_SIG_BYTE_SIZE,
|
||||
))
|
||||
}
|
||||
}
|
||||
impl_ssz!(FakeSignature, BLS_SIG_BYTE_SIZE, "FakeSignature");
|
||||
|
||||
tree_hash_ssz_encoding_as_vector!(FakeSignature);
|
||||
cached_tree_hash_ssz_encoding_as_vector!(FakeSignature, 96);
|
||||
|
@ -1,6 +1,8 @@
|
||||
extern crate bls_aggregates;
|
||||
extern crate ssz;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod aggregate_public_key;
|
||||
mod keypair;
|
||||
mod public_key;
|
||||
|
38
eth2/utils/bls/src/macros.rs
Normal file
38
eth2/utils/bls/src/macros.rs
Normal file
@ -0,0 +1,38 @@
|
||||
macro_rules! impl_ssz {
|
||||
($type: ident, $byte_size: expr, $item_str: expr) => {
|
||||
impl ssz::Encodable for $type {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
$byte_size
|
||||
}
|
||||
|
||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||
buf.append(&mut self.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz::Decodable for $type {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
$byte_size
|
||||
}
|
||||
|
||||
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
let len = bytes.len();
|
||||
let expected = <Self as ssz::Decodable>::ssz_fixed_len();
|
||||
|
||||
if len != expected {
|
||||
Err(ssz::DecodeError::InvalidByteLength { len, expected })
|
||||
} else {
|
||||
$type::from_bytes(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -4,7 +4,7 @@ use cached_tree_hash::cached_tree_hash_ssz_encoding_as_vector;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_hex::{encode as hex_encode, HexVisitor};
|
||||
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use ssz::{ssz_encode, Decodable, DecodeError};
|
||||
use std::default;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
@ -27,9 +27,19 @@ impl PublicKey {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Returns the underlying point as compressed bytes.
|
||||
///
|
||||
/// Identical to `self.as_uncompressed_bytes()`.
|
||||
fn as_bytes(&self) -> Vec<u8> {
|
||||
self.as_raw().as_bytes()
|
||||
}
|
||||
|
||||
/// Converts compressed bytes to PublicKey
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
let pubkey = RawPublicKey::from_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
|
||||
let pubkey = RawPublicKey::from_bytes(&bytes).map_err(|_| {
|
||||
DecodeError::BytesInvalid(format!("Invalid PublicKey bytes: {:?}", bytes).to_string())
|
||||
})?;
|
||||
|
||||
Ok(PublicKey(pubkey))
|
||||
}
|
||||
|
||||
@ -40,8 +50,9 @@ impl PublicKey {
|
||||
|
||||
/// Converts (x, y) bytes to PublicKey
|
||||
pub fn from_uncompressed_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
let pubkey =
|
||||
RawPublicKey::from_uncompressed_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
|
||||
let pubkey = RawPublicKey::from_uncompressed_bytes(&bytes).map_err(|_| {
|
||||
DecodeError::BytesInvalid("Invalid PublicKey uncompressed bytes.".to_string())
|
||||
})?;
|
||||
Ok(PublicKey(pubkey))
|
||||
}
|
||||
|
||||
@ -68,22 +79,7 @@ impl default::Default for PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for PublicKey {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.0.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PublicKey {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_PUBLIC_KEY_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
let raw_sig = RawPublicKey::from_bytes(&bytes[i..(i + BLS_PUBLIC_KEY_BYTE_SIZE)])
|
||||
.map_err(|_| DecodeError::TooShort)?;
|
||||
Ok((PublicKey(raw_sig), i + BLS_PUBLIC_KEY_BYTE_SIZE))
|
||||
}
|
||||
}
|
||||
impl_ssz!(PublicKey, BLS_PUBLIC_KEY_BYTE_SIZE, "PublicKey");
|
||||
|
||||
impl Serialize for PublicKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@ -100,7 +96,7 @@ impl<'de> Deserialize<'de> for PublicKey {
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||
let pubkey = decode(&bytes[..])
|
||||
let pubkey = Self::from_ssz_bytes(&bytes[..])
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid pubkey ({:?})", e)))?;
|
||||
Ok(pubkey)
|
||||
}
|
||||
@ -139,7 +135,7 @@ mod tests {
|
||||
let original = PublicKey::from_secret_key(&sk);
|
||||
|
||||
let bytes = ssz_encode(&original);
|
||||
let (decoded, _) = PublicKey::ssz_decode(&bytes, 0).unwrap();
|
||||
let decoded = PublicKey::from_ssz_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use super::BLS_SECRET_KEY_BYTE_SIZE;
|
||||
use bls_aggregates::{DecodeError as BlsDecodeError, SecretKey as RawSecretKey};
|
||||
use bls_aggregates::SecretKey as RawSecretKey;
|
||||
use hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_hex::HexVisitor;
|
||||
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use ssz::{ssz_encode, Decodable, DecodeError};
|
||||
use tree_hash::tree_hash_ssz_encoding_as_vector;
|
||||
|
||||
/// A single BLS signature.
|
||||
@ -19,11 +19,21 @@ impl SecretKey {
|
||||
SecretKey(RawSecretKey::random())
|
||||
}
|
||||
|
||||
/// Returns the underlying point as compressed bytes.
|
||||
fn as_bytes(&self) -> Vec<u8> {
|
||||
self.as_raw().as_bytes()
|
||||
}
|
||||
|
||||
/// Instantiate a SecretKey from existing bytes.
|
||||
///
|
||||
/// Note: this is _not_ SSZ decoding.
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<SecretKey, BlsDecodeError> {
|
||||
Ok(SecretKey(RawSecretKey::from_bytes(bytes)?))
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<SecretKey, DecodeError> {
|
||||
Ok(SecretKey(RawSecretKey::from_bytes(bytes).map_err(|e| {
|
||||
DecodeError::BytesInvalid(format!(
|
||||
"Invalid SecretKey bytes: {:?} Error: {:?}",
|
||||
bytes, e
|
||||
))
|
||||
})?))
|
||||
}
|
||||
|
||||
/// Returns the underlying secret key.
|
||||
@ -32,22 +42,7 @@ impl SecretKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for SecretKey {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.0.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for SecretKey {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_SECRET_KEY_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
let raw_sig = RawSecretKey::from_bytes(&bytes[i..(i + BLS_SECRET_KEY_BYTE_SIZE)])
|
||||
.map_err(|_| DecodeError::TooShort)?;
|
||||
Ok((SecretKey(raw_sig), i + BLS_SECRET_KEY_BYTE_SIZE))
|
||||
}
|
||||
}
|
||||
impl_ssz!(SecretKey, BLS_SECRET_KEY_BYTE_SIZE, "SecretKey");
|
||||
|
||||
impl Serialize for SecretKey {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@ -64,7 +59,7 @@ impl<'de> Deserialize<'de> for SecretKey {
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||
let secret_key = decode::<SecretKey>(&bytes[..])
|
||||
let secret_key = SecretKey::from_ssz_bytes(&bytes[..])
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||
Ok(secret_key)
|
||||
}
|
||||
@ -84,7 +79,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let bytes = ssz_encode(&original);
|
||||
let (decoded, _) = SecretKey::ssz_decode(&bytes, 0).unwrap();
|
||||
let decoded = SecretKey::from_ssz_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use hex::encode as hex_encode;
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde_hex::HexVisitor;
|
||||
use ssz::{decode, ssz_encode, Decodable, DecodeError, Encodable, SszStream};
|
||||
use ssz::{ssz_encode, Decodable, DecodeError};
|
||||
use tree_hash::tree_hash_ssz_encoding_as_vector;
|
||||
|
||||
/// A single BLS signature.
|
||||
@ -83,8 +83,11 @@ impl Signature {
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
for byte in bytes {
|
||||
if *byte != 0 {
|
||||
let raw_signature =
|
||||
RawSignature::from_bytes(&bytes).map_err(|_| DecodeError::Invalid)?;
|
||||
let raw_signature = RawSignature::from_bytes(&bytes).map_err(|_| {
|
||||
DecodeError::BytesInvalid(
|
||||
format!("Invalid Signature bytes: {:?}", bytes).to_string(),
|
||||
)
|
||||
})?;
|
||||
return Ok(Signature {
|
||||
signature: raw_signature,
|
||||
is_empty: false,
|
||||
@ -100,21 +103,7 @@ impl Signature {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Signature {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_encoded_raw(&self.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for Signature {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
if bytes.len() - i < BLS_SIG_BYTE_SIZE {
|
||||
return Err(DecodeError::TooShort);
|
||||
}
|
||||
let signature = Signature::from_bytes(&bytes[i..(i + BLS_SIG_BYTE_SIZE)])?;
|
||||
Ok((signature, i + BLS_SIG_BYTE_SIZE))
|
||||
}
|
||||
}
|
||||
impl_ssz!(Signature, BLS_SIG_BYTE_SIZE, "Signature");
|
||||
|
||||
tree_hash_ssz_encoding_as_vector!(Signature);
|
||||
cached_tree_hash_ssz_encoding_as_vector!(Signature, 96);
|
||||
@ -136,7 +125,7 @@ impl<'de> Deserialize<'de> for Signature {
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let bytes = deserializer.deserialize_str(HexVisitor)?;
|
||||
let signature = decode(&bytes[..])
|
||||
let signature = Self::from_ssz_bytes(&bytes[..])
|
||||
.map_err(|e| serde::de::Error::custom(format!("invalid ssz ({:?})", e)))?;
|
||||
Ok(signature)
|
||||
}
|
||||
@ -156,7 +145,7 @@ mod tests {
|
||||
let original = Signature::new(&[42, 42], 0, &keypair.sk);
|
||||
|
||||
let bytes = ssz_encode(&original);
|
||||
let decoded = decode::<Signature>(&bytes).unwrap();
|
||||
let decoded = Signature::from_ssz_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user