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/// CommitmentScheme defines the vector commitment scheme trait. Where `H` indicates if to use the
 13/// commitment in hiding mode or not.
 14pub trait CommitmentScheme<C: CurveGroup, const H: bool = false>: Clone + Debug {
 15    type ProverParams: Clone + Debug;
 16    type VerifierParams: Clone + Debug;
 17    type Proof: Clone + Debug;
 18    type ProverChallenge: Clone + Debug;
 19    type Challenge: Clone + Debug;
 20
 21    fn is_hiding() -> bool;
 22
 23    fn setup(
 24        rng: impl RngCore,
 25        len: usize,
 26    ) -> Result<(Self::ProverParams, Self::VerifierParams), Error>;
 27
 28    fn commit(
 29        params: &Self::ProverParams,
 30        v: &[C::ScalarField],
 31        blind: &C::ScalarField,
 32    ) -> Result<C, Error>;
 33
 34    fn prove(
 35        params: &Self::ProverParams,
 36        transcript: &mut impl Transcript<C>,
 37        cm: &C,
 38        v: &[C::ScalarField],
 39        blind: &C::ScalarField,
 40        rng: Option<&mut dyn RngCore>,
 41    ) -> Result<Self::Proof, Error>;
 42
 43    /// same as `prove` but instead of providing a Transcript to use, providing the already
 44    /// computed challenge
 45    fn prove_with_challenge(
 46        params: &Self::ProverParams,
 47        challenge: Self::ProverChallenge,
 48        v: &[C::ScalarField],
 49        blind: &C::ScalarField,
 50        rng: Option<&mut dyn RngCore>,
 51    ) -> Result<Self::Proof, Error>;
 52
 53    fn verify(
 54        params: &Self::VerifierParams,
 55        transcript: &mut impl Transcript<C>,
 56        cm: &C,
 57        proof: &Self::Proof,
 58    ) -> Result<(), Error>;
 59
 60    /// same as `verify` but instead of providing a Transcript to use, providing the already
 61    /// computed challenge
 62    fn verify_with_challenge(
 63        params: &Self::VerifierParams,
 64        challenge: Self::Challenge,
 65        cm: &C,
 66        proof: &Self::Proof,
 67    ) -> Result<(), Error>;
 68}
 69
 70#[cfg(test)]
 71mod tests {
 72    use super::*;
 73    use ark_bn254::{Bn254, Fr, G1Projective as G1};
 74    use ark_crypto_primitives::sponge::{poseidon::PoseidonConfig, Absorb};
 75    use ark_poly_commit::kzg10::VerifierKey;
 76    use ark_std::Zero;
 77    use ark_std::{test_rng, UniformRand};
 78
 79    use super::ipa::IPA;
 80    use super::kzg::{ProverKey, KZG};
 81    use super::pedersen::Pedersen;
 82    use crate::transcript::{
 83        poseidon::{poseidon_canonical_config, PoseidonTranscript},
 84        Transcript,
 85    };
 86
 87    #[test]
 88    fn test_homomorphic_property_using_Commitment_trait() {
 89        let mut rng = &mut test_rng();
 90        let poseidon_config = poseidon_canonical_config::<Fr>();
 91        let n: usize = 128;
 92
 93        // set random vector for the test
 94        let v_1: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect();
 95        let v_2: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect();
 96        // set a random challenge for the random linear combination
 97        let r = Fr::rand(rng);
 98
 99        // setup params for Pedersen & KZG
100        let (pedersen_params, _) = Pedersen::<G1>::setup(&mut rng, n).unwrap();
101        let (kzg_pk, kzg_vk): (ProverKey<G1>, VerifierKey<Bn254>) =
102            KZG::<Bn254>::setup(rng, n).unwrap();
103
104        // test with Pedersen
105        test_homomorphic_property_using_Commitment_trait_opt::<G1, Pedersen<G1>>(
106            &poseidon_config,
107            &pedersen_params,
108            &pedersen_params,
109            r,
110            &v_1,
111            &v_2,
112        );
113        // test with IPA
114        test_homomorphic_property_using_Commitment_trait_opt::<G1, IPA<G1>>(
115            &poseidon_config,
116            &pedersen_params,
117            &pedersen_params,
118            r,
119            &v_1,
120            &v_2,
121        );
122        // test with KZG
123        test_homomorphic_property_using_Commitment_trait_opt::<G1, KZG<Bn254>>(
124            &poseidon_config,
125            &kzg_pk,
126            &kzg_vk,
127            r,
128            &v_1,
129            &v_2,
130        );
131    }
132
133    fn test_homomorphic_property_using_Commitment_trait_opt<
134        C: CurveGroup,
135        CS: CommitmentScheme<C>,
136    >(
137        poseidon_config: &PoseidonConfig<C::ScalarField>,
138        prover_params: &CS::ProverParams,
139        verifier_params: &CS::VerifierParams,
140        r: C::ScalarField,
141        v_1: &[C::ScalarField],
142        v_2: &[C::ScalarField],
143    ) where
144        <C as ark_ec::Group>::ScalarField: Absorb,
145    {
146        // compute the commitment of the two vectors using the given CommitmentScheme
147        let cm_1 = CS::commit(prover_params, v_1, &C::ScalarField::zero()).unwrap();
148        let cm_2 = CS::commit(prover_params, v_2, &C::ScalarField::zero()).unwrap();
149
150        // random linear combination of the commitments and their witnesses (vectors v_i)
151        let cm_3 = cm_1 + cm_2.mul(r);
152        let v_3: Vec<C::ScalarField> = v_1.iter().zip(v_2).map(|(a, b)| *a + (r * b)).collect();
153
154        // compute the proof of the cm_3
155        let transcript_p = &mut PoseidonTranscript::<C>::new(poseidon_config);
156        let proof = CS::prove(
157            prover_params,
158            transcript_p,
159            &cm_3,
160            &v_3,
161            &C::ScalarField::zero(),
162            None,
163        )
164        .unwrap();
165
166        // verify the opening proof
167        let transcript_v = &mut PoseidonTranscript::<C>::new(poseidon_config);
168        CS::verify(verifier_params, transcript_v, &cm_3, &proof).unwrap();
169    }
170}