arnaucube
arnaucube/protogalaxy-pocPublic Self-hosted repository
protogalaxy-poc/src/pedersen.rs
src/pedersen.rsRaw
  1/// pedersen.rs file adapted from https://github.com/arnaucube/nova-study
  2use ark_ec::{CurveGroup, Group};
  3use ark_std::{rand::Rng, UniformRand};
  4use std::marker::PhantomData;
  5
  6use crate::utils::{vec_add, vec_scalar_mul};
  7
  8use crate::transcript::Transcript;
  9use ark_crypto_primitives::sponge::Absorb;
 10
 11pub struct Proof<C: CurveGroup> {
 12    R: C,
 13    u_: Vec<C::ScalarField>,
 14    ru_: C::ScalarField,
 15}
 16
 17pub struct Params<C: CurveGroup> {
 18    h: C,
 19    pub generators: Vec<C::Affine>,
 20}
 21
 22pub struct Pedersen<C: CurveGroup>
 23where
 24    <C as Group>::ScalarField: Absorb,
 25    <C as CurveGroup>::BaseField: Absorb,
 26{
 27    _c: PhantomData<C>,
 28}
 29
 30impl<C: CurveGroup> Pedersen<C>
 31where
 32    <C as Group>::ScalarField: Absorb,
 33    <C as CurveGroup>::BaseField: Absorb,
 34{
 35    pub fn new_params<R: Rng>(rng: &mut R, max: usize) -> Params<C> {
 36        let h_scalar = C::ScalarField::rand(rng);
 37        let g: C = C::generator();
 38        let generators: Vec<C::Affine> = vec![C::Affine::rand(rng); max];
 39        let params: Params<C> = Params::<C> {
 40            h: g.mul(h_scalar),
 41            generators,
 42        };
 43        params
 44    }
 45
 46    pub fn commit(
 47        params: &Params<C>,
 48        v: &Vec<C::ScalarField>,
 49        r: &C::ScalarField, // random value is provided, in order to be choosen by other parts of the protocol
 50    ) -> Commitment<C> {
 51        let cm = params.h.mul(r) + C::msm(&params.generators[..v.len()], v).unwrap();
 52        Commitment::<C>(cm)
 53    }
 54
 55    pub fn prove(
 56        params: &Params<C>,
 57        transcript: &mut Transcript<C::ScalarField, C>,
 58        cm: &Commitment<C>, // TODO maybe it makes sense to not have a type wrapper and use directly C
 59        v: &Vec<C::ScalarField>,
 60        r: &C::ScalarField,
 61    ) -> Proof<C> {
 62        let r1 = transcript.get_challenge();
 63        let d = transcript.get_challenge_vec(v.len());
 64
 65        let R: C = params.h.mul(r1) + C::msm(&params.generators, &d).unwrap();
 66
 67        transcript.add_point(&cm.0);
 68        transcript.add_point(&R);
 69        let e = transcript.get_challenge();
 70
 71        let u_ = vec_add(&vec_scalar_mul(v, &e), &d);
 72        let ru_ = e * r + r1;
 73
 74        Proof::<C> { R, u_, ru_ }
 75    }
 76    pub fn verify(
 77        params: &Params<C>,
 78        transcript: &mut Transcript<C::ScalarField, C>,
 79        cm: Commitment<C>,
 80        proof: Proof<C>,
 81    ) -> bool {
 82        // r1, d just to match Prover's transcript
 83        transcript.get_challenge(); // r_1
 84        transcript.get_challenge_vec(proof.u_.len()); // d
 85
 86        transcript.add_point(&cm.0);
 87        transcript.add_point(&proof.R);
 88        let e = transcript.get_challenge();
 89        let lhs = proof.R + cm.0.mul(e);
 90        let rhs = params.h.mul(proof.ru_) + C::msm(&params.generators, &proof.u_).unwrap();
 91        if lhs != rhs {
 92            return false;
 93        }
 94        true
 95    }
 96}
 97
 98#[derive(Clone, Debug)]
 99pub struct Commitment<C: CurveGroup>(pub C);
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use crate::transcript::poseidon_test_config;
105    use ark_bls12_381::{Fr, G1Projective};
106
107    #[test]
108    fn test_pedersen_vector() {
109        let mut rng = ark_std::test_rng();
110
111        const n: usize = 10;
112        // setup params
113        let params = Pedersen::<G1Projective>::new_params(&mut rng, n);
114        let poseidon_config = poseidon_test_config::<Fr>();
115
116        // init Prover's transcript
117        let mut transcript_p = Transcript::<Fr, G1Projective>::new(&poseidon_config);
118        // init Verifier's transcript
119        let mut transcript_v = Transcript::<Fr, G1Projective>::new(&poseidon_config);
120
121        let v: Vec<Fr> = vec![Fr::rand(&mut rng); n];
122        let r: Fr = Fr::rand(&mut rng);
123        let cm = Pedersen::commit(&params, &v, &r);
124        let proof = Pedersen::prove(&params, &mut transcript_p, &cm, &v, &r);
125        let v = Pedersen::verify(&params, &mut transcript_v, cm, proof);
126        assert!(v);
127    }
128}