mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-02-02 17:26:44 +01:00
Compute Decider's CM challenges in Groth16 circuit, link G16 & KZG proofs in Onchain Decider, refactor CommitmentScheme trait (#79)
* Compute Decider's CM challenges in Groth16 circuit, link G16 & KZG proofs in Onchain Decider, refactor CommitmentScheme trait - Refactor commitment package - Refactor `Commitment` trait and the kzg, ipa, pedersen impls - Add methods to prove & verify given challenges (not computing them in-method) - Add KZG challenges computation in decider_eth_circuit - Add cmE & cmW KZG proving & verification in DeciderEth - Link Decider's Groth16 proof & KZG proofs data - Fix point to bytes arkworks inconsistency - Patch ark_curves to use a cherry-picked version with bn254::constraints & grumpkin for v0.4.0 (once arkworks v0.5.0 is released this will no longer be needed) * DeciderEthCircuit: Add check eval=p(c) for E & W The check is temporary disabled due https://github.com/privacy-scaling-explorations/folding-schemes/issues/80, but the public inputs and logic are there, to be able to continue the other parts development while issue #80 is solved.
This commit is contained in:
@@ -9,25 +9,60 @@ pub mod ipa;
|
||||
pub mod kzg;
|
||||
pub mod pedersen;
|
||||
|
||||
/// CommitmentProver defines the vector commitment scheme prover trait. Where `H` indicates if to
|
||||
/// use the commitment in hiding mode or not.
|
||||
pub trait CommitmentProver<C: CurveGroup, const H: bool = false>: Clone + Debug {
|
||||
type Params: Clone + Debug;
|
||||
/// CommitmentScheme defines the vector commitment scheme trait. Where `H` indicates if to use the
|
||||
/// commitment in hiding mode or not.
|
||||
pub trait CommitmentScheme<C: CurveGroup, const H: bool = false>: Clone + Debug {
|
||||
type ProverParams: Clone + Debug;
|
||||
type VerifierParams: Clone + Debug;
|
||||
type Proof: Clone + Debug;
|
||||
type ProverChallenge: Clone + Debug;
|
||||
type Challenge: Clone + Debug;
|
||||
|
||||
fn setup(
|
||||
rng: impl RngCore,
|
||||
len: usize,
|
||||
) -> Result<(Self::ProverParams, Self::VerifierParams), Error>;
|
||||
|
||||
fn commit(
|
||||
params: &Self::Params,
|
||||
params: &Self::ProverParams,
|
||||
v: &[C::ScalarField],
|
||||
blind: &C::ScalarField,
|
||||
) -> Result<C, Error>;
|
||||
|
||||
fn prove(
|
||||
params: &Self::Params,
|
||||
params: &Self::ProverParams,
|
||||
transcript: &mut impl Transcript<C>,
|
||||
cm: &C,
|
||||
v: &[C::ScalarField],
|
||||
blind: &C::ScalarField,
|
||||
rng: Option<&mut dyn RngCore>,
|
||||
) -> Result<Self::Proof, Error>;
|
||||
|
||||
/// same as `prove` but instead of providing a Transcript to use, providing the already
|
||||
/// computed challenge
|
||||
fn prove_with_challenge(
|
||||
params: &Self::ProverParams,
|
||||
challenge: Self::ProverChallenge,
|
||||
v: &[C::ScalarField],
|
||||
blind: &C::ScalarField,
|
||||
rng: Option<&mut dyn RngCore>,
|
||||
) -> Result<Self::Proof, Error>;
|
||||
|
||||
fn verify(
|
||||
params: &Self::VerifierParams,
|
||||
transcript: &mut impl Transcript<C>,
|
||||
cm: &C,
|
||||
proof: &Self::Proof,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
/// same as `verify` but instead of providing a Transcript to use, providing the already
|
||||
/// computed challenge
|
||||
fn verify_with_challenge(
|
||||
params: &Self::VerifierParams,
|
||||
challenge: Self::Challenge,
|
||||
cm: &C,
|
||||
proof: &Self::Proof,
|
||||
) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -35,58 +70,23 @@ mod tests {
|
||||
use super::*;
|
||||
use ark_bn254::{Bn254, Fr, G1Projective as G1};
|
||||
use ark_crypto_primitives::sponge::{poseidon::PoseidonConfig, Absorb};
|
||||
use ark_poly::univariate::DensePolynomial;
|
||||
use ark_poly_commit::kzg10::{
|
||||
Commitment as KZG10Commitment, Proof as KZG10Proof, VerifierKey, KZG10,
|
||||
};
|
||||
use ark_poly_commit::kzg10::VerifierKey;
|
||||
use ark_std::Zero;
|
||||
use ark_std::{test_rng, UniformRand};
|
||||
|
||||
use super::kzg::{KZGProver, KZGSetup, ProverKey};
|
||||
use super::ipa::IPA;
|
||||
use super::kzg::{ProverKey, KZG};
|
||||
use super::pedersen::Pedersen;
|
||||
use crate::transcript::{
|
||||
poseidon::{poseidon_test_config, PoseidonTranscript},
|
||||
Transcript,
|
||||
};
|
||||
|
||||
// Computes the commitment of the two vectors using the given CommitmentProver, then computes
|
||||
// their random linear combination, and returns it together with the proof of it.
|
||||
fn commit_rlc_and_prove<C: CurveGroup, CP: CommitmentProver<C>>(
|
||||
poseidon_config: &PoseidonConfig<C::ScalarField>,
|
||||
params: &CP::Params,
|
||||
r: C::ScalarField,
|
||||
v_1: &[C::ScalarField],
|
||||
v_2: &[C::ScalarField],
|
||||
) -> Result<(C, CP::Proof), Error>
|
||||
where
|
||||
<C as ark_ec::Group>::ScalarField: Absorb,
|
||||
{
|
||||
let cm_1 = CP::commit(params, v_1, &C::ScalarField::zero())?;
|
||||
let cm_2 = CP::commit(params, v_2, &C::ScalarField::zero())?;
|
||||
|
||||
// random linear combination of the commitment and the witness (vector v)
|
||||
let cm_3 = cm_1 + cm_2.mul(r);
|
||||
let v_3: Vec<C::ScalarField> = v_1.iter().zip(v_2).map(|(a, b)| *a + (r * b)).collect();
|
||||
|
||||
let transcript = &mut PoseidonTranscript::<C>::new(poseidon_config);
|
||||
let proof = CP::prove(
|
||||
params,
|
||||
transcript,
|
||||
&cm_3,
|
||||
&v_3,
|
||||
&C::ScalarField::zero(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Ok((cm_3, proof))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_homomorphic_property_using_CommitmentProver_trait() {
|
||||
let rng = &mut test_rng();
|
||||
fn test_homomorphic_property_using_Commitment_trait() {
|
||||
let mut rng = &mut test_rng();
|
||||
let poseidon_config = poseidon_test_config::<Fr>();
|
||||
let n: usize = 100;
|
||||
let n: usize = 128;
|
||||
|
||||
// set random vector for the test
|
||||
let v_1: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect();
|
||||
@@ -95,45 +95,74 @@ mod tests {
|
||||
let r = Fr::rand(rng);
|
||||
|
||||
// setup params for Pedersen & KZG
|
||||
let pedersen_params = Pedersen::<G1>::new_params(rng, n);
|
||||
let (pedersen_params, _) = Pedersen::<G1>::setup(&mut rng, n).unwrap();
|
||||
let (kzg_pk, kzg_vk): (ProverKey<G1>, VerifierKey<Bn254>) =
|
||||
KZGSetup::<Bn254>::setup(rng, n);
|
||||
KZG::<Bn254>::setup(rng, n).unwrap();
|
||||
|
||||
// Pedersen commit the two vectors and return their random linear combination and proof
|
||||
let (pedersen_cm, pedersen_proof) = commit_rlc_and_prove::<G1, Pedersen<G1>>(
|
||||
// test with Pedersen
|
||||
test_homomorphic_property_using_Commitment_trait_opt::<G1, Pedersen<G1>>(
|
||||
&poseidon_config,
|
||||
&pedersen_params,
|
||||
&pedersen_params,
|
||||
r,
|
||||
&v_1,
|
||||
&v_2,
|
||||
);
|
||||
// test with IPA
|
||||
test_homomorphic_property_using_Commitment_trait_opt::<G1, IPA<G1>>(
|
||||
&poseidon_config,
|
||||
&pedersen_params,
|
||||
&pedersen_params,
|
||||
r,
|
||||
&v_1,
|
||||
&v_2,
|
||||
);
|
||||
// test with KZG
|
||||
test_homomorphic_property_using_Commitment_trait_opt::<G1, KZG<Bn254>>(
|
||||
&poseidon_config,
|
||||
&kzg_pk,
|
||||
&kzg_vk,
|
||||
r,
|
||||
&v_1,
|
||||
&v_2,
|
||||
);
|
||||
}
|
||||
|
||||
fn test_homomorphic_property_using_Commitment_trait_opt<
|
||||
C: CurveGroup,
|
||||
CS: CommitmentScheme<C>,
|
||||
>(
|
||||
poseidon_config: &PoseidonConfig<C::ScalarField>,
|
||||
prover_params: &CS::ProverParams,
|
||||
verifier_params: &CS::VerifierParams,
|
||||
r: C::ScalarField,
|
||||
v_1: &[C::ScalarField],
|
||||
v_2: &[C::ScalarField],
|
||||
) where
|
||||
<C as ark_ec::Group>::ScalarField: Absorb,
|
||||
{
|
||||
// compute the commitment of the two vectors using the given CommitmentScheme
|
||||
let cm_1 = CS::commit(prover_params, v_1, &C::ScalarField::zero()).unwrap();
|
||||
let cm_2 = CS::commit(prover_params, v_2, &C::ScalarField::zero()).unwrap();
|
||||
|
||||
// random linear combination of the commitments and their witnesses (vectors v_i)
|
||||
let cm_3 = cm_1 + cm_2.mul(r);
|
||||
let v_3: Vec<C::ScalarField> = v_1.iter().zip(v_2).map(|(a, b)| *a + (r * b)).collect();
|
||||
|
||||
// compute the proof of the cm_3
|
||||
let transcript_p = &mut PoseidonTranscript::<C>::new(poseidon_config);
|
||||
let proof = CS::prove(
|
||||
prover_params,
|
||||
transcript_p,
|
||||
&cm_3,
|
||||
&v_3,
|
||||
&C::ScalarField::zero(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// KZG commit the two vectors and return their random linear combination and proof
|
||||
let (kzg_cm, kzg_proof) =
|
||||
commit_rlc_and_prove::<G1, KZGProver<G1>>(&poseidon_config, &kzg_pk, r, &v_1, &v_2)
|
||||
.unwrap();
|
||||
|
||||
// verify Pedersen
|
||||
let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
|
||||
Pedersen::<G1>::verify(&pedersen_params, transcript_v, pedersen_cm, pedersen_proof)
|
||||
.unwrap();
|
||||
|
||||
// verify KZG
|
||||
let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
|
||||
transcript_v.absorb_point(&kzg_cm).unwrap();
|
||||
let challenge = transcript_v.get_challenge();
|
||||
// verify the KZG proof using arkworks method
|
||||
assert!(KZG10::<Bn254, DensePolynomial<Fr>>::check(
|
||||
&kzg_vk,
|
||||
&KZG10Commitment(kzg_cm.into_affine()),
|
||||
challenge,
|
||||
kzg_proof.0, // eval
|
||||
&KZG10Proof::<Bn254> {
|
||||
w: kzg_proof.1.into_affine(), // proof
|
||||
random_v: None,
|
||||
},
|
||||
)
|
||||
.unwrap());
|
||||
// verify the opening proof
|
||||
let transcript_v = &mut PoseidonTranscript::<C>::new(poseidon_config);
|
||||
CS::verify(verifier_params, transcript_v, &cm_3, &proof).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user