Reduce the number of constraints in AugmentedFCircuit for Nova (#86)

* Reduce the number of constraints in `AugmentedFCircuit`

For the test `folding::nova::tests::test_ivc`
Before: 138240
After: 86756 (1.6x improvement)

Two notable optimization techniques:
1. Instead of allocating two witness variables `a, b` and enforce their equality by calling `a.conditional_enforce_equal(&b, &cond)`, we can avoid the allocation of `b` and directly set `b = a`. The former might be costly due to the checks in allocation and `conditional_enforce_equal`. See `nova/circuits.rs` for details.
2. Before this commit, `NonNativeFieldVar::to_constraint_field` was majorly called for generating the inputs (preimage) to hash functions. However, it turns out that the underlying conversion strategy (optimized for weight) is not optimal for reducing the length of hash preimage. We can go further by maximizing the number of bits per limb, thereby minimizing the preimage length. See `circuits/nonnative.rs` for details.

* Format

* Fix clippy warnings

* Move the comments to the right position

* Cleanup unnecessary code
This commit is contained in:
winderica
2024-04-12 14:01:27 +01:00
committed by GitHub
parent 6a7dd935bd
commit 4dcb981dd4
7 changed files with 373 additions and 288 deletions

View File

@@ -2,7 +2,6 @@
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{CurveGroup, Group};
use ark_ff::PrimeField;
use ark_r1cs_std::fields::nonnative::params::OptimizationType;
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
use ark_snark::SNARK;
use ark_std::rand::{CryptoRng, RngCore};
@@ -14,7 +13,7 @@ use super::{circuits::CF2, nifs::NIFS, CommittedInstance, Nova};
use crate::commitment::{
kzg::Proof as KZGProof, pedersen::Params as PedersenParams, CommitmentScheme,
};
use crate::folding::circuits::nonnative::point_to_nonnative_limbs_custom_opt;
use crate::folding::circuits::nonnative::NonNativeAffineVar;
use crate::frontend::FCircuit;
use crate::Error;
use crate::{Decider as DeciderTrait, FoldingScheme};
@@ -151,12 +150,9 @@ where
// compute U = U_{d+1}= NIFS.V(U_d, u_d, cmT)
let U = NIFS::<C1, CS1>::verify(proof.r, running_instance, incoming_instance, &proof.cmT);
let (cmE_x, cmE_y) =
point_to_nonnative_limbs_custom_opt::<C1>(U.cmE, OptimizationType::Constraints)?;
let (cmW_x, cmW_y) =
point_to_nonnative_limbs_custom_opt::<C1>(U.cmW, OptimizationType::Constraints)?;
let (cmT_x, cmT_y) =
point_to_nonnative_limbs_custom_opt::<C1>(proof.cmT, OptimizationType::Constraints)?;
let (cmE_x, cmE_y) = NonNativeAffineVar::inputize(U.cmE)?;
let (cmW_x, cmW_y) = NonNativeAffineVar::inputize(U.cmW)?;
let (cmT_x, cmT_y) = NonNativeAffineVar::inputize(proof.cmT)?;
let public_input: Vec<C1::ScalarField> = vec![
vec![i],