use crate::{
rand::{distributions::Standard, Rng, RngCore},
PublicKey,
};
use blsttc::{serde_impl::SerdeSecret, SecretKey, PK_SIZE};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type DerivationIndex = [u8; 32];
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct DbcId(PublicKey);
impl DbcId {
pub fn new<G: Into<PublicKey>>(public_key: G) -> Self {
Self(public_key.into())
}
pub fn to_bytes(&self) -> [u8; blsttc::PK_SIZE] {
self.0.to_bytes()
}
pub fn verify<M: AsRef<[u8]>>(&self, sig: &blsttc::Signature, msg: M) -> bool {
self.0.verify(sig, msg)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct DerivedKey(SerdeSecret<SecretKey>);
impl DerivedKey {
pub fn new<S: Into<SecretKey>>(secret_key: S) -> Self {
Self(SerdeSecret(secret_key.into()))
}
pub fn dbc_id(&self) -> DbcId {
DbcId(self.0.public_key())
}
pub(crate) fn sign(&self, msg: &[u8]) -> blsttc::Signature {
self.0.sign(msg)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Clone)]
pub struct PublicAddress(pub PublicKey);
impl PublicAddress {
pub fn new(public_key: PublicKey) -> Self {
Self(public_key)
}
pub fn verify(&self, sig: &blsttc::Signature, msg: &[u8]) -> bool {
self.0.verify(sig, msg)
}
pub fn new_dbc_id(&self, index: &DerivationIndex) -> DbcId {
DbcId(self.0.derive_child(index))
}
pub fn to_bytes(self) -> [u8; PK_SIZE] {
self.0.to_bytes()
}
}
pub struct MainKey(SerdeSecret<SecretKey>);
impl MainKey {
pub fn new(secret_key: SecretKey) -> Self {
Self(SerdeSecret(secret_key))
}
pub fn secret_key(&self) -> &SecretKey {
&self.0
}
pub fn public_address(&self) -> PublicAddress {
PublicAddress(self.0.public_key())
}
pub fn sign(&self, msg: &[u8]) -> blsttc::Signature {
self.0.sign(msg)
}
pub fn derive_key(&self, index: &DerivationIndex) -> DerivedKey {
DerivedKey::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(blsttc::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) -> DerivedKey {
self.derive_key(&random_derivation_index(rng))
}
}
pub fn random_derivation_index(rng: &mut impl RngCore) -> [u8; 32] {
let mut bytes = [0u8; 32];
rng.fill_bytes(&mut bytes);
bytes
}