primitives/commitments/
mod.rs1use crate::{errors::PrimitiveError, random::CryptoRngCore};
2
3pub mod hashbased;
4pub mod pedersen;
5
6pub trait CommitmentScheme<InputT> {
7 type Commitment: Clone;
8 type Witness: Default + Clone;
9
10 fn commit<R: CryptoRngCore>(&self, input: &InputT, rng: R)
11 -> (Self::Commitment, Self::Witness);
12 fn open(
13 &self,
14 commitment: &Self::Commitment,
15 witness: &Self::Witness,
16 input: &InputT,
17 ) -> Result<(), PrimitiveError>;
18}
19
20#[cfg(test)]
21mod tests {
22 use rand::SeedableRng;
23
24 use super::{hashbased, pedersen};
25 use crate::{
26 algebra::elliptic_curve::{Curve25519Ristretto as C, ScalarAsExtension},
27 commitments::CommitmentScheme,
28 hashing::hash,
29 random::{test_rng, BaseRng, Random, Seed},
30 types::SessionId,
31 };
32
33 pub fn test_happypath_commitment_opens_ok<InputT, C: CommitmentScheme<InputT>>(
35 commitment_scheme: &C,
36 input_generator: impl Fn(Seed) -> InputT,
37 ) {
38 let input = input_generator([0u8; 32]);
39 let mut rng = test_rng();
40
41 let (c, w) = commitment_scheme.commit(&input, &mut rng);
42 assert!(commitment_scheme.open(&c, &w, &input).is_ok());
43 }
44
45 pub fn test_unhappypath_wrong_or_mismatched_dont_open<InputT, C: CommitmentScheme<InputT>>(
48 commitment_scheme: &C,
49 input_generator: impl Fn(Seed) -> InputT,
50 ) {
51 let input = input_generator([1u8; 32]);
52 let mut rng = test_rng();
53
54 let (c, w) = commitment_scheme.commit(&input, &mut rng);
55
56 let second_input = input_generator([2u8; 32]);
58 assert!(commitment_scheme.open(&c, &w, &second_input).is_err());
59
60 let (c2, w2) = commitment_scheme.commit(&input, &mut rng);
62 assert!(commitment_scheme.open(&c, &w2, &input).is_err());
63 assert!(commitment_scheme.open(&c2, &w, &input).is_err());
64 }
65
66 #[test]
67 pub fn test_commitment_scheme_hashbased() {
68 let session_id = SessionId::random(test_rng());
69 let commitment_scheme = hashbased::HashBasedCommitment::new_with_session_id(session_id);
70 let input_generator = |seed: Seed| hash(&[seed.as_ref()]);
71
72 test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
73 test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
74 }
75
76 #[test]
77 pub fn test_commitment_scheme_pedersen() {
78 let commitment_scheme =
79 pedersen::PedersenCommitment::<C>::new(b"Nothing-up-my-sleeve generator h");
80 let input_generator = |seed: Seed| {
81 let mut rng = BaseRng::from_seed(seed);
82 ScalarAsExtension::<C>::random(&mut rng)
83 };
84
85 test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
86 test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
87 }
88}