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