use crate::crypto::{CryptoType, Pair};
use sp_std::vec::Vec;
pub trait ProofOfPossessionGenerator: Pair
where
Self::Public: CryptoType,
{
#[cfg(feature = "full_crypto")]
fn generate_proof_of_possession(&mut self) -> Self::Signature;
}
pub trait ProofOfPossessionVerifier: Pair
where
Self::Public: CryptoType,
{
fn verify_proof_of_possession(
proof_of_possession: &Self::Signature,
allegedly_possessesd_pubkey: &Self::Public,
) -> bool;
}
pub trait NonAggregatable: Pair {
fn proof_of_possession_statement(pk: &impl crate::Public) -> Vec<u8> {
const PROOF_OF_POSSESSION_CONTEXT_TAG: &[u8; 4] = b"POP_";
[PROOF_OF_POSSESSION_CONTEXT_TAG, pk.to_raw_vec().as_slice()].concat()
}
}
impl<T> ProofOfPossessionVerifier for T
where
T: NonAggregatable,
{
fn verify_proof_of_possession(
proof_of_possession: &Self::Signature,
allegedly_possessesd_pubkey: &Self::Public,
) -> bool {
let proof_of_possession_statement =
Self::proof_of_possession_statement(allegedly_possessesd_pubkey);
Self::verify(
&proof_of_possession,
proof_of_possession_statement,
allegedly_possessesd_pubkey,
)
}
}
impl<T> ProofOfPossessionGenerator for T
where
T: NonAggregatable,
{
#[cfg(feature = "full_crypto")]
fn generate_proof_of_possession(&mut self) -> Self::Signature {
let proof_of_possession_statement = Self::proof_of_possession_statement(&self.public());
self.sign(proof_of_possession_statement.as_slice())
}
}