sonobe/src/pedersen.rs
src/pedersen.rsRaw
1use ark_ec::CurveGroup;
2use ark_std::{rand::Rng, UniformRand};
3use std::marker::PhantomData;
4
5use crate::utils::vec::{vec_add, vec_scalar_mul};
6
7use crate::transcript::Transcript;
8
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub struct Proof<C: CurveGroup> {
11 R: C,
12 u: Vec<C::ScalarField>,
13 r_u: C::ScalarField,
14}
15
16#[derive(Debug, Clone, Eq, PartialEq)]
17pub struct Params<C: CurveGroup> {
18 h: C,
19 pub generators: Vec<C::Affine>,
20}
21
22#[derive(Debug, Clone, Eq, PartialEq)]
23pub struct Pedersen<C: CurveGroup> {
24 _c: PhantomData<C>,
25}
26
27impl<C: CurveGroup> Pedersen<C> {
28 pub fn new_params<R: Rng>(rng: &mut R, max: usize) -> Params<C> {
29 let generators: Vec<C::Affine> = std::iter::repeat_with(|| C::Affine::rand(rng))
30 .take(max.next_power_of_two())
31 .collect();
32 let params: Params<C> = Params::<C> {
33 h: C::rand(rng),
34 generators,
35 };
36 params
37 }
38
39 pub fn commit(params: &Params<C>, v: &Vec<C::ScalarField>, r: &C::ScalarField) -> C {
40 // h⋅r + <g, v>
41 params.h.mul(r) + C::msm(¶ms.generators[..v.len()], v).unwrap()
42 }
43
44 pub fn prove(
45 params: &Params<C>,
46 transcript: &mut impl Transcript<C>,
47 cm: &C,
48 v: &Vec<C::ScalarField>,
49 r: &C::ScalarField,
50 ) -> Proof<C> {
51 transcript.absorb_point(cm);
52 let r1 = transcript.get_challenge();
53 let d = transcript.get_challenges(v.len());
54
55 // R = h⋅r_1 + <g, d>
56 let R: C = params.h.mul(r1) + C::msm(¶ms.generators[..d.len()], &d).unwrap();
57
58 transcript.absorb_point(&R);
59 let e = transcript.get_challenge();
60
61 // u = d + v⋅e
62 let u = vec_add(&vec_scalar_mul(v, &e), &d);
63 // r_u = e⋅r + r_1
64 let r_u = e * r + r1;
65
66 Proof::<C> { R, u, r_u }
67 }
68
69 pub fn verify(
70 params: &Params<C>,
71 transcript: &mut impl Transcript<C>,
72 cm: C,
73 proof: Proof<C>,
74 ) -> bool {
75 transcript.absorb_point(&cm);
76 transcript.get_challenge(); // r_1
77 transcript.get_challenges(proof.u.len()); // d
78 transcript.absorb_point(&proof.R);
79 let e = transcript.get_challenge();
80
81 // check that: R + cm == h⋅r_u + <g, u>
82 let lhs = proof.R + cm.mul(e);
83 let rhs = params.h.mul(proof.r_u)
84 + C::msm(¶ms.generators[..proof.u.len()], &proof.u).unwrap();
85 if lhs != rhs {
86 return false;
87 }
88 true
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use crate::transcript::poseidon::{tests::poseidon_test_config, PoseidonTranscript};
96
97 use ark_pallas::{Fr, Projective};
98
99 #[test]
100 fn test_pedersen_vector() {
101 let mut rng = ark_std::test_rng();
102
103 const n: usize = 10;
104 // setup params
105 let params = Pedersen::<Projective>::new_params(&mut rng, n);
106 let poseidon_config = poseidon_test_config::<Fr>();
107
108 // init Prover's transcript
109 let mut transcript_p = PoseidonTranscript::<Projective>::new(&poseidon_config);
110 // init Verifier's transcript
111 let mut transcript_v = PoseidonTranscript::<Projective>::new(&poseidon_config);
112
113 let v: Vec<Fr> = vec![Fr::rand(&mut rng); n];
114 let r: Fr = Fr::rand(&mut rng);
115 let cm = Pedersen::<Projective>::commit(¶ms, &v, &r);
116 let proof = Pedersen::<Projective>::prove(¶ms, &mut transcript_p, &cm, &v, &r);
117 let v = Pedersen::<Projective>::verify(¶ms, &mut transcript_v, cm, proof);
118 assert!(v);
119 }
120}