arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/commitment/mod.rs
folding-schemes/src/commitment/mod.rsRaw
  1use ark_ec::CurveGroup;
  2use ark_std::fmt::Debug;
  3use ark_std::rand::RngCore;
  4
  5use crate::transcript::Transcript;
  6use crate::Error;
  7
  8pub mod ipa;
  9pub mod kzg;
 10pub mod pedersen;
 11
 12/// CommitmentProver defines the vector commitment scheme prover trait. Where `H` indicates if to
 13/// use the commitment in hiding mode or not.
 14pub trait CommitmentProver<C: CurveGroup, const H: bool = false>: Clone + Debug {
 15    type Params: Clone + Debug;
 16    type Proof: Clone + Debug;
 17
 18    fn commit(
 19        params: &Self::Params,
 20        v: &[C::ScalarField],
 21        blind: &C::ScalarField,
 22    ) -> Result<C, Error>;
 23    fn prove(
 24        params: &Self::Params,
 25        transcript: &mut impl Transcript<C>,
 26        cm: &C,
 27        v: &[C::ScalarField],
 28        blind: &C::ScalarField,
 29        rng: Option<&mut dyn RngCore>,
 30    ) -> Result<Self::Proof, Error>;
 31}
 32
 33#[cfg(test)]
 34mod tests {
 35    use super::*;
 36    use ark_bn254::{Bn254, Fr, G1Projective as G1};
 37    use ark_crypto_primitives::sponge::{poseidon::PoseidonConfig, Absorb};
 38    use ark_poly::univariate::DensePolynomial;
 39    use ark_poly_commit::kzg10::{
 40        Commitment as KZG10Commitment, Proof as KZG10Proof, VerifierKey, KZG10,
 41    };
 42    use ark_std::Zero;
 43    use ark_std::{test_rng, UniformRand};
 44
 45    use super::kzg::{KZGProver, KZGSetup, ProverKey};
 46    use super::pedersen::Pedersen;
 47    use crate::transcript::{
 48        poseidon::{poseidon_test_config, PoseidonTranscript},
 49        Transcript,
 50    };
 51
 52    // Computes the commitment of the two vectors using the given CommitmentProver, then computes
 53    // their random linear combination, and returns it together with the proof of it.
 54    fn commit_rlc_and_prove<C: CurveGroup, CP: CommitmentProver<C>>(
 55        poseidon_config: &PoseidonConfig<C::ScalarField>,
 56        params: &CP::Params,
 57        r: C::ScalarField,
 58        v_1: &[C::ScalarField],
 59        v_2: &[C::ScalarField],
 60    ) -> Result<(C, CP::Proof), Error>
 61    where
 62        <C as ark_ec::Group>::ScalarField: Absorb,
 63    {
 64        let cm_1 = CP::commit(params, v_1, &C::ScalarField::zero())?;
 65        let cm_2 = CP::commit(params, v_2, &C::ScalarField::zero())?;
 66
 67        // random linear combination of the commitment and the witness (vector v)
 68        let cm_3 = cm_1 + cm_2.mul(r);
 69        let v_3: Vec<C::ScalarField> = v_1.iter().zip(v_2).map(|(a, b)| *a + (r * b)).collect();
 70
 71        let transcript = &mut PoseidonTranscript::<C>::new(poseidon_config);
 72        let proof = CP::prove(
 73            params,
 74            transcript,
 75            &cm_3,
 76            &v_3,
 77            &C::ScalarField::zero(),
 78            None,
 79        )
 80        .unwrap();
 81
 82        Ok((cm_3, proof))
 83    }
 84
 85    #[test]
 86    fn test_homomorphic_property_using_CommitmentProver_trait() {
 87        let rng = &mut test_rng();
 88        let poseidon_config = poseidon_test_config::<Fr>();
 89        let n: usize = 100;
 90
 91        // set random vector for the test
 92        let v_1: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect();
 93        let v_2: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect();
 94        // set a random challenge for the random linear combination
 95        let r = Fr::rand(rng);
 96
 97        // setup params for Pedersen & KZG
 98        let pedersen_params = Pedersen::<G1>::new_params(rng, n);
 99        let (kzg_pk, kzg_vk): (ProverKey<G1>, VerifierKey<Bn254>) =
100            KZGSetup::<Bn254>::setup(rng, n);
101
102        // Pedersen commit the two vectors and return their random linear combination and proof
103        let (pedersen_cm, pedersen_proof) = commit_rlc_and_prove::<G1, Pedersen<G1>>(
104            &poseidon_config,
105            &pedersen_params,
106            r,
107            &v_1,
108            &v_2,
109        )
110        .unwrap();
111
112        // KZG commit the two vectors and return their random linear combination and proof
113        let (kzg_cm, kzg_proof) =
114            commit_rlc_and_prove::<G1, KZGProver<G1>>(&poseidon_config, &kzg_pk, r, &v_1, &v_2)
115                .unwrap();
116
117        // verify Pedersen
118        let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
119        Pedersen::<G1>::verify(&pedersen_params, transcript_v, pedersen_cm, pedersen_proof)
120            .unwrap();
121
122        // verify KZG
123        let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
124        transcript_v.absorb_point(&kzg_cm).unwrap();
125        let challenge = transcript_v.get_challenge();
126        // verify the KZG proof using arkworks method
127        assert!(KZG10::<Bn254, DensePolynomial<Fr>>::check(
128            &kzg_vk,
129            &KZG10Commitment(kzg_cm.into_affine()),
130            challenge,
131            kzg_proof.0, // eval
132            &KZG10Proof::<Bn254> {
133                w: kzg_proof.1.into_affine(), // proof
134                random_v: None,
135            },
136        )
137        .unwrap());
138    }
139}