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