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