primitives/commitments/
pedersen.rs1use rand::SeedableRng;
2use subtle::ConstantTimeEq;
3
4use super::CommitmentScheme;
5use crate::{
6 algebra::elliptic_curve::{Curve, Point, ScalarAsExtension},
7 errors::PrimitiveError,
8 hashing::hash,
9 random::{BaseRng, CryptoRngCore, Random},
10};
11
12#[derive(Copy, Clone, Debug)]
13pub struct PedersenCommitment<C: Curve> {
14 pub g: Point<C>,
15 pub h: Point<C>,
16}
17
18impl<C: Curve> PedersenCommitment<C> {
19 pub fn new<S: AsRef<[u8]>>(second_generator_seed: &S) -> Self {
23 let g = Point::generator();
24 let mut rng = BaseRng::from_seed(hash(&[second_generator_seed.as_ref()]).into());
25 let h = Point::random(&mut rng);
26 Self { g, h }
27 }
28}
29
30impl<C: Curve> CommitmentScheme<ScalarAsExtension<C>> for PedersenCommitment<C> {
31 type Commitment = Point<C>;
32 type Witness = ScalarAsExtension<C>;
33
34 fn commit<R: CryptoRngCore>(
35 &self,
36 input: &ScalarAsExtension<C>,
37 mut rng: R,
38 ) -> (Self::Commitment, Self::Witness) {
39 let witness = ScalarAsExtension::<C>::random(&mut rng);
40
41 let commitment = self.g * witness + self.h * input;
42 (commitment, witness)
43 }
44
45 fn open(
46 &self,
47 c: &Self::Commitment,
48 w: &Self::Witness,
49 input: &ScalarAsExtension<C>,
50 ) -> Result<(), PrimitiveError> {
51 let c_prime = self.g * w + self.h * input;
52 if bool::from(c.ct_eq(&c_prime)) {
53 Ok(())
54 } else {
55 Err(PrimitiveError::WrongOpening(
56 format!("{c:?}"),
57 format!("{c_prime:?}"),
58 ))
59 }
60 }
61}