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