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}
 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, &params, &v);
142        let proof = cm.prove(&params, &mut transcript_p, v);
143        // also can use:
144        // let proof = Pedersen::prove(&params, &mut transcript_p, cm.cm, v, cm.r);
145        let v = Pedersen::verify(&params, &mut transcript_v, cm.cm, proof);
146        assert!(v);
147    }
148}