arnaucube
arnaucube/nova-studyPublic Self-hosted repository
nova-study/src/pedersen.rs
src/pedersen.rsRaw
  1use ark_ec::AffineRepr;
  2use ark_std::{rand::RngCore, UniformRand};
  3use std::marker::PhantomData;
  4
  5use crate::transcript::Transcript;
  6
  7pub struct Proof<C: AffineRepr> {
  8    R: C,
  9    t1: C::ScalarField,
 10    t2: C::ScalarField,
 11}
 12
 13pub struct Params<C: AffineRepr> {
 14    g: C,
 15    h: C,
 16}
 17
 18pub struct Pedersen<C: AffineRepr> {
 19    _phantom: PhantomData<C>,
 20}
 21
 22impl<C: AffineRepr> Pedersen<C> {
 23    pub fn commit<R: RngCore>(
 24        rng: &mut R,
 25        params: &Params<C>,
 26        v: &C::ScalarField,
 27    ) -> (C, C::ScalarField) {
 28        let r = C::ScalarField::rand(rng);
 29        let cm: C = (params.g.mul(v) + params.h.mul(r)).into();
 30        (cm, r)
 31    }
 32    pub fn prove(
 33        params: &Params<C>,
 34        transcript: &mut Transcript<C::ScalarField>,
 35        cm: C,
 36        v: C::ScalarField,
 37        r: C::ScalarField,
 38    ) -> Proof<C> {
 39        let s1 = transcript.get_challenge(b"s_1");
 40        let s2 = transcript.get_challenge(b"s_2");
 41
 42        let R: C = (params.g.mul(s1) + params.h.mul(s2)).into();
 43
 44        transcript.add(b"cm", &cm);
 45        transcript.add(b"R", &R);
 46        let c = transcript.get_challenge(b"c");
 47
 48        let t1 = s1 + v * c;
 49        let t2 = s2 + r * c;
 50
 51        Proof::<C> { R, t1, t2 }
 52    }
 53
 54    pub fn verify(
 55        params: &Params<C>,
 56        transcript: &mut Transcript<C::ScalarField>,
 57        cm: C,
 58        proof: Proof<C>,
 59    ) -> bool {
 60        // s1, s2 just to match Prover's transcript
 61        transcript.get_challenge(b"s_1");
 62        transcript.get_challenge(b"s_2");
 63
 64        transcript.add(b"cm", &cm);
 65        transcript.add(b"R", &proof.R);
 66        let c = transcript.get_challenge(b"c");
 67        let lhs = proof.R + cm.mul(c);
 68        let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2);
 69        if lhs != rhs {
 70            return false;
 71        }
 72        true
 73    }
 74}
 75
 76pub struct Commitment<C: AffineRepr> {
 77    pub cm: C,
 78    pub r: C::ScalarField,
 79}
 80impl<C: AffineRepr> Commitment<C> {
 81    pub fn prove(
 82        self,
 83        params: &Params<C>,
 84        transcript: &mut Transcript<C::ScalarField>,
 85        v: C::ScalarField,
 86    ) -> Proof<C> {
 87        Pedersen::<C>::prove(params, transcript, self.cm, v, self.r)
 88    }
 89}
 90
 91#[cfg(test)]
 92mod tests {
 93    use super::*;
 94    use ark_bn254::{g1::G1Affine, Fr};
 95    use ark_ec::CurveGroup;
 96    use std::ops::Mul;
 97
 98    #[test]
 99    fn test_pedersen() {
100        let mut rng = ark_std::test_rng();
101
102        // setup params
103        let h_scalar = Fr::rand(&mut rng);
104        let g: G1Affine = G1Affine::generator();
105        let params: Params<G1Affine> = Params::<G1Affine> {
106            g,
107            h: g.mul(h_scalar).into_affine(),
108        };
109
110        // init Prover's transcript
111        let mut transcript_p: Transcript<Fr> = Transcript::<Fr>::new();
112        // init Verifier's transcript
113        let mut transcript_v: Transcript<Fr> = Transcript::<Fr>::new();
114
115        let v = Fr::rand(&mut rng);
116
117        let (cm, r) = Pedersen::commit(&mut rng, &params, &v);
118        let proof = Pedersen::prove(&params, &mut transcript_p, cm, v, r);
119        let v = Pedersen::verify(&params, &mut transcript_v, cm, proof);
120        assert!(v);
121    }
122}