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 use rand_chacha::ChaCha12Rng as ChaChaRng;
24
25 use super::{hashbased, pedersen};
26 use crate::{
27 algebra::elliptic_curve::{Curve25519Ristretto as C, ScalarAsExtension},
28 commitments::CommitmentScheme,
29 hashing::hash,
30 random::{self, Prng, Random},
31 types::SessionId,
32 };
33
34 pub fn test_happypath_commitment_opens_ok<InputT, C: CommitmentScheme<InputT>>(
36 commitment_scheme: &C,
37 input_generator: impl Fn(u64) -> InputT,
38 ) {
39 let input = input_generator(0);
40 let mut rng = ChaChaRng::from_seed(
41 hash(&[b"It's like the great stories, Mr. Frodo, the ones that really mattered."])
42 .into(),
43 );
44
45 let (c, w) = commitment_scheme.commit(&input, &mut rng);
46 assert!(commitment_scheme.open(&c, &w, &input).is_ok());
47 }
48
49 pub fn test_unhappypath_wrong_or_mismatched_dont_open<InputT, C: CommitmentScheme<InputT>>(
52 commitment_scheme: &C,
53 input_generator: impl Fn(u64) -> InputT,
54 ) {
55 let input = input_generator(1);
56 let mut rng = random::test_rng();
57
58 let (c, w) = commitment_scheme.commit(&input, &mut rng);
59
60 let second_input = input_generator(2);
62 assert!(commitment_scheme.open(&c, &w, &second_input).is_err());
63
64 let (c2, w2) = commitment_scheme.commit(&input, &mut rng);
66 assert!(commitment_scheme.open(&c, &w2, &input).is_err());
67 assert!(commitment_scheme.open(&c2, &w, &input).is_err());
68 }
69
70 #[test]
71 pub fn test_commitment_scheme_hashbased() {
72 let session_id =
73 SessionId::from_hashed_seed(b"I will take the Ring though I do not know the way.");
74 let commitment_scheme = hashbased::HashBasedCommitment::new_with_session_id(session_id);
75 let input_generator = |seed: u64| hash(&[seed.to_be_bytes().as_ref()]);
76
77 test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
78 test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
79 }
80
81 #[test]
82 pub fn test_commitment_scheme_pedersen() {
83 let commitment_scheme =
84 pedersen::PedersenCommitment::<C>::new(b"the Ring is trying to get back to its master");
85 let input_generator = |seed: u64| {
86 let mut rng = ChaChaRng::from_hashed_seed(seed.to_be_bytes());
87 ScalarAsExtension::<C>::random(&mut rng)
88 };
89
90 test_happypath_commitment_opens_ok(&commitment_scheme, input_generator);
91 test_unhappypath_wrong_or_mismatched_dont_open(&commitment_scheme, input_generator);
92 }
93}