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