mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-19 21:04:41 +00:00
## Issue Addressed NA ## Proposed Changes - Refactor the `bls` crate to support multiple BLS "backends" (e.g., milagro, blst, etc). - Removes some duplicate, unused code in `common/rest_types/src/validator.rs`. - Removes the old "upgrade legacy keypairs" functionality (these were unencrypted keys that haven't been supported for a few testnets, no one should be using them anymore). ## Additional Info Most of the files changed are just inconsequential changes to function names. ## TODO - [x] Optimization levels - [x] Infinity point: https://github.com/supranational/blst/issues/11 - [x] Ensure milagro *and* blst are tested via CI - [x] What to do with unsafe code? - [x] Test infinity point in signature sets
122 lines
3.8 KiB
Rust
122 lines
3.8 KiB
Rust
use crate::{
|
|
generic_aggregate_public_key::TAggregatePublicKey,
|
|
generic_aggregate_signature::{GenericAggregateSignature, TAggregateSignature},
|
|
generic_public_key::{GenericPublicKey, TPublicKey},
|
|
generic_signature::{GenericSignature, TSignature},
|
|
Hash256,
|
|
};
|
|
use std::borrow::Cow;
|
|
use std::marker::PhantomData;
|
|
|
|
/// A generic way to represent a `GenericSignature` or `GenericAggregateSignature`.
|
|
pub struct WrappedSignature<'a, Pub, AggPub, Sig, AggSig>
|
|
where
|
|
Pub: TPublicKey + Clone,
|
|
AggPub: Clone,
|
|
Sig: Clone,
|
|
AggSig: Clone,
|
|
{
|
|
aggregate: Cow<'a, GenericAggregateSignature<Pub, AggPub, Sig, AggSig>>,
|
|
}
|
|
|
|
impl<'a, Pub, AggPub, Sig, AggSig> Into<WrappedSignature<'a, Pub, AggPub, Sig, AggSig>>
|
|
for &'a GenericSignature<Pub, Sig>
|
|
where
|
|
Pub: TPublicKey + Clone,
|
|
AggPub: Clone,
|
|
Sig: TSignature<Pub> + Clone,
|
|
AggSig: TAggregateSignature<Pub, AggPub, Sig> + Clone,
|
|
{
|
|
fn into(self) -> WrappedSignature<'a, Pub, AggPub, Sig, AggSig> {
|
|
let mut aggregate: GenericAggregateSignature<Pub, AggPub, Sig, AggSig> =
|
|
GenericAggregateSignature::infinity();
|
|
aggregate.add_assign(self);
|
|
WrappedSignature {
|
|
aggregate: Cow::Owned(aggregate),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, Pub, AggPub, Sig, AggSig> Into<WrappedSignature<'a, Pub, AggPub, Sig, AggSig>>
|
|
for &'a GenericAggregateSignature<Pub, AggPub, Sig, AggSig>
|
|
where
|
|
Pub: TPublicKey + Clone,
|
|
AggPub: Clone,
|
|
Sig: Clone,
|
|
AggSig: Clone,
|
|
{
|
|
fn into(self) -> WrappedSignature<'a, Pub, AggPub, Sig, AggSig> {
|
|
WrappedSignature {
|
|
aggregate: Cow::Borrowed(self),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A generic way to represent a signature across a message by multiple public keys.
|
|
///
|
|
/// This struct is primarily useful in a collection (e.g., `Vec<GenericSignatureSet>`) so we can perform
|
|
/// multiple-signature verification which is much faster than verifying each signature
|
|
/// individually.
|
|
#[derive(Clone)]
|
|
pub struct GenericSignatureSet<'a, Pub, AggPub, Sig, AggSig>
|
|
where
|
|
Pub: TPublicKey + Clone,
|
|
AggPub: Clone,
|
|
Sig: Clone,
|
|
AggSig: Clone,
|
|
{
|
|
pub signature: Cow<'a, GenericAggregateSignature<Pub, AggPub, Sig, AggSig>>,
|
|
pub(crate) signing_keys: Vec<Cow<'a, GenericPublicKey<Pub>>>,
|
|
pub(crate) message: Hash256,
|
|
_phantom: PhantomData<Sig>,
|
|
}
|
|
|
|
impl<'a, Pub, AggPub, Sig, AggSig> GenericSignatureSet<'a, Pub, AggPub, Sig, AggSig>
|
|
where
|
|
Pub: TPublicKey + Clone,
|
|
AggPub: TAggregatePublicKey + Clone,
|
|
Sig: TSignature<Pub> + Clone,
|
|
AggSig: TAggregateSignature<Pub, AggPub, Sig> + Clone,
|
|
{
|
|
/// Instantiate self where `signature` is only signed by a single public key.
|
|
pub fn single_pubkey(
|
|
signature: impl Into<WrappedSignature<'a, Pub, AggPub, Sig, AggSig>>,
|
|
signing_key: Cow<'a, GenericPublicKey<Pub>>,
|
|
message: Hash256,
|
|
) -> Self {
|
|
Self {
|
|
signature: signature.into().aggregate,
|
|
signing_keys: vec![signing_key],
|
|
message,
|
|
_phantom: PhantomData,
|
|
}
|
|
}
|
|
|
|
/// Instantiate self where `signature` is signed by multiple public keys.
|
|
pub fn multiple_pubkeys(
|
|
signature: impl Into<WrappedSignature<'a, Pub, AggPub, Sig, AggSig>>,
|
|
signing_keys: Vec<Cow<'a, GenericPublicKey<Pub>>>,
|
|
message: Hash256,
|
|
) -> Self {
|
|
Self {
|
|
signature: signature.into().aggregate,
|
|
signing_keys,
|
|
message,
|
|
_phantom: PhantomData,
|
|
}
|
|
}
|
|
|
|
/// Returns `true` if `self.signature` is a signature across `self.message` by
|
|
/// `self.signing_keys`.
|
|
pub fn verify(self) -> bool {
|
|
let pubkeys = self
|
|
.signing_keys
|
|
.iter()
|
|
.map(|pk| pk.as_ref())
|
|
.collect::<Vec<_>>();
|
|
|
|
self.signature
|
|
.fast_aggregate_verify(self.message, &pubkeys[..])
|
|
}
|
|
}
|