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