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}