use crate::rand::{distributions::Standard, Rng, RngCore};
use bls::{serde_impl::SerdeSecret, PublicKey, SecretKey, PK_SIZE};
use serde::{Deserialize, Serialize};
pub type DerivationIndex = [u8; 32];
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct UniquePubkey(PublicKey);
impl UniquePubkey {
pub fn new<G: Into<PublicKey>>(public_key: G) -> Self {
Self(public_key.into())
}
pub fn to_bytes(&self) -> [u8; bls::PK_SIZE] {
self.0.to_bytes()
}
pub fn verify<M: AsRef<[u8]>>(&self, sig: &bls::Signature, msg: M) -> bool {
self.0.verify(sig, msg)
}
pub fn random_derivation_index(rng: &mut impl RngCore) -> DerivationIndex {
let mut bytes = [0u8; 32];
rng.fill_bytes(&mut bytes);
bytes
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DerivedSecretKey(SerdeSecret<SecretKey>);
impl DerivedSecretKey {
pub fn new<S: Into<SecretKey>>(secret_key: S) -> Self {
Self(SerdeSecret(secret_key.into()))
}
pub fn unique_pubkey(&self) -> UniquePubkey {
UniquePubkey(self.0.public_key())
}
pub(crate) fn sign(&self, msg: &[u8]) -> bls::Signature {
self.0.sign(msg)
}
}
#[derive(Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Serialize, Deserialize)]
pub struct MainPubkey(pub PublicKey);
impl MainPubkey {
pub fn new(public_key: PublicKey) -> Self {
Self(public_key)
}
pub fn verify(&self, sig: &bls::Signature, msg: &[u8]) -> bool {
self.0.verify(sig, msg)
}
pub fn new_unique_pubkey(&self, index: &DerivationIndex) -> UniquePubkey {
UniquePubkey(self.0.derive_child(index))
}
pub fn to_bytes(self) -> [u8; PK_SIZE] {
self.0.to_bytes()
}
}
pub struct MainSecretKey(SerdeSecret<SecretKey>);
impl MainSecretKey {
pub fn new(secret_key: SecretKey) -> Self {
Self(SerdeSecret(secret_key))
}
pub fn secret_key(&self) -> &SecretKey {
&self.0
}
pub fn main_pubkey(&self) -> MainPubkey {
MainPubkey(self.0.public_key())
}
pub fn sign(&self, msg: &[u8]) -> bls::Signature {
self.0.sign(msg)
}
pub fn derive_key(&self, index: &DerivationIndex) -> DerivedSecretKey {
DerivedSecretKey::new(self.0.inner().derive_child(index))
}
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes().to_vec()
}
pub fn random() -> Self {
Self::new(bls::SecretKey::random())
}
pub fn random_from_rng(rng: &mut impl RngCore) -> Self {
let sk: SecretKey = rng.sample(Standard);
Self::new(sk)
}
pub fn random_derived_key(&self, rng: &mut impl RngCore) -> DerivedSecretKey {
self.derive_key(&UniquePubkey::random_derivation_index(rng))
}
}