nova-study/src/pedersen.rs
src/pedersen.rsRaw
1use ark_ec::AffineRepr;
2use ark_std::{rand::RngCore, UniformRand};
3use std::marker::PhantomData;
4
5use crate::transcript::Transcript;
6
7pub struct Proof<C: AffineRepr> {
8 R: C,
9 t1: C::ScalarField,
10 t2: C::ScalarField,
11}
12
13pub struct Params<C: AffineRepr> {
14 g: C,
15 h: C,
16}
17
18pub struct Pedersen<C: AffineRepr> {
19 _phantom: PhantomData<C>,
20}
21
22impl<C: AffineRepr> Pedersen<C> {
23 pub fn commit<R: RngCore>(
24 rng: &mut R,
25 params: &Params<C>,
26 v: &C::ScalarField,
27 ) -> (C, C::ScalarField) {
28 let r = C::ScalarField::rand(rng);
29 let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
30 (cm, r)
31 }
32 pub fn prove(
33 params: &Params<C>,
34 transcript: &mut Transcript<C::ScalarField>,
35 cm: C,
36 v: C::ScalarField,
37 r: C::ScalarField,
38 ) -> Proof<C> {
39 let s1 = transcript.get_challenge(b"s_1");
40 let s2 = transcript.get_challenge(b"s_2");
41
42 let R: C = (params.g.mul(s1) + params.h.mul(s2)).into();
43
44 transcript.add(b"cm", &cm);
45 transcript.add(b"R", &R);
46 let c = transcript.get_challenge(b"c");
47
48 let t1 = s1 + v * c;
49 let t2 = s2 + r * c;
50
51 Proof::<C> { R, t1, t2 }
52 }
53
54 pub fn verify(
55 params: &Params<C>,
56 transcript: &mut Transcript<C::ScalarField>,
57 cm: C,
58 proof: Proof<C>,
59 ) -> bool {
60 // s1, s2 just to match Prover's transcript
61 transcript.get_challenge(b"s_1");
62 transcript.get_challenge(b"s_2");
63
64 transcript.add(b"cm", &cm);
65 transcript.add(b"R", &proof.R);
66 let c = transcript.get_challenge(b"c");
67 let lhs = proof.R + cm.mul(c);
68 let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
69 if lhs != rhs {
70 return false;
71 }
72 true
73 }
74}
75
76pub struct Commitment<C: AffineRepr> {
77 pub cm: C,
78 pub r: C::ScalarField,
79}
80impl<C: AffineRepr> Commitment<C> {
81 pub fn prove(
82 self,
83 params: &Params<C>,
84 transcript: &mut Transcript<C::ScalarField>,
85 v: C::ScalarField,
86 ) -> Proof<C> {
87 Pedersen::<C>::prove(params, transcript, self.cm, v, self.r)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use ark_bn254::{g1::G1Affine, Fr};
95 use ark_ec::CurveGroup;
96 use std::ops::Mul;
97
98 #[test]
99 fn test_pedersen() {
100 let mut rng = ark_std::test_rng();
101
102 // setup params
103 let h_scalar = Fr::rand(&mut rng);
104 let g: G1Affine = G1Affine::generator();
105 let params: Params<G1Affine> = Params::<G1Affine> {
106 g,
107 h: g.mul(h_scalar).into_affine(),
108 };
109
110 // init Prover's transcript
111 let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
112 // init Verifier's transcript
113 let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
114
115 let v = Fr::rand(&mut rng);
116
117 let (cm, r) = Pedersen::commit(&mut rng, ¶ms, &v);
118 let proof = Pedersen::prove(¶ms, &mut transcript_p, cm, v, r);
119 let v = Pedersen::verify(¶ms, &mut transcript_v, cm, proof);
120 assert!(v);
121 }
122}