primitives/commitments/
hashbased.rs1use hybrid_array::Array;
2
3use super::CommitmentScheme;
4use crate::{
5 constants::CollisionResistanceBytes,
6 errors::{PrimitiveError, VerificationError},
7 hashing::{hash, Digest},
8 random::CryptoRngCore,
9 types::SessionId,
10};
11
12pub type Commitment = Digest;
13pub type Witness = Array<u8, CollisionResistanceBytes>;
14
15#[derive(Default, Copy, Clone, Debug)]
16pub struct HashBasedCommitment {
17 session_id: Option<SessionId>,
18}
19
20impl HashBasedCommitment {
21 pub fn new() -> Self {
22 Self { session_id: None }
23 }
24 pub fn new_with_session_id(session_id: SessionId) -> Self {
25 Self {
26 session_id: Some(session_id),
27 }
28 }
29}
30
31impl<T> CommitmentScheme<T> for HashBasedCommitment
32where
33 T: AsRef<[u8]>,
34{
35 type Commitment = Commitment;
36 type Witness = Witness;
37
38 fn commit<R: CryptoRngCore>(&self, input: &T, mut rng: R) -> (Self::Commitment, Self::Witness) {
39 let mut w = Witness::default();
41 rng.fill_bytes(&mut w);
42
43 let c = match self.session_id {
45 Some(session_id) => hash(&[w.as_ref(), input.as_ref(), session_id.as_ref()]),
46 None => hash(&[w.as_ref(), input.as_ref()]),
47 };
48
49 (c, w)
50 }
51
52 fn open(
53 &self,
54 c: &Self::Commitment,
55 w: &Self::Witness,
56 input: &T,
57 ) -> Result<(), PrimitiveError> {
58 let c_prime = match self.session_id {
60 Some(session_id) => hash(&[w.as_ref(), input.as_ref(), session_id.as_ref()]),
61 None => hash(&[w.as_ref(), input.as_ref()]),
62 };
63 if *c == c_prime {
65 Ok(())
66 } else {
67 Err(VerificationError::OpeningMismatch(format!("{c:?}"), format!("{c_prime:?}")).into())
68 }
69 }
70}