use crate::{errors::PrimitiveError, random::CryptoRngCore};
pub mod hashbased;
pub mod pedersen;
pub trait CommitmentScheme<InputT> {
type Commitment: Clone;
type Witness: Default + Clone;
fn commit<R: CryptoRngCore>(&self, input: &InputT, rng: R)
-> (Self::Commitment, Self::Witness);
fn open(
&self,
commitment: &Self::Commitment,
witness: &Self::Witness,
input: &InputT,
) -> Result<(), PrimitiveError>;
}
#[cfg(test)]
mod tests {
use rand::SeedableRng;
use super::{hashbased, pedersen};
use crate::{
algebra::elliptic_curve::{Curve25519Ristretto as C, ScalarAsExtension},
commitments::CommitmentScheme,
hashing::hash,
random::{test_rng, BaseRng, Random, Seed},
types::SessionId,
};
pub fn test_happypath_commitment_opens_ok<InputT, C: CommitmentScheme<InputT>>(
commitment_scheme: &C,
input_generator: impl Fn(Seed) -> InputT,
) {
let input = input_generator([0u8; 32]);
let mut rng = test_rng();
let (c, w) = commitment_scheme.commit(&input, &mut rng);
assert!(commitment_scheme.open(&c, &w, &input).is_ok());
}
pub fn test_unhappypath_wrong_or_mismatched_dont_open<InputT, C: CommitmentScheme<InputT>>(
commitment_scheme: &C,
input_generator: impl Fn(Seed) -> InputT,
) {
let input = input_generator([1u8; 32]);
let mut rng = test_rng();
let (c, w) = commitment_scheme.commit(&input, &mut rng);
let second_input = input_generator([2u8; 32]);
assert!(commitment_scheme.open(&c, &w, &second_input).is_err());
let (c2, w2) = commitment_scheme.commit(&input, &mut rng);
assert!(commitment_scheme.open(&c, &w2, &input).is_err());
assert!(commitment_scheme.open(&c2, &w, &input).is_err());
}
#[test]
pub fn test_commitment_scheme_hashbased() {
let session_id = SessionId::random(test_rng());
let commitment_scheme = hashbased::HashBasedCommitment::new_with_session_id(session_id);
let input_generator = |seed: Seed| hash(&[seed.as_ref()]);
test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
}
#[test]
pub fn test_commitment_scheme_pedersen() {
let commitment_scheme =
pedersen::PedersenCommitment::<C>::new(b"Nothing-up-my-sleeve generator h");
let input_generator = |seed: Seed| {
let mut rng = BaseRng::from_seed(seed);
ScalarAsExtension::<C>::random(&mut rng)
};
test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
}
}