use crate::{utils, PublicKey, Signature, SignatureShare};
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Debug, Formatter},
hash::{Hash, Hasher},
};
#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Proof {
Bls(BlsProof),
BlsShare(BlsProofShare),
Ed25519(Ed25519Proof),
}
impl Proof {
pub fn id(&self) -> PublicKey {
use Proof::*;
match self {
Bls(proof) => proof.id(),
BlsShare(proof) => proof.id(),
Ed25519(proof) => proof.id(),
}
}
pub fn signature(&self) -> Signature {
use Proof::*;
match self {
Bls(proof) => proof.signature(),
BlsShare(proof) => proof.signature(),
Ed25519(proof) => proof.signature(),
}
}
pub fn verify(&self, payload: &[u8]) -> bool {
use Proof::*;
match self {
Bls(proof) => proof.verify(payload),
BlsShare(proof) => proof.verify(payload),
Ed25519(proof) => proof.verify(payload),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Ed25519Proof {
pub public_key: ed25519_dalek::PublicKey,
pub signature: ed25519_dalek::Signature,
}
impl Ed25519Proof {
pub fn id(&self) -> PublicKey {
PublicKey::Ed25519(self.public_key)
}
pub fn signature(&self) -> Signature {
Signature::Ed25519(self.signature)
}
pub fn verify(&self, payload: &[u8]) -> bool {
self.id().verify(&self.signature(), payload).is_ok()
}
}
impl PartialEq for Ed25519Proof {
fn eq(&self, other: &Self) -> bool {
self.public_key.to_bytes().to_vec() == other.public_key.to_bytes().to_vec()
&& self.signature.to_bytes().to_vec() == other.signature.to_bytes().to_vec()
}
}
impl Eq for Ed25519Proof {}
#[allow(clippy::derive_hash_xor_eq)]
impl Hash for Ed25519Proof {
fn hash<H: Hasher>(&self, state: &mut H) {
utils::serialise(&self).hash(state)
}
}
#[derive(Clone, Hash, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct BlsProof {
pub public_key: threshold_crypto::PublicKey,
pub signature: threshold_crypto::Signature,
}
impl BlsProof {
pub fn verify(&self, payload: &[u8]) -> bool {
self.public_key.verify(&self.signature, payload)
}
pub fn id(&self) -> PublicKey {
PublicKey::Bls(self.public_key)
}
pub fn signature(&self) -> Signature {
Signature::Bls(self.signature.clone())
}
}
#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct BlsProofShare {
pub public_key_set: threshold_crypto::PublicKeySet,
pub index: usize,
pub signature_share: threshold_crypto::SignatureShare,
}
impl BlsProofShare {
pub fn new(
public_key_set: threshold_crypto::PublicKeySet,
index: usize,
secret_key_share: &threshold_crypto::SecretKeyShare,
payload: &[u8],
) -> Self {
Self {
public_key_set,
index,
signature_share: secret_key_share.sign(payload),
}
}
pub fn id(&self) -> PublicKey {
PublicKey::BlsShare(self.public_key_set.public_key_share(self.index))
}
pub fn signature(&self) -> Signature {
Signature::BlsShare(SignatureShare {
index: self.index,
share: self.signature_share.clone(),
})
}
pub fn verify(&self, payload: &[u8]) -> bool {
self.public_key_set
.public_key_share(self.index)
.verify(&self.signature_share, payload)
}
}
impl Debug for BlsProofShare {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
write!(
formatter,
"ProofShare {{ public_key: {:?}, index: {}, .. }}",
self.public_key_set.public_key(),
self.index
)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Proven<T> {
pub value: T,
pub proof: BlsProof,
}
impl<T> Proven<T> {
pub fn new(value: T, proof: BlsProof) -> Self {
Self { value, proof }
}
}