nova-study/src/pedersen.rs
src/pedersen.rsRaw
1use ark_ec::AffineRepr;
2use ark_std::{
3 rand::{Rng, RngCore},
4 UniformRand,
5};
6use std::marker::PhantomData;
7
8use crate::transcript::Transcript;
9use crate::utils::{naive_msm, vec_add, vector_elem_product};
10
11pub struct Proof_elem<C: AffineRepr> {
12 R: C,
13 t1: C::ScalarField,
14 t2: C::ScalarField,
15}
16pub struct Proof<C: AffineRepr> {
17 R: C,
18 u_: Vec<C::ScalarField>,
19 ru_: C::ScalarField,
20}
21
22pub struct Params<C: AffineRepr> {
23 g: C,
24 h: C,
25 pub r_vec: Vec<C>,
26}
27
28pub struct Pedersen<C: AffineRepr> {
29 _phantom: PhantomData<C>,
30}
31
32impl<C: AffineRepr> Pedersen<C> {
33 pub fn new_params<R: Rng>(rng: &mut R, max: usize) -> Params<C> {
34 let h_scalar = C::ScalarField::rand(rng);
35 let g: C = C::generator();
36 let r_vec: Vec<C> = vec![C::rand(rng); max];
37 let params: Params<C> = Params::<C> {
38 g,
39 h: g.mul(h_scalar).into(),
40 r_vec, // will need 2 r: rE, rW
41 };
42 params
43 }
44
45 pub fn commit_elem<R: RngCore>(
46 rng: &mut R,
47 params: &Params<C>,
48 v: &C::ScalarField,
49 ) -> CommitmentElem<C> {
50 let r = C::ScalarField::rand(rng);
51 let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
52 CommitmentElem::<C> { cm, r }
53 }
54 pub fn commit<R: RngCore>(
55 rng: &mut R,
56 params: &Params<C>,
57 v: &Vec<C::ScalarField>,
58 ) -> Commitment<C> {
59 let r = C::ScalarField::rand(rng);
60 let cm = params.h.mul(r) + naive_msm(v, ¶ms.r_vec);
61 Commitment::<C> { cm: cm.into(), r }
62 }
63
64 pub fn prove_elem(
65 params: &Params<C>,
66 transcript: &mut Transcript<C::ScalarField>,
67 cm: C,
68 v: C::ScalarField,
69 r: C::ScalarField,
70 ) -> Proof_elem<C> {
71 let r1 = transcript.get_challenge(b"r_1");
72 let r2 = transcript.get_challenge(b"r_2");
73
74 let R: C = (params.g.mul(r1) + params.h.mul(r2)).into();
75
76 transcript.add(b"cm", &cm);
77 transcript.add(b"R", &R);
78 let e = transcript.get_challenge(b"e");
79
80 let t1 = r1 + v * e;
81 let t2 = r2 + r * e;
82
83 Proof_elem::<C> { R, t1, t2 }
84 }
85 pub fn prove(
86 params: &Params<C>,
87 transcript: &mut Transcript<C::ScalarField>,
88 cm: C,
89 v: Vec<C::ScalarField>,
90 r: C::ScalarField,
91 ) -> Proof<C> {
92 let r1 = transcript.get_challenge(b"r_1");
93 let d = transcript.get_challenge_vec(b"d", v.len());
94
95 let R: C = (params.h.mul(r1) + naive_msm(&d, ¶ms.r_vec)).into();
96
97 transcript.add(b"cm", &cm);
98 transcript.add(b"R", &R);
99 let e = transcript.get_challenge(b"e");
100
101 let u_ = vec_add(&vector_elem_product(&v, &e), &d);
102 let ru_ = e * r + r1;
103
104 Proof::<C> { R, u_, ru_ }
105 }
106 pub fn verify(
107 params: &Params<C>,
108 transcript: &mut Transcript<C::ScalarField>,
109 cm: C,
110 proof: Proof<C>,
111 ) -> bool {
112 // r1, d just to match Prover's transcript
113 transcript.get_challenge(b"r_1");
114 transcript.get_challenge_vec(b"d", proof.u_.len());
115
116 transcript.add(b"cm", &cm);
117 transcript.add(b"R", &proof.R);
118 let e = transcript.get_challenge(b"e");
119 let lhs = proof.R + cm.mul(e);
120 let rhs = params.h.mul(proof.ru_) + naive_msm(&proof.u_, ¶ms.r_vec);
121 if lhs != rhs {
122 return false;
123 }
124 true
125 }
126
127 pub fn verify_elem(
128 params: &Params<C>,
129 transcript: &mut Transcript<C::ScalarField>,
130 cm: C,
131 proof: Proof_elem<C>,
132 ) -> bool {
133 // s1, s2 just to match Prover's transcript
134 transcript.get_challenge(b"r_1");
135 transcript.get_challenge(b"r_2");
136
137 transcript.add(b"cm", &cm);
138 transcript.add(b"R", &proof.R);
139 let e = transcript.get_challenge(b"e");
140 let lhs = proof.R + cm.mul(e);
141 let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
142 if lhs != rhs {
143 return false;
144 }
145 true
146 }
147}
148
149pub struct Commitment<C: AffineRepr> {
150 pub cm: C,
151 pub r: C::ScalarField,
152}
153impl<C: AffineRepr> Commitment<C> {
154 pub fn prove(
155 &self,
156 params: &Params<C>,
157 transcript: &mut Transcript<C::ScalarField>,
158 v: Vec<C::ScalarField>,
159 ) -> Proof<C> {
160 Pedersen::<C>::prove(params, transcript, self.cm, v, self.r)
161 }
162}
163
164pub struct CommitmentElem<C: AffineRepr> {
165 pub cm: C,
166 pub r: C::ScalarField,
167}
168impl<C: AffineRepr> CommitmentElem<C> {
169 pub fn prove(
170 &self,
171 params: &Params<C>,
172 transcript: &mut Transcript<C::ScalarField>,
173 v: C::ScalarField,
174 ) -> Proof_elem<C> {
175 Pedersen::<C>::prove_elem(params, transcript, self.cm, v, self.r)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182 use ark_bn254::{g1::G1Affine, Fr};
183 use ark_ec::CurveGroup;
184 use std::ops::Mul;
185
186 #[test]
187 fn test_pedersen_single_element() {
188 let mut rng = ark_std::test_rng();
189
190 // setup params
191 let params = Pedersen::<G1Affine>::new_params(
192 &mut rng, 0, /* 0, as here we don't use commit_vec */
193 );
194
195 // init Prover's transcript
196 let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
197 // init Verifier's transcript
198 let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
199
200 let v = Fr::rand(&mut rng);
201
202 let cm = Pedersen::commit_elem(&mut rng, ¶ms, &v);
203 let proof = cm.prove(¶ms, &mut transcript_p, v);
204 // also can use:
205 // let proof = Pedersen::prove_elem(¶ms, &mut transcript_p, cm.cm, v, cm.r);
206 let v = Pedersen::verify_elem(¶ms, &mut transcript_v, cm.cm, proof);
207 assert!(v);
208 }
209 #[test]
210 fn test_pedersen_vector() {
211 let mut rng = ark_std::test_rng();
212
213 const n: usize = 10;
214 // setup params
215 let params = Pedersen::<G1Affine>::new_params(&mut rng, n);
216
217 // init Prover's transcript
218 let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
219 // init Verifier's transcript
220 let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
221
222 let mut v: Vec<Fr> = vec![Fr::rand(&mut rng); n];
223
224 let cm = Pedersen::commit(&mut rng, ¶ms, &v);
225 let proof = cm.prove(¶ms, &mut transcript_p, v);
226 // also can use:
227 // let proof = Pedersen::prove(¶ms, &mut transcript_p, cm.cm, v, cm.r);
228 let v = Pedersen::verify(¶ms, &mut transcript_v, cm.cm, proof);
229 assert!(v);
230 }
231}