use crate::CommitmentProtocol;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)]
#[display(doc_comments)]
pub enum VerifyError {
InvalidCommitment,
InvalidMessage,
}
pub trait CommitVerify<Msg, Protocol: CommitmentProtocol>
where Self: Eq + Sized
{
fn commit(msg: &Msg) -> Self;
#[inline]
fn verify(&self, msg: &Msg) -> Result<(), VerifyError> {
match Self::commit(msg) == *self {
false => Err(VerifyError::InvalidCommitment),
true => Ok(()),
}
}
}
pub trait TryCommitVerify<Msg, Protocol: CommitmentProtocol>
where Self: Eq + Sized
{
type Error: std::error::Error;
fn try_commit(msg: &Msg) -> Result<Self, Self::Error>;
#[inline]
fn verify(&self, msg: &Msg) -> Result<(), VerifyError> {
let other_commitment = Self::try_commit(msg).map_err(|_| VerifyError::InvalidMessage)?;
if other_commitment != *self {
return Err(VerifyError::InvalidCommitment);
}
Ok(())
}
}
#[cfg(test)]
pub(crate) mod test_helpers {
#![cfg_attr(coverage_nightly, coverage(off))]
use core::fmt::Debug;
use core::hash::Hash;
use std::collections::HashSet;
use super::*;
use crate::UntaggedProtocol;
pub fn commit_verify_suite<Msg, Cmt>(messages: Vec<Msg>)
where
Msg: AsRef<[u8]> + Eq,
Cmt: CommitVerify<Msg, UntaggedProtocol> + Eq + Hash + Debug,
{
messages
.iter()
.fold(HashSet::<Cmt>::with_capacity(messages.len()), |mut acc, msg| {
let commitment = Cmt::commit(msg);
(1..10).for_each(|_| {
assert_eq!(Cmt::commit(msg), commitment);
});
assert!(commitment.verify(msg).is_ok());
messages.iter().for_each(|m| {
assert_eq!(commitment.verify(m).is_ok(), m == msg);
});
acc.iter().for_each(|cmt| {
assert!(cmt.verify(msg).is_err());
});
assert!(acc.insert(commitment));
acc
});
}
}