use crate::messaging::{
signature_aggregator::{AggregatorError, SignatureAggregator},
AuthorityProof,
};
use serde::{Deserialize, Serialize};
use std::{
borrow::Borrow,
fmt::{self, Debug, Formatter},
ops::Deref,
};
use xor_name::Prefix;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct SectionSig {
pub public_key: bls::PublicKey,
pub signature: bls::Signature,
}
impl Debug for SectionSig {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("SectionSig").field(&self.public_key).finish()
}
}
impl SectionSig {
pub fn verify(&self, payload: &[u8]) -> bool {
self.public_key.verify(&self.signature, payload)
}
pub fn try_authorize(
aggregator: &mut SignatureAggregator,
share: SectionSigShare,
payload: impl AsRef<[u8]>,
) -> Result<Option<AuthorityProof<Self>>, AggregatorError> {
match aggregator.try_aggregate(payload.as_ref(), share)? {
Some(sig) => Ok(Some(AuthorityProof(Self {
public_key: sig.public_key,
signature: sig.signature,
}))),
None => Ok(None),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct SectionSigShare {
pub public_key_set: bls::PublicKeySet,
pub index: usize,
pub signature_share: bls::SignatureShare,
}
impl SectionSigShare {
pub fn new(
public_key_set: bls::PublicKeySet,
index: usize,
secret_key_share: &bls::SecretKeyShare,
payload: &[u8],
) -> Self {
Self {
public_key_set,
index,
signature_share: secret_key_share.sign(payload),
}
}
pub fn verify(&self, payload: &[u8]) -> bool {
self.public_key_set
.public_key_share(self.index)
.verify(&self.signature_share, payload)
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
pub struct SectionSigned<T: Serialize> {
pub value: T,
pub sig: SectionSig,
}
impl<T> Borrow<Prefix> for SectionSigned<T>
where
T: Borrow<Prefix> + Serialize,
{
fn borrow(&self) -> &Prefix {
self.value.borrow()
}
}
impl<T: Serialize> Deref for SectionSigned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[cfg(test)]
mod tests {
use crate::test_utils::TestKeys;
use bls::SecretKey;
#[test]
fn verify_keyed_sig() {
let sk = SecretKey::random();
let data = "hello";
let sig = TestKeys::get_section_sig_bytes(&sk, data.as_bytes());
assert!(sig.verify(data.as_bytes()));
}
}