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/// CommitmentProver defines the vector commitment scheme prover trait. Where `H` indicates if to
13/// use the commitment in hiding mode or not.
14pub trait CommitmentProver<C: CurveGroup, const H: bool = false>: Clone + Debug {
15 type Params: Clone + Debug;
16 type Proof: Clone + Debug;
17
18 fn commit(
19 params: &Self::Params,
20 v: &[C::ScalarField],
21 blind: &C::ScalarField,
22 ) -> Result<C, Error>;
23 fn prove(
24 params: &Self::Params,
25 transcript: &mut impl Transcript<C>,
26 cm: &C,
27 v: &[C::ScalarField],
28 blind: &C::ScalarField,
29 rng: Option<&mut dyn RngCore>,
30 ) -> Result<Self::Proof, Error>;
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use ark_bn254::{Bn254, Fr, G1Projective as G1};
37 use ark_crypto_primitives::sponge::{poseidon::PoseidonConfig, Absorb};
38 use ark_poly::univariate::DensePolynomial;
39 use ark_poly_commit::kzg10::{
40 Commitment as KZG10Commitment, Proof as KZG10Proof, VerifierKey, KZG10,
41 };
42 use ark_std::Zero;
43 use ark_std::{test_rng, UniformRand};
44
45 use super::kzg::{KZGProver, KZGSetup, ProverKey};
46 use super::pedersen::Pedersen;
47 use crate::transcript::{
48 poseidon::{poseidon_test_config, PoseidonTranscript},
49 Transcript,
50 };
51
52 // Computes the commitment of the two vectors using the given CommitmentProver, then computes
53 // their random linear combination, and returns it together with the proof of it.
54 fn commit_rlc_and_prove<C: CurveGroup, CP: CommitmentProver<C>>(
55 poseidon_config: &PoseidonConfig<C::ScalarField>,
56 params: &CP::Params,
57 r: C::ScalarField,
58 v_1: &[C::ScalarField],
59 v_2: &[C::ScalarField],
60 ) -> Result<(C, CP::Proof), Error>
61 where
62 <C as ark_ec::Group>::ScalarField: Absorb,
63 {
64 let cm_1 = CP::commit(params, v_1, &C::ScalarField::zero())?;
65 let cm_2 = CP::commit(params, v_2, &C::ScalarField::zero())?;
66
67 // random linear combination of the commitment and the witness (vector v)
68 let cm_3 = cm_1 + cm_2.mul(r);
69 let v_3: Vec<C::ScalarField> = v_1.iter().zip(v_2).map(|(a, b)| *a + (r * b)).collect();
70
71 let transcript = &mut PoseidonTranscript::<C>::new(poseidon_config);
72 let proof = CP::prove(
73 params,
74 transcript,
75 &cm_3,
76 &v_3,
77 &C::ScalarField::zero(),
78 None,
79 )
80 .unwrap();
81
82 Ok((cm_3, proof))
83 }
84
85 #[test]
86 fn test_homomorphic_property_using_CommitmentProver_trait() {
87 let rng = &mut test_rng();
88 let poseidon_config = poseidon_test_config::<Fr>();
89 let n: usize = 100;
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>::new_params(rng, n);
99 let (kzg_pk, kzg_vk): (ProverKey<G1>, VerifierKey<Bn254>) =
100 KZGSetup::<Bn254>::setup(rng, n);
101
102 // Pedersen commit the two vectors and return their random linear combination and proof
103 let (pedersen_cm, pedersen_proof) = commit_rlc_and_prove::<G1, Pedersen<G1>>(
104 &poseidon_config,
105 &pedersen_params,
106 r,
107 &v_1,
108 &v_2,
109 )
110 .unwrap();
111
112 // KZG commit the two vectors and return their random linear combination and proof
113 let (kzg_cm, kzg_proof) =
114 commit_rlc_and_prove::<G1, KZGProver<G1>>(&poseidon_config, &kzg_pk, r, &v_1, &v_2)
115 .unwrap();
116
117 // verify Pedersen
118 let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
119 Pedersen::<G1>::verify(&pedersen_params, transcript_v, pedersen_cm, pedersen_proof)
120 .unwrap();
121
122 // verify KZG
123 let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
124 transcript_v.absorb_point(&kzg_cm).unwrap();
125 let challenge = transcript_v.get_challenge();
126 // verify the KZG proof using arkworks method
127 assert!(KZG10::<Bn254, DensePolynomial<Fr>>::check(
128 &kzg_vk,
129 &KZG10Commitment(kzg_cm.into_affine()),
130 challenge,
131 kzg_proof.0, // eval
132 &KZG10Proof::<Bn254> {
133 w: kzg_proof.1.into_affine(), // proof
134 random_v: None,
135 },
136 )
137 .unwrap());
138 }
139}