Update milagro_bls to new release (#1183)

* Update milagro_bls to new release

Signed-off-by: Kirk Baird <baird.k@outlook.com>

* Tidy up fake cryptos

Signed-off-by: Kirk Baird <baird.k@outlook.com>

* move SecretHash to bls and put plaintext back

Signed-off-by: Kirk Baird <baird.k@outlook.com>
This commit is contained in:
Kirk Baird
2020-05-29 14:39:33 +10:00
committed by GitHub
parent 08e6b4961d
commit dceab5e6ea
26 changed files with 182 additions and 132 deletions

View File

@@ -43,7 +43,7 @@ impl AggregatePublicKey {
}
/// Returns the underlying point as compressed bytes.
pub fn as_bytes(&self) -> Vec<u8> {
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()))
}
}

View File

@@ -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<u8> {
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()))
}
}

View File

@@ -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<u8>,
/// 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<u8> {
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<Self> {

View File

@@ -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<u8>,
/// 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<u8> {
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<Self> {

View File

@@ -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<u8>,
/// 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<u8> {
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<Self, DecodeError> {
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<u8> {
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, DecodeError> {
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.
///

View File

@@ -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<u8>,
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<u8> {
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where

View File

@@ -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")]

View File

@@ -14,7 +14,7 @@ macro_rules! impl_ssz {
}
fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.append(&mut self.as_bytes())
buf.extend_from_slice(&self.as_bytes())
}
}

View File

@@ -1,40 +0,0 @@
use zeroize::Zeroize;
/// Provides wrapper around `Vec<u8>` that implements `Zeroize`.
#[derive(Zeroize, Clone, PartialEq)]
#[zeroize(drop)]
pub struct PlainText(Vec<u8>);
impl PlainText {
/// Instantiate self with `len` zeros.
pub fn zero(len: usize) -> Self {
Self(vec![0; len])
}
/// The byte-length of `self`
pub fn len(&self) -> usize {
self.0.len()
}
/// Returns a reference to the underlying bytes.
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
/// Returns a mutable reference to the underlying bytes.
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl From<Vec<u8>> for PlainText {
fn from(vec: Vec<u8>) -> Self {
Self(vec)
}
}
impl AsRef<[u8]> for PlainText {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

View File

@@ -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<u8> {
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<u8> {
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()))
}
}

View File

@@ -0,0 +1,36 @@
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; BLS_SECRET_KEY_BYTE_SIZE]);
impl SecretHash {
/// Instantiates `Self` with all zeros.
pub fn zero() -> Self {
Self([0; BLS_SECRET_KEY_BYTE_SIZE])
}
/// Returns a reference to the underlying bytes.
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
/// Returns a mutable reference to the underlying bytes.
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
&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
}
}

View File

@@ -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());
}
}

View File

@@ -40,7 +40,7 @@ impl Signature {
/// Returns a new empty signature.
pub fn empty_signature() -> Self {
// Set RawSignature = infinity
let mut empty: Vec<u8> = 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<u8> {
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<u8> = 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]);
}
}