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}