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