use ark_ec::AffineRepr; use ark_std::{rand::RngCore, UniformRand}; use std::marker::PhantomData; use crate::transcript::Transcript; pub struct Proof { R: C, t1: C::ScalarField, t2: C::ScalarField, } pub struct Params { g: C, h: C, } pub struct Pedersen { _phantom: PhantomData, } impl Pedersen { pub fn commit( rng: &mut R, params: &Params, v: &C::ScalarField, ) -> (C, C::ScalarField) { let r = C::ScalarField::rand(rng); let cm: C = (params.g.mul(v) + params.h.mul(r)).into(); (cm, r) } pub fn prove( params: &Params, transcript: &mut Transcript, cm: C, v: C::ScalarField, r: C::ScalarField, ) -> Proof { let s1 = transcript.get_challenge(b"s_1"); let s2 = transcript.get_challenge(b"s_2"); let R: C = (params.g.mul(s1) + params.h.mul(s2)).into(); transcript.add(b"cm", &cm); transcript.add(b"R", &R); let c = transcript.get_challenge(b"c"); let t1 = s1 + v * c; let t2 = s2 + r * c; Proof:: { R, t1, t2 } } pub fn verify( params: &Params, transcript: &mut Transcript, cm: C, proof: Proof, ) -> bool { // s1, s2 just to match Prover's transcript transcript.get_challenge(b"s_1"); transcript.get_challenge(b"s_2"); transcript.add(b"cm", &cm); transcript.add(b"R", &proof.R); let c = transcript.get_challenge(b"c"); let lhs = proof.R + cm.mul(c); let rhs = params.g.mul(proof.t1) + params.h.mul(proof.t2); if lhs != rhs { return false; } true } } pub struct Commitment { pub cm: C, pub r: C::ScalarField, } impl Commitment { pub fn prove( self, params: &Params, transcript: &mut Transcript, v: C::ScalarField, ) -> Proof { Pedersen::::prove(params, transcript, self.cm, v, self.r) } } #[cfg(test)] mod tests { use super::*; use ark_bn254::{g1::G1Affine, Fr}; use ark_ec::CurveGroup; use std::ops::Mul; #[test] fn test_pedersen() { let mut rng = ark_std::test_rng(); // setup params let h_scalar = Fr::rand(&mut rng); let g: G1Affine = G1Affine::generator(); let params: Params = Params:: { g, h: g.mul(h_scalar).into_affine(), }; // init Prover's transcript let mut transcript_p: Transcript = Transcript::::new(); // init Verifier's transcript let mut transcript_v: Transcript = Transcript::::new(); let v = Fr::rand(&mut rng); let (cm, r) = Pedersen::commit(&mut rng, ¶ms, &v); let proof = Pedersen::prove(¶ms, &mut transcript_p, cm, v, r); let v = Pedersen::verify(¶ms, &mut transcript_v, cm, proof); assert!(v); } }