primitives/commitments/
pedersen.rs

1use rand_chacha::ChaCha12Rng;
2
3use super::CommitmentScheme;
4use crate::{
5    algebra::elliptic_curve::{Curve, Point, ScalarAsExtension},
6    errors::PrimitiveError,
7    random::{CryptoRngCore, Prng, Random},
8};
9
10#[derive(Copy, Clone, Debug)]
11pub struct PedersenCommitment<C: Curve> {
12    pub g: Point<C>,
13    pub h: Point<C>,
14}
15
16impl<C: Curve> PedersenCommitment<C> {
17    // Create a new Pedersen commitment scheme by defining the two generators, using the curve's
18    // generator as the first generator (g) and the provided seed to derive the second generator
19    // (h).
20    pub fn new<S: AsRef<[u8]>>(second_generator_seed: &S) -> Self {
21        let g = Point::generator();
22        let mut rng = ChaCha12Rng::from_hashed_seed(second_generator_seed.as_ref());
23        let h = Point::random(&mut rng);
24        Self { g, h }
25    }
26}
27
28impl<C: Curve> CommitmentScheme<ScalarAsExtension<C>> for PedersenCommitment<C> {
29    type Commitment = Point<C>;
30    type Witness = ScalarAsExtension<C>;
31
32    fn commit<R: CryptoRngCore>(
33        &self,
34        input: &ScalarAsExtension<C>,
35        mut rng: R,
36    ) -> (Self::Commitment, Self::Witness) {
37        let witness = ScalarAsExtension::<C>::random(&mut rng);
38
39        let commitment = self.g * witness + self.h * input;
40        (commitment, witness)
41    }
42
43    fn open(
44        &self,
45        c: &Self::Commitment,
46        w: &Self::Witness,
47        input: &ScalarAsExtension<C>,
48    ) -> Result<(), PrimitiveError> {
49        let c_prime = self.g * w + self.h * input;
50        if *c == c_prime {
51            Ok(())
52        } else {
53            Err(PrimitiveError::WrongOpening(
54                format!("{c:?}"),
55                format!("{c_prime:?}"),
56            ))
57        }
58    }
59}