mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
Expose blst internals (#6829)
This commit is contained in:
@@ -61,6 +61,11 @@ where
|
|||||||
GenericPublicKey::from_point(self.point.public_key())
|
GenericPublicKey::from_point(self.point.public_key())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the underlying BLS point.
|
||||||
|
pub fn point(&self) -> &Sec {
|
||||||
|
&self.point
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize `self` as compressed bytes.
|
/// Serialize `self` as compressed bytes.
|
||||||
///
|
///
|
||||||
/// ## Note
|
/// ## Note
|
||||||
@@ -89,3 +94,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Sig, Pub, Sec> GenericSecretKey<Sig, Pub, Sec>
|
||||||
|
where
|
||||||
|
Sig: TSignature<Pub>,
|
||||||
|
Pub: TPublicKey,
|
||||||
|
Sec: TSecretKey<Sig, Pub> + Clone,
|
||||||
|
{
|
||||||
|
/// Instantiates `Self` from a `point`.
|
||||||
|
/// Takes a reference, as moves might accidentally leave behind key material
|
||||||
|
pub fn from_point(point: &Sec) -> Self {
|
||||||
|
Self {
|
||||||
|
point: point.clone(),
|
||||||
|
_phantom_signature: PhantomData,
|
||||||
|
_phantom_public_key: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ use tree_hash::TreeHash;
|
|||||||
/// The byte-length of a BLS signature when serialized in compressed form.
|
/// The byte-length of a BLS signature when serialized in compressed form.
|
||||||
pub const SIGNATURE_BYTES_LEN: usize = 96;
|
pub const SIGNATURE_BYTES_LEN: usize = 96;
|
||||||
|
|
||||||
|
/// The byte-length of a BLS signature when serialized in uncompressed form.
|
||||||
|
pub const SIGNATURE_UNCOMPRESSED_BYTES_LEN: usize = 192;
|
||||||
|
|
||||||
/// Represents the signature at infinity.
|
/// Represents the signature at infinity.
|
||||||
pub const INFINITY_SIGNATURE: [u8; SIGNATURE_BYTES_LEN] = [
|
pub const INFINITY_SIGNATURE: [u8; SIGNATURE_BYTES_LEN] = [
|
||||||
0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@@ -22,6 +25,16 @@ pub const INFINITY_SIGNATURE: [u8; SIGNATURE_BYTES_LEN] = [
|
|||||||
0,
|
0,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const INFINITY_SIGNATURE_UNCOMPRESSED: [u8; SIGNATURE_UNCOMPRESSED_BYTES_LEN] = [
|
||||||
|
0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0,
|
||||||
|
];
|
||||||
|
|
||||||
/// The compressed bytes used to represent `GenericSignature::empty()`.
|
/// The compressed bytes used to represent `GenericSignature::empty()`.
|
||||||
pub const NONE_SIGNATURE: [u8; SIGNATURE_BYTES_LEN] = [0; SIGNATURE_BYTES_LEN];
|
pub const NONE_SIGNATURE: [u8; SIGNATURE_BYTES_LEN] = [0; SIGNATURE_BYTES_LEN];
|
||||||
|
|
||||||
@@ -31,9 +44,15 @@ pub trait TSignature<GenericPublicKey>: Sized + Clone {
|
|||||||
/// Serialize `self` as compressed bytes.
|
/// Serialize `self` as compressed bytes.
|
||||||
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN];
|
fn serialize(&self) -> [u8; SIGNATURE_BYTES_LEN];
|
||||||
|
|
||||||
|
/// Serialize `self` as uncompressed bytes.
|
||||||
|
fn serialize_uncompressed(&self) -> [u8; SIGNATURE_UNCOMPRESSED_BYTES_LEN];
|
||||||
|
|
||||||
/// Deserialize `self` from compressed bytes.
|
/// Deserialize `self` from compressed bytes.
|
||||||
fn deserialize(bytes: &[u8]) -> Result<Self, Error>;
|
fn deserialize(bytes: &[u8]) -> Result<Self, Error>;
|
||||||
|
|
||||||
|
/// Serialize `self` from uncompressed bytes.
|
||||||
|
fn deserialize_uncompressed(bytes: &[u8]) -> Result<Self, Error>;
|
||||||
|
|
||||||
/// Returns `true` if `self` is a signature across `msg` by `pubkey`.
|
/// Returns `true` if `self` is a signature across `msg` by `pubkey`.
|
||||||
fn verify(&self, pubkey: &GenericPublicKey, msg: Hash256) -> bool;
|
fn verify(&self, pubkey: &GenericPublicKey, msg: Hash256) -> bool;
|
||||||
}
|
}
|
||||||
@@ -93,12 +112,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the underlying BLS point.
|
/// Returns a reference to the underlying BLS point.
|
||||||
pub(crate) fn point(&self) -> Option<&Sig> {
|
pub fn point(&self) -> Option<&Sig> {
|
||||||
self.point.as_ref()
|
self.point.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiates `Self` from a `point`.
|
/// Instantiates `Self` from a `point`.
|
||||||
pub(crate) fn from_point(point: Sig, is_infinity: bool) -> Self {
|
pub fn from_point(point: Sig, is_infinity: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
point: Some(point),
|
point: Some(point),
|
||||||
is_infinity,
|
is_infinity,
|
||||||
@@ -115,6 +134,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serialize `self` as compressed bytes.
|
||||||
|
pub fn serialize_uncompressed(&self) -> Option<[u8; SIGNATURE_UNCOMPRESSED_BYTES_LEN]> {
|
||||||
|
self.point
|
||||||
|
.as_ref()
|
||||||
|
.map(|point| point.serialize_uncompressed())
|
||||||
|
}
|
||||||
|
|
||||||
/// Deserialize `self` from compressed bytes.
|
/// Deserialize `self` from compressed bytes.
|
||||||
pub fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
pub fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
let point = if bytes == &NONE_SIGNATURE[..] {
|
let point = if bytes == &NONE_SIGNATURE[..] {
|
||||||
@@ -129,6 +155,17 @@ where
|
|||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize `self` from uncompressed bytes.
|
||||||
|
pub fn deserialize_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
// The "none signature" is a beacon chain concept. As we never directly deal with
|
||||||
|
// uncompressed signatures on the beacon chain, it does not apply here.
|
||||||
|
Ok(Self {
|
||||||
|
point: Some(Sig::deserialize_uncompressed(bytes)?),
|
||||||
|
is_infinity: bytes == &INFINITY_SIGNATURE_UNCOMPRESSED[..],
|
||||||
|
_phantom: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Pub, Sig> GenericSignature<Pub, Sig>
|
impl<Pub, Sig> GenericSignature<Pub, Sig>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::{
|
|||||||
GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
||||||
},
|
},
|
||||||
generic_secret_key::TSecretKey,
|
generic_secret_key::TSecretKey,
|
||||||
generic_signature::{TSignature, SIGNATURE_BYTES_LEN},
|
generic_signature::{TSignature, SIGNATURE_BYTES_LEN, SIGNATURE_UNCOMPRESSED_BYTES_LEN},
|
||||||
BlstError, Error, Hash256, ZeroizeHash, INFINITY_SIGNATURE,
|
BlstError, Error, Hash256, ZeroizeHash, INFINITY_SIGNATURE,
|
||||||
};
|
};
|
||||||
pub use blst::min_pk as blst_core;
|
pub use blst::min_pk as blst_core;
|
||||||
@@ -189,10 +189,18 @@ impl TSignature<blst_core::PublicKey> for blst_core::Signature {
|
|||||||
self.to_bytes()
|
self.to_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_uncompressed(&self) -> [u8; SIGNATURE_UNCOMPRESSED_BYTES_LEN] {
|
||||||
|
self.serialize()
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
Self::from_bytes(bytes).map_err(Into::into)
|
Self::from_bytes(bytes).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
Self::deserialize(bytes).map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
fn verify(&self, pubkey: &blst_core::PublicKey, msg: Hash256) -> bool {
|
fn verify(&self, pubkey: &blst_core::PublicKey, msg: Hash256) -> bool {
|
||||||
// Public keys have already been checked for subgroup and infinity
|
// Public keys have already been checked for subgroup and infinity
|
||||||
// Check Signature inside function for subgroup
|
// Check Signature inside function for subgroup
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::{
|
|||||||
GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
GenericPublicKey, TPublicKey, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
||||||
},
|
},
|
||||||
generic_secret_key::{TSecretKey, SECRET_KEY_BYTES_LEN},
|
generic_secret_key::{TSecretKey, SECRET_KEY_BYTES_LEN},
|
||||||
generic_signature::{TSignature, SIGNATURE_BYTES_LEN},
|
generic_signature::{TSignature, SIGNATURE_BYTES_LEN, SIGNATURE_UNCOMPRESSED_BYTES_LEN},
|
||||||
Error, Hash256, ZeroizeHash, INFINITY_PUBLIC_KEY, INFINITY_SIGNATURE,
|
Error, Hash256, ZeroizeHash, INFINITY_PUBLIC_KEY, INFINITY_SIGNATURE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,12 +106,22 @@ impl TSignature<PublicKey> for Signature {
|
|||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_uncompressed(&self) -> [u8; SIGNATURE_UNCOMPRESSED_BYTES_LEN] {
|
||||||
|
let mut ret = [0; SIGNATURE_UNCOMPRESSED_BYTES_LEN];
|
||||||
|
ret[0..SIGNATURE_BYTES_LEN].copy_from_slice(&self.0);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
let mut signature = Self::infinity();
|
let mut signature = Self::infinity();
|
||||||
signature.0[..].copy_from_slice(&bytes[0..SIGNATURE_BYTES_LEN]);
|
signature.0[..].copy_from_slice(&bytes[0..SIGNATURE_BYTES_LEN]);
|
||||||
Ok(signature)
|
Ok(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
|
||||||
|
Self::deserialize(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
fn verify(&self, _pubkey: &PublicKey, _msg: Hash256) -> bool {
|
fn verify(&self, _pubkey: &PublicKey, _msg: Hash256) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ pub use generic_public_key::{
|
|||||||
INFINITY_PUBLIC_KEY, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
INFINITY_PUBLIC_KEY, PUBLIC_KEY_BYTES_LEN, PUBLIC_KEY_UNCOMPRESSED_BYTES_LEN,
|
||||||
};
|
};
|
||||||
pub use generic_secret_key::SECRET_KEY_BYTES_LEN;
|
pub use generic_secret_key::SECRET_KEY_BYTES_LEN;
|
||||||
pub use generic_signature::{INFINITY_SIGNATURE, SIGNATURE_BYTES_LEN};
|
pub use generic_signature::{
|
||||||
|
INFINITY_SIGNATURE, INFINITY_SIGNATURE_UNCOMPRESSED, SIGNATURE_BYTES_LEN,
|
||||||
|
SIGNATURE_UNCOMPRESSED_BYTES_LEN,
|
||||||
|
};
|
||||||
pub use get_withdrawal_credentials::get_withdrawal_credentials;
|
pub use get_withdrawal_credentials::get_withdrawal_credentials;
|
||||||
pub use zeroize_hash::ZeroizeHash;
|
pub use zeroize_hash::ZeroizeHash;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use bls::{FixedBytesExtended, Hash256, INFINITY_SIGNATURE, SECRET_KEY_BYTES_LEN};
|
use bls::{
|
||||||
|
FixedBytesExtended, Hash256, INFINITY_SIGNATURE, INFINITY_SIGNATURE_UNCOMPRESSED,
|
||||||
|
SECRET_KEY_BYTES_LEN,
|
||||||
|
};
|
||||||
use ssz::{Decode, Encode};
|
use ssz::{Decode, Encode};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@@ -37,6 +40,18 @@ macro_rules! test_suite {
|
|||||||
assert!(AggregateSignature::infinity().is_infinity());
|
assert!(AggregateSignature::infinity().is_infinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn infinity_sig_serializations_match() {
|
||||||
|
let sig = Signature::deserialize(&INFINITY_SIGNATURE).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
sig.serialize_uncompressed().unwrap(),
|
||||||
|
INFINITY_SIGNATURE_UNCOMPRESSED
|
||||||
|
);
|
||||||
|
let sig =
|
||||||
|
Signature::deserialize_uncompressed(&INFINITY_SIGNATURE_UNCOMPRESSED).unwrap();
|
||||||
|
assert_eq!(sig.serialize(), INFINITY_SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ssz_round_trip_multiple_types() {
|
fn ssz_round_trip_multiple_types() {
|
||||||
let mut agg_sig = AggregateSignature::infinity();
|
let mut agg_sig = AggregateSignature::infinity();
|
||||||
|
|||||||
Reference in New Issue
Block a user