mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-28 14:56:40 +01:00
Add IPA commitment scheme and the respective circuit verifier gadget (#72)
* Add IPA commitment native implementation * Add IPA Gadget verifier * polish Pedersen & IPA, add blind bool param to IPA * Optimize IPA gadget constraints (and native): - optimize <s,b> computation from linear to log time - optimize s computation from k*2^k to k*(2^k)/2 * add small optimization: delegate u_i^-1 to prover and just check u_i*u_i^-1==1 in verifier circuit * IPA polish and document * Add 'BLIND' parameter to CommitmentProver trait (and to Pedersen and KZG impls). Fit IPA into CommitmentProver trait. * rename 'BLIND' to 'H' (hiding) in commitment * IPA: rm u_invs from Proof and compute them incircuit * Update IPA's build_s & gadget to use Halo2 approach following @han0110 's suggestion. This reduced further the amount of constraints needed. - for k=4: -9k constraints (-7%) - for k=8: -473k constr (-31%) - for k=9: -1123k constr (-35%) - for k=10: -2578k constr (-39%) And now IPA verification (without amortizing) is very close to Pedersen verification (in-circuits). * rm dbg!(cs.num_constraints()) from multiple tests * IPA::prove remove intermediate v_lo,v_hi vectors, add doc to build_s_gadget * move powers_of into utils/mod.rs, update iters to cfg_iter
This commit is contained in:
@@ -654,7 +654,6 @@ pub mod tests {
|
||||
.generate_constraints(cs.clone())
|
||||
.unwrap();
|
||||
cs.finalize();
|
||||
println!("num_constraints={:?}", cs.num_constraints());
|
||||
let cs = cs.into_inner().unwrap();
|
||||
let r1cs = extract_r1cs::<Fr>(&cs);
|
||||
let (w, x) = extract_w_x::<Fr>(&cs);
|
||||
|
||||
@@ -459,7 +459,6 @@ pub mod tests {
|
||||
.unwrap();
|
||||
nifs_cf_check.enforce_equal(&Boolean::<Fq>::TRUE).unwrap();
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
dbg!(cs.num_constraints());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -500,7 +499,6 @@ pub mod tests {
|
||||
.unwrap();
|
||||
nifs_check.enforce_equal(&Boolean::<Fq>::TRUE).unwrap();
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
dbg!(cs.num_constraints());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -370,13 +370,6 @@ where
|
||||
// `#[cfg(not(test))]`
|
||||
use crate::commitment::pedersen::PedersenGadget;
|
||||
use crate::folding::nova::cyclefold::{CycleFoldCommittedInstanceVar, CF_IO_LEN};
|
||||
use ark_r1cs_std::ToBitsGadget;
|
||||
|
||||
let cf_r1cs = R1CSVar::<
|
||||
C1::BaseField,
|
||||
CF1<C1>,
|
||||
NonNativeFieldVar<C1::BaseField, CF1<C1>>,
|
||||
>::new_witness(cs.clone(), || Ok(self.cf_r1cs.clone()))?;
|
||||
|
||||
let cf_u_dummy_native = CommittedInstance::<C2>::dummy(CF_IO_LEN);
|
||||
let w_dummy_native = Witness::<C2>::new(
|
||||
@@ -393,28 +386,24 @@ where
|
||||
// 5. check Pedersen commitments of cf_U_i.{cmE, cmW}
|
||||
let H = GC2::new_constant(cs.clone(), self.cf_pedersen_params.h)?;
|
||||
let G = Vec::<GC2>::new_constant(cs.clone(), self.cf_pedersen_params.generators)?;
|
||||
let cf_W_i_E_bits: Vec<Vec<Boolean<CF1<C1>>>> = cf_W_i
|
||||
.E
|
||||
.iter()
|
||||
.map(|E_i| E_i.to_bits_le().unwrap())
|
||||
.collect();
|
||||
let cf_W_i_W_bits: Vec<Vec<Boolean<CF1<C1>>>> = cf_W_i
|
||||
.W
|
||||
.iter()
|
||||
.map(|W_i| W_i.to_bits_le().unwrap())
|
||||
.collect();
|
||||
|
||||
let computed_cmE = PedersenGadget::<C2, GC2>::commit(
|
||||
H.clone(),
|
||||
G.clone(),
|
||||
cf_W_i_E_bits,
|
||||
cf_W_i.rE.to_bits_le()?,
|
||||
cf_W_i.E.clone(),
|
||||
cf_W_i.rE,
|
||||
)?;
|
||||
cf_U_i.cmE.enforce_equal(&computed_cmE)?;
|
||||
let computed_cmW =
|
||||
PedersenGadget::<C2, GC2>::commit(H, G, cf_W_i_W_bits, cf_W_i.rW.to_bits_le()?)?;
|
||||
PedersenGadget::<C2, GC2>::commit(H, G, cf_W_i.W.clone(), cf_W_i.rW)?;
|
||||
cf_U_i.cmW.enforce_equal(&computed_cmW)?;
|
||||
|
||||
let cf_r1cs = R1CSVar::<
|
||||
C1::BaseField,
|
||||
CF1<C1>,
|
||||
NonNativeFieldVar<C1::BaseField, CF1<C1>>,
|
||||
>::new_witness(cs.clone(), || Ok(self.cf_r1cs.clone()))?;
|
||||
|
||||
// 6. check RelaxedR1CS of cf_U_i
|
||||
let cf_z_U: Vec<NonNativeFieldVar<C2::ScalarField, CF1<C1>>> =
|
||||
[vec![cf_U_i.u.clone()], cf_U_i.x.to_vec(), cf_W_i.W.to_vec()].concat();
|
||||
@@ -681,6 +670,5 @@ pub mod tests {
|
||||
// generate the constraints and check that are satisfied by the inputs
|
||||
decider_circuit.generate_constraints(cs.clone()).unwrap();
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
dbg!(cs.num_constraints());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,9 +190,9 @@ where
|
||||
T: Vec<C::ScalarField>,
|
||||
cmT: &C,
|
||||
) -> Result<[CP::Proof; 3], Error> {
|
||||
let cmE_proof = CP::prove(cm_prover_params, tr, &ci.cmE, &w.E, &w.rE)?;
|
||||
let cmW_proof = CP::prove(cm_prover_params, tr, &ci.cmW, &w.W, &w.rW)?;
|
||||
let cmT_proof = CP::prove(cm_prover_params, tr, cmT, &T, &C::ScalarField::one())?; // cm(T) is committed with rT=1
|
||||
let cmE_proof = CP::prove(cm_prover_params, tr, &ci.cmE, &w.E, &w.rE, None)?;
|
||||
let cmW_proof = CP::prove(cm_prover_params, tr, &ci.cmW, &w.W, &w.rW, None)?;
|
||||
let cmT_proof = CP::prove(cm_prover_params, tr, cmT, &T, &C::ScalarField::one(), None)?; // cm(T) is committed with rT=1
|
||||
Ok([cmE_proof, cmW_proof, cmT_proof])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user