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;
10
11pub struct Proof<C: AffineRepr> {
12 R: C,
13 t1: C::ScalarField,
14 t2: C::ScalarField,
15}
16
17pub struct Params<C: AffineRepr> {
18 g: C,
19 h: C,
20}
21
22pub struct Pedersen<C: AffineRepr> {
23 _phantom: PhantomData<C>,
24}
25
26impl<C: AffineRepr> Pedersen<C> {
27 pub fn new_params<R: Rng>(rng: &mut R) -> Params<C> {
28 let h_scalar = C::ScalarField::rand(rng);
29 let g: C = C::generator();
30 let params: Params<C> = Params::<C> {
31 g,
32 h: g.mul(h_scalar).into(),
33 };
34 params
35 }
36
37 pub fn commit_elem<R: RngCore>(
38 rng: &mut R,
39 params: &Params<C>,
40 v: &C::ScalarField,
41 ) -> Commitment<C> {
42 let r = C::ScalarField::rand(rng);
43 let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
44 Commitment::<C> { cm, r }
45 }
46 pub fn commit_vec<R: RngCore>(
47 rng: &mut R,
48 params: &Params<C>,
49 v: &Vec<C::ScalarField>,
50 ) -> CommitmentVec<C> {
51 let r: Vec<C> = vec![C::rand(rng); v.len()]; // wip
52 let cm = naive_msm(v, &r);
53 CommitmentVec::<C> { cm, r }
54 }
55
56 pub fn prove(
57 params: &Params<C>,
58 transcript: &mut Transcript<C::ScalarField>,
59 cm: C,
60 v: C::ScalarField,
61 r: C::ScalarField,
62 ) -> Proof<C> {
63 let s1 = transcript.get_challenge(b"s_1");
64 let s2 = transcript.get_challenge(b"s_2");
65
66 let R: C = (params.g.mul(s1) + params.h.mul(s2)).into();
67
68 transcript.add(b"cm", &cm);
69 transcript.add(b"R", &R);
70 let c = transcript.get_challenge(b"c");
71
72 let t1 = s1 + v * c;
73 let t2 = s2 + r * c;
74
75 Proof::<C> { R, t1, t2 }
76 }
77
78 pub fn verify(
79 params: &Params<C>,
80 transcript: &mut Transcript<C::ScalarField>,
81 cm: C,
82 proof: Proof<C>,
83 ) -> bool {
84 // s1, s2 just to match Prover's transcript
85 transcript.get_challenge(b"s_1");
86 transcript.get_challenge(b"s_2");
87
88 transcript.add(b"cm", &cm);
89 transcript.add(b"R", &proof.R);
90 let c = transcript.get_challenge(b"c");
91 let lhs = proof.R + cm.mul(c);
92 let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
93 if lhs != rhs {
94 return false;
95 }
96 true
97 }
98}
99
100pub struct CommitmentVec<C: AffineRepr> {
101 // WIP
102 pub cm: C,
103 pub r: Vec<C>,
104}
105pub struct Commitment<C: AffineRepr> {
106 pub cm: C,
107 pub r: C::ScalarField,
108}
109impl<C: AffineRepr> Commitment<C> {
110 pub fn prove(
111 &self,
112 params: &Params<C>,
113 transcript: &mut Transcript<C::ScalarField>,
114 v: C::ScalarField,
115 ) -> Proof<C> {
116 Pedersen::<C>::prove(params, transcript, self.cm, v, self.r)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use ark_bn254::{g1::G1Affine, Fr};
124 use ark_ec::CurveGroup;
125 use std::ops::Mul;
126
127 #[test]
128 fn test_pedersen() {
129 let mut rng = ark_std::test_rng();
130
131 // setup params
132 let params = Pedersen::<G1Affine>::new_params(&mut rng);
133
134 // init Prover's transcript
135 let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
136 // init Verifier's transcript
137 let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
138
139 let v = Fr::rand(&mut rng);
140
141 let cm = Pedersen::commit_elem(&mut rng, ¶ms, &v);
142 let proof = cm.prove(¶ms, &mut transcript_p, v);
143 // also can use:
144 // let proof = Pedersen::prove(¶ms, &mut transcript_p, cm.cm, v, cm.r);
145 let v = Pedersen::verify(¶ms, &mut transcript_v, cm.cm, proof);
146 assert!(v);
147 }
148}