mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-07 14:31:31 +01:00
Resolve the stack overflow issue when evaluating polynomials in-circuit (#166)
* Resolve the stack overflow issue when evaluating polynomials in-circuit * Format * Add the missing line of comment
This commit is contained in:
@@ -26,7 +26,6 @@ use super::{
|
||||
nimfs::{NIMFSProof, NIMFS},
|
||||
HyperNova, Witness, CCCS, LCCCS,
|
||||
};
|
||||
use crate::commitment::{pedersen::Params as PedersenParams, CommitmentScheme};
|
||||
use crate::folding::circuits::{
|
||||
cyclefold::{CycleFoldCommittedInstance, CycleFoldWitness},
|
||||
CF1, CF2,
|
||||
@@ -42,6 +41,10 @@ use crate::{
|
||||
arith::{ccs::CCS, r1cs::R1CS},
|
||||
folding::traits::{CommittedInstanceVarOps, Dummy, WitnessVarOps},
|
||||
};
|
||||
use crate::{
|
||||
commitment::{pedersen::Params as PedersenParams, CommitmentScheme},
|
||||
folding::nova::decider_eth_circuit::evaluate_gadget,
|
||||
};
|
||||
|
||||
/// In-circuit representation of the Witness associated to the CommittedInstance.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -322,7 +325,7 @@ where
|
||||
let kzg_challenge = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.kzg_challenge.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
let _eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
let eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_W.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
|
||||
@@ -423,14 +426,6 @@ where
|
||||
// `rho_bits` computed along the way of computing `computed_U_i1` for the later `rho_powers`
|
||||
// check (6.b).
|
||||
|
||||
// Check 7 is temporary disabled due
|
||||
// https://github.com/privacy-scaling-explorations/sonobe/issues/80
|
||||
log::warn!("[WARNING]: issue #80 (https://github.com/privacy-scaling-explorations/sonobe/issues/80) is not resolved yet.");
|
||||
//
|
||||
// 7. check eval_W==p_W(c_W)
|
||||
// let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
// incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
|
||||
// 8.a verify the NIMFS.V of the final fold, and check that the obtained rho_powers from the
|
||||
// transcript match the one from the public input (so we avoid the onchain logic of the
|
||||
// verifier computing it).
|
||||
@@ -462,6 +457,10 @@ where
|
||||
computed_U_i1.r_x.enforce_equal(&U_i1.r_x)?;
|
||||
computed_U_i1.v.enforce_equal(&U_i1.v)?;
|
||||
|
||||
// 7. check eval_W==p_W(c_W)
|
||||
let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.w, incircuit_challenge)?;
|
||||
incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
|
||||
// 8.b check that the in-circuit computed r is equal to the inputted r.
|
||||
|
||||
let rho = Boolean::le_bits_to_fp_var(&rho_bits)?;
|
||||
|
||||
@@ -25,7 +25,9 @@ use core::marker::PhantomData;
|
||||
|
||||
use super::{
|
||||
circuits::{ChallengeGadget, CommittedInstanceVar},
|
||||
decider_eth_circuit::{KZGChallengesGadget, R1CSVar, RelaxedR1CSGadget, WitnessVar},
|
||||
decider_eth_circuit::{
|
||||
evaluate_gadget, KZGChallengesGadget, R1CSVar, RelaxedR1CSGadget, WitnessVar,
|
||||
},
|
||||
nifs::NIFS,
|
||||
traits::NIFSTrait,
|
||||
CommittedInstance, Nova, Witness,
|
||||
@@ -239,10 +241,10 @@ where
|
||||
let cs_c_E = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.cs_c_E.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
let _eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
let eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_W.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
let _eval_E = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
let eval_E = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_E.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
|
||||
@@ -296,15 +298,11 @@ where
|
||||
incircuit_c_W.enforce_equal(&cs_c_W)?;
|
||||
incircuit_c_E.enforce_equal(&cs_c_E)?;
|
||||
|
||||
// Check 5.2 is temporary disabled due
|
||||
// https://github.com/privacy-scaling-explorations/sonobe/issues/80
|
||||
log::warn!("[WARNING]: issue #80 (https://github.com/privacy-scaling-explorations/sonobe/issues/80) is not resolved yet.");
|
||||
//
|
||||
// 5.2. check eval_W==p_W(c_W) and eval_E==p_E(c_E)
|
||||
// let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
// let incircuit_eval_E = evaluate_gadget::<CF1<C1>>(W_i1.E, incircuit_c_E)?;
|
||||
// incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
// incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
let incircuit_eval_E = evaluate_gadget::<CF1<C1>>(W_i1.E, incircuit_c_E)?;
|
||||
incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
|
||||
// 1.1.b check that the NIFS.V challenge matches the one from the public input (so we avoid
|
||||
// the verifier computing it)
|
||||
@@ -451,7 +449,7 @@ where
|
||||
|
||||
// 6. check RelaxedR1CS of cf_U_i
|
||||
let cf_z_U = [vec![cf_U_i.u.clone()], cf_U_i.x.to_vec(), cf_W_i.W.to_vec()].concat();
|
||||
RelaxedR1CSGadget::check_native(cf_r1cs, cf_W_i.E, cf_U_i.u.clone(), cf_z_U)?;
|
||||
RelaxedR1CSGadget::check_native(cf_r1cs, cf_W_i.E.clone(), cf_U_i.u.clone(), cf_z_U)?;
|
||||
|
||||
// `transcript` is for challenge generation.
|
||||
let mut transcript =
|
||||
@@ -466,10 +464,10 @@ where
|
||||
Ok(self.cs_c_E.unwrap_or_else(CF1::<C2>::zero))
|
||||
})?;
|
||||
// allocate the inputs for the check 7.2
|
||||
let _eval_W = FpVar::<CF1<C2>>::new_input(cs.clone(), || {
|
||||
let eval_W = FpVar::<CF1<C2>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_W.unwrap_or_else(CF1::<C2>::zero))
|
||||
})?;
|
||||
let _eval_E = FpVar::<CF1<C2>>::new_input(cs.clone(), || {
|
||||
let eval_E = FpVar::<CF1<C2>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_E.unwrap_or_else(CF1::<C2>::zero))
|
||||
})?;
|
||||
|
||||
@@ -479,14 +477,11 @@ where
|
||||
incircuit_c_W.enforce_equal(&cs_c_W)?;
|
||||
incircuit_c_E.enforce_equal(&cs_c_E)?;
|
||||
|
||||
// Check 7.2 is temporary disabled due
|
||||
// https://github.com/privacy-scaling-explorations/sonobe/issues/80
|
||||
log::warn!("[WARNING]: issue #80 (https://github.com/privacy-scaling-explorations/sonobe/issues/80) is not resolved yet.");
|
||||
// 7.2. check eval_W==p_W(c_W) and eval_E==p_E(c_E)
|
||||
// let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
// let incircuit_eval_E = evaluate_gadget::<CF1<C1>>(W_i1.E, incircuit_c_E)?;
|
||||
// incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
// incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
let incircuit_eval_W = evaluate_gadget::<CF1<C2>>(cf_W_i.W, incircuit_c_W)?;
|
||||
let incircuit_eval_E = evaluate_gadget::<CF1<C2>>(cf_W_i.E, incircuit_c_E)?;
|
||||
incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -383,10 +383,10 @@ where
|
||||
Ok(self.kzg_c_E.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
// allocate the inputs for the check 5.2
|
||||
let _eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
let eval_W = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_W.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
let _eval_E = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
let eval_E = FpVar::<CF1<C1>>::new_input(cs.clone(), || {
|
||||
Ok(self.eval_E.unwrap_or_else(CF1::<C1>::zero))
|
||||
})?;
|
||||
|
||||
@@ -498,15 +498,11 @@ where
|
||||
incircuit_c_W.enforce_equal(&kzg_c_W)?;
|
||||
incircuit_c_E.enforce_equal(&kzg_c_E)?;
|
||||
|
||||
// Check 5.2 is temporary disabled due
|
||||
// https://github.com/privacy-scaling-explorations/sonobe/issues/80
|
||||
log::warn!("[WARNING]: issue #80 (https://github.com/privacy-scaling-explorations/sonobe/issues/80) is not resolved yet.");
|
||||
//
|
||||
// 5.2. check eval_W==p_W(c_W) and eval_E==p_E(c_E)
|
||||
// let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
// let incircuit_eval_E = evaluate_gadget::<CF1<C1>>(W_i1.E, incircuit_c_E)?;
|
||||
// incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
// incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
let incircuit_eval_W = evaluate_gadget::<CF1<C1>>(W_i1.W, incircuit_c_W)?;
|
||||
let incircuit_eval_E = evaluate_gadget::<CF1<C1>>(W_i1.E, incircuit_c_E)?;
|
||||
incircuit_eval_W.enforce_equal(&eval_W)?;
|
||||
incircuit_eval_E.enforce_equal(&eval_E)?;
|
||||
|
||||
// 1.1.b check that the NIFS.V challenge matches the one from the public input (so we avoid
|
||||
// the verifier computing it)
|
||||
@@ -523,13 +519,11 @@ where
|
||||
/// Interpolates the polynomial from the given vector, and then returns it's evaluation at the
|
||||
/// given point.
|
||||
#[allow(unused)] // unused while check 7 is disabled
|
||||
fn evaluate_gadget<F: PrimeField>(
|
||||
v: Vec<FpVar<F>>,
|
||||
pub fn evaluate_gadget<F: PrimeField>(
|
||||
mut v: Vec<FpVar<F>>,
|
||||
point: FpVar<F>,
|
||||
) -> Result<FpVar<F>, SynthesisError> {
|
||||
if !v.len().is_power_of_two() {
|
||||
return Err(SynthesisError::Unsatisfiable);
|
||||
}
|
||||
v.resize(v.len().next_power_of_two(), FpVar::zero());
|
||||
let n = v.len() as u64;
|
||||
let gen = F::get_root_of_unity(n).unwrap();
|
||||
let domain = Radix2DomainVar::new(gen, log2(v.len()) as u64, FpVar::one()).unwrap();
|
||||
@@ -884,10 +878,6 @@ pub mod tests {
|
||||
assert_eq!(challenge_E_Var.value().unwrap(), challenge_E);
|
||||
}
|
||||
|
||||
// The test test_polynomial_interpolation is temporary disabled due
|
||||
// https://github.com/privacy-scaling-explorations/sonobe/issues/80
|
||||
// for n<=11 it will work, but for n>11 it will fail with stack overflow.
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_polynomial_interpolation() {
|
||||
let mut rng = ark_std::test_rng();
|
||||
|
||||
Reference in New Issue
Block a user