diff --git a/Cargo.lock b/Cargo.lock index eefda513ca..eb164bef1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "amcl" version = "0.2.0" -source = "git+https://github.com/sigp/milagro_bls?tag=v1.0.1#2ccdd4b517c1ab3debe10277deed9d1b1cbbe9ce" +source = "git+https://github.com/sigp/milagro_bls?tag=v1.1.0#32c9f9382fc73f8976a00aca9773e6a322bb2c9e" dependencies = [ "hex 0.3.2", "lazy_static", @@ -1305,6 +1305,7 @@ dependencies = [ name = "eth2_key_derivation" version = "0.1.0" dependencies = [ + "bls", "hex 0.3.2", "num-bigint-dig", "ring", @@ -1317,6 +1318,7 @@ name = "eth2_keystore" version = "0.1.0" dependencies = [ "bls", + "eth2_key_derivation", "eth2_ssz", "hex 0.3.2", "rand 0.7.3", @@ -2743,8 +2745,8 @@ dependencies = [ [[package]] name = "milagro_bls" -version = "1.0.1" -source = "git+https://github.com/sigp/milagro_bls?tag=v1.0.1#2ccdd4b517c1ab3debe10277deed9d1b1cbbe9ce" +version = "1.1.0" +source = "git+https://github.com/sigp/milagro_bls?tag=v1.1.0#32c9f9382fc73f8976a00aca9773e6a322bb2c9e" dependencies = [ "amcl", "hex 0.4.2", diff --git a/common/eth2_interop_keypairs/Cargo.toml b/common/eth2_interop_keypairs/Cargo.toml index bc678f4e93..fb33be4eb0 100644 --- a/common/eth2_interop_keypairs/Cargo.toml +++ b/common/eth2_interop_keypairs/Cargo.toml @@ -11,7 +11,7 @@ lazy_static = "1.4.0" num-bigint = "0.2.6" eth2_hashing = "0.1.0" hex = "0.4.2" -milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.0.1" } +milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.1.0" } serde_yaml = "0.8.11" serde = "1.0.110" serde_derive = "1.0.110" diff --git a/common/eth2_interop_keypairs/tests/generation.rs b/common/eth2_interop_keypairs/tests/generation.rs index dfc6a9b410..02df8fe37e 100644 --- a/common/eth2_interop_keypairs/tests/generation.rs +++ b/common/eth2_interop_keypairs/tests/generation.rs @@ -53,6 +53,6 @@ fn reference_public_keys() { "Reference should be 48 bytes (public key size)" ); - assert_eq!(pair.pk.as_bytes(), reference); + assert_eq!(pair.pk.as_bytes().to_vec(), reference); }); } diff --git a/crypto/bls/Cargo.toml b/crypto/bls/Cargo.toml index 6c3d2a8f3e..ff894a7e08 100644 --- a/crypto/bls/Cargo.toml +++ b/crypto/bls/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Paul Hauner "] edition = "2018" [dependencies] -milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.0.1" } +milagro_bls = { git = "https://github.com/sigp/milagro_bls", tag = "v1.1.0" } eth2_hashing = "0.1.0" hex = "0.4.2" rand = "0.7.3" diff --git a/crypto/bls/src/aggregate_public_key.rs b/crypto/bls/src/aggregate_public_key.rs index 628ed86d16..9fa65e96c7 100644 --- a/crypto/bls/src/aggregate_public_key.rs +++ b/crypto/bls/src/aggregate_public_key.rs @@ -43,7 +43,7 @@ impl AggregatePublicKey { } /// Returns the underlying point as compressed bytes. - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE] { self.as_raw().as_bytes() } @@ -54,7 +54,7 @@ impl AggregatePublicKey { /// Return a hex string representation of this key's bytes. #[cfg(test)] pub fn as_hex_string(&self) -> String { - serde_hex::encode(self.as_bytes()) + serde_hex::encode(self.as_ssz_bytes()) } } @@ -71,7 +71,7 @@ impl Serialize for AggregatePublicKey { where S: Serializer, { - serializer.serialize_str(&hex_encode(self.as_bytes())) + serializer.serialize_str(&hex_encode(self.as_ssz_bytes())) } } diff --git a/crypto/bls/src/aggregate_signature.rs b/crypto/bls/src/aggregate_signature.rs index 176e61804f..3ad4fdddf2 100644 --- a/crypto/bls/src/aggregate_signature.rs +++ b/crypto/bls/src/aggregate_signature.rs @@ -1,5 +1,5 @@ use super::*; -use milagro_bls::{AggregateSignature as RawAggregateSignature, G2Point}; +use milagro_bls::AggregateSignature as RawAggregateSignature; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_hex::{encode as hex_encode, PrefixedHexVisitor}; @@ -84,9 +84,9 @@ impl AggregateSignature { } /// Return AggregateSignature as bytes - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_AGG_SIG_BYTE_SIZE] { if self.is_empty { - return vec![0; BLS_AGG_SIG_BYTE_SIZE]; + return [0; BLS_AGG_SIG_BYTE_SIZE]; } self.aggregate_signature.as_bytes() } @@ -116,14 +116,6 @@ impl AggregateSignature { &self.aggregate_signature } - /// Returns the underlying signature. - pub fn from_point(point: G2Point) -> Self { - Self { - aggregate_signature: RawAggregateSignature { point }, - is_empty: false, - } - } - /// Returns if the AggregateSignature `is_empty` pub fn is_empty(&self) -> bool { self.is_empty @@ -143,7 +135,7 @@ impl AggregateSignature { /// Return a hex string representation of the bytes of this signature. #[cfg(test)] pub fn as_hex_string(&self) -> String { - hex_encode(self.as_bytes()) + hex_encode(self.as_ssz_bytes()) } } @@ -161,7 +153,7 @@ impl Serialize for AggregateSignature { where S: Serializer, { - serializer.serialize_str(&hex_encode(self.as_bytes())) + serializer.serialize_str(&hex_encode(self.as_ssz_bytes())) } } diff --git a/crypto/bls/src/fake_aggregate_public_key.rs b/crypto/bls/src/fake_aggregate_public_key.rs index cabd6862c4..4c25f21568 100644 --- a/crypto/bls/src/fake_aggregate_public_key.rs +++ b/crypto/bls/src/fake_aggregate_public_key.rs @@ -1,20 +1,18 @@ use super::{PublicKey, BLS_PUBLIC_KEY_BYTE_SIZE}; use hex::encode as hex_encode; -use milagro_bls::G1Point; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_hex::PrefixedHexVisitor; use ssz::{ssz_encode, Decode, DecodeError, Encode}; +use std::fmt; /// A BLS aggregate public key. /// /// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ /// serialization). -#[derive(Debug, Clone, Default)] +#[derive(Clone)] pub struct FakeAggregatePublicKey { - bytes: Vec, - /// Never used, only use for compatibility with "real" `AggregatePublicKey`. - pub point: G1Point, + bytes: [u8; BLS_PUBLIC_KEY_BYTE_SIZE], } impl FakeAggregatePublicKey { @@ -24,8 +22,7 @@ impl FakeAggregatePublicKey { pub fn empty_signature() -> Self { Self { - bytes: vec![0; BLS_PUBLIC_KEY_BYTE_SIZE], - point: G1Point::new(), + bytes: [0; BLS_PUBLIC_KEY_BYTE_SIZE], } } @@ -36,10 +33,9 @@ impl FakeAggregatePublicKey { expected: BLS_PUBLIC_KEY_BYTE_SIZE, }) } else { - Ok(Self { - bytes: bytes.to_vec(), - point: G1Point::new(), - }) + let mut array = [0; BLS_PUBLIC_KEY_BYTE_SIZE]; + array.copy_from_slice(&bytes); + Ok(Self { bytes: array }) } } @@ -54,8 +50,7 @@ impl FakeAggregatePublicKey { /// Creates a new all-zero's aggregate public key pub fn zero() -> Self { Self { - bytes: vec![0; BLS_PUBLIC_KEY_BYTE_SIZE], - point: G1Point::new(), + bytes: [0; BLS_PUBLIC_KEY_BYTE_SIZE], } } @@ -63,10 +58,6 @@ impl FakeAggregatePublicKey { // No nothing. } - pub fn add_point(&mut self, _point: &G1Point) { - // No nothing. - } - pub fn aggregate(_pks: &[&PublicKey]) -> Self { Self::new() } @@ -74,7 +65,6 @@ impl FakeAggregatePublicKey { pub fn from_public_key(public_key: &PublicKey) -> Self { Self { bytes: public_key.as_bytes(), - point: public_key.point.clone(), } } @@ -86,7 +76,7 @@ impl FakeAggregatePublicKey { self } - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE] { self.bytes.clone() } } @@ -120,6 +110,18 @@ impl<'de> Deserialize<'de> for FakeAggregatePublicKey { } } +impl Default for FakeAggregatePublicKey { + fn default() -> Self { + Self::new() + } +} + +impl fmt::Debug for FakeAggregatePublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{:?}", self.bytes.to_vec())) + } +} + #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary for FakeAggregatePublicKey { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { diff --git a/crypto/bls/src/fake_aggregate_signature.rs b/crypto/bls/src/fake_aggregate_signature.rs index 3744f95792..2535cb13f5 100644 --- a/crypto/bls/src/fake_aggregate_signature.rs +++ b/crypto/bls/src/fake_aggregate_signature.rs @@ -2,21 +2,19 @@ use super::{ fake_aggregate_public_key::FakeAggregatePublicKey, fake_public_key::FakePublicKey, fake_signature::FakeSignature, BLS_AGG_SIG_BYTE_SIZE, }; -use milagro_bls::G2Point; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_hex::{encode as hex_encode, PrefixedHexVisitor}; use ssz::{ssz_encode, Decode, DecodeError, Encode}; +use std::fmt; /// 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)] +#[derive(Clone)] pub struct FakeAggregateSignature { - bytes: Vec, - /// Never used, only use for compatibility with "real" `AggregateSignature`. - pub point: G2Point, + bytes: [u8; BLS_AGG_SIG_BYTE_SIZE], } impl FakeAggregateSignature { @@ -28,8 +26,7 @@ impl FakeAggregateSignature { /// Creates a new all-zero's signature pub fn zero() -> Self { Self { - bytes: vec![0; BLS_AGG_SIG_BYTE_SIZE], - point: G2Point::new(), + bytes: [0; BLS_AGG_SIG_BYTE_SIZE], } } @@ -79,7 +76,13 @@ impl FakeAggregateSignature { pub fn from_signature(signature: &FakeSignature) -> Self { Self { bytes: signature.as_bytes(), - point: signature.point.clone(), + } + } + + /// Creates a new empty FakeAggregateSignature + pub fn empty_signature() -> Self { + Self { + bytes: [0u8; BLS_AGG_SIG_BYTE_SIZE], } } @@ -91,14 +94,13 @@ impl FakeAggregateSignature { expected: BLS_AGG_SIG_BYTE_SIZE, }) } else { - Ok(Self { - bytes: bytes.to_vec(), - point: G2Point::new(), - }) + let mut array = [0u8; BLS_AGG_SIG_BYTE_SIZE]; + array.copy_from_slice(bytes); + Ok(Self { bytes: array }) } } - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_AGG_SIG_BYTE_SIZE] { self.bytes.clone() } } @@ -132,6 +134,26 @@ impl<'de> Deserialize<'de> for FakeAggregateSignature { } } +impl fmt::Debug for FakeAggregateSignature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{:?}", self.bytes.to_vec())) + } +} + +impl PartialEq for FakeAggregateSignature { + fn eq(&self, other: &FakeAggregateSignature) -> bool { + ssz_encode(self) == ssz_encode(other) + } +} + +impl Eq for FakeAggregateSignature {} + +impl Default for FakeAggregateSignature { + fn default() -> Self { + Self::zero() + } +} + #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary for FakeAggregateSignature { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { diff --git a/crypto/bls/src/fake_public_key.rs b/crypto/bls/src/fake_public_key.rs index 32852b085c..02b59812fa 100644 --- a/crypto/bls/src/fake_public_key.rs +++ b/crypto/bls/src/fake_public_key.rs @@ -1,5 +1,4 @@ use super::{SecretKey, BLS_PUBLIC_KEY_BYTE_SIZE}; -use milagro_bls::G1Point; use milagro_bls::PublicKey as RawPublicKey; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; @@ -13,11 +12,9 @@ use std::hash::{Hash, Hasher}; /// /// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ /// serialization). -#[derive(Clone, Eq)] +#[derive(Clone)] pub struct FakePublicKey { - bytes: Vec, - /// Never used, only use for compatibility with "real" `PublicKey`. - pub point: G1Point, + bytes: [u8; BLS_PUBLIC_KEY_BYTE_SIZE], } impl FakePublicKey { @@ -28,39 +25,52 @@ impl FakePublicKey { pub fn from_raw(raw: RawPublicKey) -> Self { Self { bytes: raw.clone().as_bytes(), - point: G1Point::new(), } } /// Creates a new all-zero's public key pub fn zero() -> Self { Self { - bytes: vec![0; BLS_PUBLIC_KEY_BYTE_SIZE], - point: G1Point::new(), + bytes: [0; BLS_PUBLIC_KEY_BYTE_SIZE], } } /// Returns the underlying point as compressed bytes. - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE] { self.bytes.clone() } /// Converts compressed bytes to FakePublicKey pub fn from_bytes(bytes: &[u8]) -> Result { - Ok(Self { - bytes: bytes.to_vec(), - point: G1Point::new(), - }) + if bytes.len() != BLS_PUBLIC_KEY_BYTE_SIZE { + Err(DecodeError::InvalidByteLength { + len: bytes.len(), + expected: BLS_PUBLIC_KEY_BYTE_SIZE, + }) + } else { + let mut array = [0u8; BLS_PUBLIC_KEY_BYTE_SIZE]; + array.copy_from_slice(bytes); + Ok(Self { bytes: array }) + } } /// Returns the FakePublicKey as (x, y) bytes - pub fn as_uncompressed_bytes(&self) -> Vec { - self.as_bytes() + pub fn as_uncompressed_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE * 2] { + [0u8; BLS_PUBLIC_KEY_BYTE_SIZE * 2] } /// Converts (x, y) bytes to FakePublicKey pub fn from_uncompressed_bytes(bytes: &[u8]) -> Result { - Self::from_bytes(bytes) + if bytes.len() != BLS_PUBLIC_KEY_BYTE_SIZE * 2 { + Err(DecodeError::InvalidByteLength { + len: bytes.len(), + expected: BLS_PUBLIC_KEY_BYTE_SIZE * 2, + }) + } else { + let mut array = [0u8; BLS_PUBLIC_KEY_BYTE_SIZE]; + array.copy_from_slice(bytes); + Ok(Self { bytes: array }) + } } /// Returns the last 6 bytes of the SSZ encoding of the public key, as a hex string. @@ -83,14 +93,6 @@ impl FakePublicKey { pub fn as_raw(&self) -> &Self { self } - - pub fn as_point(&self) -> &G1Point { - &self.point - } - - pub fn into_point(self) -> G1Point { - self.point - } } impl fmt::Display for FakePublicKey { @@ -121,7 +123,7 @@ impl Serialize for FakePublicKey { where S: Serializer, { - serializer.serialize_str(&hex_encode(self.as_bytes())) + serializer.serialize_str(&hex_encode(self.as_ssz_bytes())) } } @@ -143,6 +145,8 @@ impl PartialEq for FakePublicKey { } } +impl Eq for FakePublicKey {} + impl Hash for FakePublicKey { /// Note: this is distinct from consensus serialization, it will produce a different hash. /// diff --git a/crypto/bls/src/fake_signature.rs b/crypto/bls/src/fake_signature.rs index df77a3d935..2fcb669011 100644 --- a/crypto/bls/src/fake_signature.rs +++ b/crypto/bls/src/fake_signature.rs @@ -1,21 +1,19 @@ use super::{PublicKey, SecretKey, BLS_SIG_BYTE_SIZE}; use hex::encode as hex_encode; -use milagro_bls::G2Point; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_hex::PrefixedHexVisitor; use ssz::{ssz_encode, Decode, DecodeError, Encode}; +use std::fmt; /// A single BLS signature. /// /// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ /// serialization). -#[derive(Debug, PartialEq, Clone, Eq)] +#[derive(Clone)] pub struct FakeSignature { - bytes: Vec, + bytes: [u8; BLS_SIG_BYTE_SIZE], is_empty: bool, - /// Never used, only use for compatibility with "real" `Signature`. - pub point: G2Point, } impl FakeSignature { @@ -27,9 +25,8 @@ impl FakeSignature { /// Creates a new all-zero's signature pub fn zero() -> Self { Self { - bytes: vec![0; BLS_SIG_BYTE_SIZE], + bytes: [0; BLS_SIG_BYTE_SIZE], is_empty: true, - point: G2Point::new(), } } @@ -66,15 +63,16 @@ impl FakeSignature { }) } else { let is_empty = bytes.iter().all(|x| *x == 0); + let mut array = [0u8; BLS_SIG_BYTE_SIZE]; + array.copy_from_slice(bytes); Ok(Self { - bytes: bytes.to_vec(), + bytes: array, is_empty, - point: G2Point::new(), }) } } - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_SIG_BYTE_SIZE] { self.bytes.clone() } @@ -93,6 +91,24 @@ impl_ssz!(FakeSignature, BLS_SIG_BYTE_SIZE, "FakeSignature"); impl_tree_hash!(FakeSignature, BLS_SIG_BYTE_SIZE); +impl fmt::Debug for FakeSignature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!( + "{:?}, {:?}", + self.bytes.to_vec(), + self.is_empty() + )) + } +} + +impl PartialEq for FakeSignature { + fn eq(&self, other: &FakeSignature) -> bool { + self.bytes.to_vec() == other.bytes.to_vec() + } +} + +impl Eq for FakeSignature {} + impl Serialize for FakeSignature { fn serialize(&self, serializer: S) -> Result where diff --git a/crypto/bls/src/lib.rs b/crypto/bls/src/lib.rs index 23cc6a6eaa..dff6403d16 100644 --- a/crypto/bls/src/lib.rs +++ b/crypto/bls/src/lib.rs @@ -4,8 +4,8 @@ extern crate ssz; #[macro_use] mod macros; mod keypair; -mod plain_text; mod public_key_bytes; +mod secret_hash; mod secret_key; mod signature_bytes; mod signature_set; @@ -14,8 +14,7 @@ pub use crate::keypair::Keypair; pub use crate::public_key_bytes::PublicKeyBytes; pub use crate::secret_key::SecretKey; pub use crate::signature_bytes::SignatureBytes; -pub use milagro_bls::{compress_g2, hash_to_curve_g2}; -pub use plain_text::PlainText; +pub use secret_hash::SecretHash; pub use signature_set::{verify_signature_sets, SignatureSet}; #[cfg(feature = "arbitrary")] diff --git a/crypto/bls/src/macros.rs b/crypto/bls/src/macros.rs index a7b1a99bab..8a2f386e51 100644 --- a/crypto/bls/src/macros.rs +++ b/crypto/bls/src/macros.rs @@ -14,7 +14,7 @@ macro_rules! impl_ssz { } fn ssz_append(&self, buf: &mut Vec) { - buf.append(&mut self.as_bytes()) + buf.extend_from_slice(&self.as_bytes()) } } diff --git a/crypto/bls/src/public_key.rs b/crypto/bls/src/public_key.rs index 98eaf467ac..c9b454c37f 100644 --- a/crypto/bls/src/public_key.rs +++ b/crypto/bls/src/public_key.rs @@ -1,5 +1,5 @@ use super::{SecretKey, BLS_PUBLIC_KEY_BYTE_SIZE}; -use milagro_bls::{G1Point, PublicKey as RawPublicKey}; +use milagro_bls::PublicKey as RawPublicKey; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_hex::{encode as hex_encode, PrefixedHexVisitor}; @@ -29,18 +29,8 @@ impl PublicKey { &self.0 } - /// Consumes self and returns the underlying signature. - pub fn as_point(&self) -> &G1Point { - &self.0.point - } - - /// Consumes self and returns the underlying signature. - pub fn into_point(self) -> G1Point { - self.0.point - } - /// Returns the underlying point as compressed bytes. - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE] { self.as_raw().as_bytes() } @@ -54,7 +44,7 @@ impl PublicKey { } /// Returns the PublicKey as (x, y) bytes - pub fn as_uncompressed_bytes(&self) -> Vec { + pub fn as_uncompressed_bytes(&self) -> [u8; BLS_PUBLIC_KEY_BYTE_SIZE * 2] { RawPublicKey::as_uncompressed_bytes(&mut self.0.clone()) } @@ -109,7 +99,7 @@ impl Serialize for PublicKey { where S: Serializer, { - serializer.serialize_str(&hex_encode(self.as_raw().as_bytes())) + serializer.serialize_str(&hex_encode(self.as_ssz_bytes())) } } diff --git a/crypto/eth2_key_derivation/src/secret_hash.rs b/crypto/bls/src/secret_hash.rs similarity index 56% rename from crypto/eth2_key_derivation/src/secret_hash.rs rename to crypto/bls/src/secret_hash.rs index 0d9cfac110..c1d92d00db 100644 --- a/crypto/eth2_key_derivation/src/secret_hash.rs +++ b/crypto/bls/src/secret_hash.rs @@ -1,15 +1,15 @@ -use crate::derived_key::HASH_SIZE; +use super::BLS_SECRET_KEY_BYTE_SIZE; use zeroize::Zeroize; /// Provides a wrapper around a `[u8; HASH_SIZE]` that implements `Zeroize` on `Drop`. #[derive(Zeroize)] #[zeroize(drop)] -pub struct SecretHash([u8; HASH_SIZE]); +pub struct SecretHash([u8; BLS_SECRET_KEY_BYTE_SIZE]); impl SecretHash { /// Instantiates `Self` with all zeros. pub fn zero() -> Self { - Self([0; HASH_SIZE]) + Self([0; BLS_SECRET_KEY_BYTE_SIZE]) } /// Returns a reference to the underlying bytes. @@ -22,3 +22,15 @@ impl SecretHash { &mut self.0 } } + +impl From<[u8; BLS_SECRET_KEY_BYTE_SIZE]> for SecretHash { + fn from(array: [u8; BLS_SECRET_KEY_BYTE_SIZE]) -> Self { + Self(array) + } +} + +impl AsRef<[u8]> for SecretHash { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} diff --git a/crypto/bls/src/secret_key.rs b/crypto/bls/src/secret_key.rs index 3cb0cd8b08..3d03805ea1 100644 --- a/crypto/bls/src/secret_key.rs +++ b/crypto/bls/src/secret_key.rs @@ -1,6 +1,6 @@ extern crate rand; -use crate::PlainText; +use crate::SecretHash; use milagro_bls::SecretKey as RawSecretKey; use ssz::DecodeError; @@ -21,12 +21,12 @@ impl SecretKey { Self(raw) } - /// Returns the secret key as a byte array (wrapped in `PlainText` wrapper so it is zeroized on + /// Returns the secret key as a byte array (wrapped in `SecretHash` wrapper so it is zeroized on /// `Drop`). /// /// Extreme care should be taken not to leak these bytes as they are the unencrypted secret /// key. - pub fn as_bytes(&self) -> PlainText { + pub fn as_bytes(&self) -> SecretHash { self.as_raw().as_bytes().into() } @@ -63,6 +63,6 @@ mod tests { let bytes = original.as_bytes(); let decoded = SecretKey::from_bytes(bytes.as_ref()).unwrap(); - assert!(original.as_bytes() == decoded.as_bytes()); + assert!(original.as_bytes().as_ref().to_vec() == decoded.as_bytes().as_ref().to_vec()); } } diff --git a/crypto/bls/src/signature.rs b/crypto/bls/src/signature.rs index 73de59bf9a..5a2bea773a 100644 --- a/crypto/bls/src/signature.rs +++ b/crypto/bls/src/signature.rs @@ -40,7 +40,7 @@ impl Signature { /// Returns a new empty signature. pub fn empty_signature() -> Self { // Set RawSignature = infinity - let mut empty: Vec = vec![0; BLS_SIG_BYTE_SIZE]; + let mut empty = [0u8; BLS_SIG_BYTE_SIZE]; empty[0] += u8::pow(2, 6) + u8::pow(2, 7); Signature { signature: RawSignature::from_bytes(&empty).unwrap(), @@ -49,9 +49,9 @@ impl Signature { } // Converts a BLS Signature to bytes - pub fn as_bytes(&self) -> Vec { + pub fn as_bytes(&self) -> [u8; BLS_SIG_BYTE_SIZE] { if self.is_empty { - return vec![0; 96]; + return [0u8; BLS_SIG_BYTE_SIZE]; } self.signature.as_bytes() } @@ -80,7 +80,7 @@ impl Signature { /// Display a signature as a hex string of its bytes. #[cfg(test)] pub fn as_hex_string(&self) -> String { - hex_encode(self.as_bytes()) + hex_encode(self.as_ssz_bytes()) } } @@ -148,10 +148,10 @@ mod tests { } #[test] - pub fn test_empty_signature() { + pub fn test_infinity_signature() { let sig = Signature::empty_signature(); - let sig_as_bytes: Vec = sig.as_raw().as_bytes(); + let sig_as_bytes = sig.as_raw().as_bytes(); assert_eq!(sig_as_bytes.len(), BLS_SIG_BYTE_SIZE); for (i, one_byte) in sig_as_bytes.iter().enumerate() { @@ -162,4 +162,13 @@ mod tests { } } } + + #[test] + pub fn test_empty_signature() { + let sig = Signature::empty_signature(); + + let sig_as_bytes = sig.as_bytes().to_vec(); + + assert_eq!(sig_as_bytes, vec![0u8; BLS_SIG_BYTE_SIZE]); + } } diff --git a/crypto/eth2_key_derivation/Cargo.toml b/crypto/eth2_key_derivation/Cargo.toml index b912c58a10..c0607fff91 100644 --- a/crypto/eth2_key_derivation/Cargo.toml +++ b/crypto/eth2_key_derivation/Cargo.toml @@ -11,6 +11,7 @@ rust-crypto = "0.2.36" zeroize = { version = "1.0.0", features = ["zeroize_derive"] } num-bigint-dig = { version = "0.6.0", features = ["zeroize"] } ring = "0.16.9" +bls = { path = "../bls" } [dev-dependencies] hex = "0.3" diff --git a/crypto/eth2_key_derivation/src/derived_key.rs b/crypto/eth2_key_derivation/src/derived_key.rs index a8a0cf7df1..ecc31e64b4 100644 --- a/crypto/eth2_key_derivation/src/derived_key.rs +++ b/crypto/eth2_key_derivation/src/derived_key.rs @@ -1,6 +1,4 @@ -use crate::{ - lamport_secret_key::LamportSecretKey, secret_bytes::SecretBytes, secret_hash::SecretHash, -}; +use crate::{lamport_secret_key::LamportSecretKey, secret_bytes::SecretBytes, SecretHash}; use crypto::{digest::Digest, sha2::Sha256}; use num_bigint_dig::BigUint; use ring::hkdf::{KeyType, Prk, Salt, HKDF_SHA256}; diff --git a/crypto/eth2_key_derivation/src/lib.rs b/crypto/eth2_key_derivation/src/lib.rs index f6ed44c4df..763f8fe04c 100644 --- a/crypto/eth2_key_derivation/src/lib.rs +++ b/crypto/eth2_key_derivation/src/lib.rs @@ -3,7 +3,9 @@ mod derived_key; mod lamport_secret_key; +mod plain_text; mod secret_bytes; -mod secret_hash; +pub use bls::SecretHash; pub use derived_key::DerivedKey; +pub use plain_text::PlainText; diff --git a/crypto/bls/src/plain_text.rs b/crypto/eth2_key_derivation/src/plain_text.rs similarity index 100% rename from crypto/bls/src/plain_text.rs rename to crypto/eth2_key_derivation/src/plain_text.rs diff --git a/crypto/eth2_keystore/Cargo.toml b/crypto/eth2_keystore/Cargo.toml index 89123379ef..43573961be 100644 --- a/crypto/eth2_keystore/Cargo.toml +++ b/crypto/eth2_keystore/Cargo.toml @@ -17,6 +17,6 @@ hex = "0.3" bls = { path = "../bls" } eth2_ssz = { path = "../../consensus/ssz" } serde_json = "1.0.41" - +eth2_key_derivation = { path = "../eth2_key_derivation" } [dev-dependencies] tempfile = "3.1.0" diff --git a/crypto/eth2_keystore/src/keystore.rs b/crypto/eth2_keystore/src/keystore.rs index 04c0655a65..8d68265a7d 100644 --- a/crypto/eth2_keystore/src/keystore.rs +++ b/crypto/eth2_keystore/src/keystore.rs @@ -6,10 +6,10 @@ use crate::json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, EmptyMap, EmptyString, JsonKeystore, Kdf, KdfModule, Scrypt, Sha256Checksum, Version, }; -use crate::PlainText; use crate::Uuid; -use bls::{Keypair, PublicKey, SecretKey}; +use bls::{Keypair, PublicKey, SecretHash, SecretKey}; use crypto::{digest::Digest, sha2::Sha256}; +use eth2_key_derivation::PlainText; use rand::prelude::*; use serde::{Deserialize, Serialize}; use ssz::DecodeError; @@ -136,7 +136,7 @@ impl Keystore { uuid: Uuid, path: String, ) -> Result { - let secret: PlainText = keypair.sk.as_bytes(); + let secret: SecretHash = keypair.sk.as_bytes(); let (cipher_text, checksum) = encrypt(secret.as_bytes(), password, &kdf, &cipher)?; diff --git a/crypto/eth2_keystore/src/lib.rs b/crypto/eth2_keystore/src/lib.rs index 93dbabe5de..385b1950b6 100644 --- a/crypto/eth2_keystore/src/lib.rs +++ b/crypto/eth2_keystore/src/lib.rs @@ -6,7 +6,8 @@ mod keystore; pub mod json_keystore; -pub use bls::PlainText; +pub use bls::SecretHash; +pub use eth2_key_derivation::PlainText; pub use keystore::{ decrypt, default_kdf, encrypt, keypair_from_secret, Error, Keystore, KeystoreBuilder, DKLEN, HASH_SIZE, IV_SIZE, SALT_SIZE, diff --git a/lighthouse/tests/account_manager.rs b/lighthouse/tests/account_manager.rs index 31a02786d4..b8daa2b726 100644 --- a/lighthouse/tests/account_manager.rs +++ b/lighthouse/tests/account_manager.rs @@ -369,7 +369,7 @@ fn validator_create() { fn write_legacy_keypair>(name: &str, dir: P) -> Keypair { let keypair = Keypair::random(); - let mut keypair_bytes = keypair.pk.as_bytes(); + let mut keypair_bytes = keypair.pk.as_bytes().to_vec(); keypair_bytes.extend_from_slice(keypair.sk.as_bytes().as_ref()); fs::write(dir.as_ref().join(name), &keypair_bytes).unwrap(); diff --git a/testing/ef_tests/src/cases/bls_aggregate_sigs.rs b/testing/ef_tests/src/cases/bls_aggregate_sigs.rs index 22fa197df6..561c7bc643 100644 --- a/testing/ef_tests/src/cases/bls_aggregate_sigs.rs +++ b/testing/ef_tests/src/cases/bls_aggregate_sigs.rs @@ -29,7 +29,7 @@ impl Case for BlsAggregateSigs { hex::decode(&self.output[2..]) .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?, ); - let aggregate_signature = Ok(aggregate_signature.as_bytes()); + let aggregate_signature = Ok(aggregate_signature.as_bytes().to_vec()); compare_result::, Vec>(&aggregate_signature, &output_bytes) } diff --git a/testing/ef_tests/src/cases/bls_sign_msg.rs b/testing/ef_tests/src/cases/bls_sign_msg.rs index b985a2d399..2662746995 100644 --- a/testing/ef_tests/src/cases/bls_sign_msg.rs +++ b/testing/ef_tests/src/cases/bls_sign_msg.rs @@ -33,6 +33,6 @@ impl Case for BlsSign { let decoded = hex::decode(&self.output[2..]) .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; - compare_result::, Vec>(&Ok(signature.as_bytes()), &Some(decoded)) + compare_result::, Vec>(&Ok(signature.as_bytes().to_vec()), &Some(decoded)) } }