From e4cbee2b5778b0c49e22c582947dbd2b0a8498ac Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sat, 14 Aug 2021 10:01:10 -0700 Subject: [PATCH] Disable ZK in `large_config` (#180) * Disable ZK in large_config Speeds up the tests from ~6m to ~1m (debug mode). `large_config` is crate-private so I don't think we need to worry about real users forgetting ZK, and I don't think ZK seems important in these tests, though we should probably have ZK enabled for a couple tests. A couple tests need ZK or they fail; I added a TODO to look later. This led to a few other changes: - Fixed a bug where `trim` could truncate the final poly to a non-power-of-two length. This was improbable when ZK is on due to randomization. - Gave a few methods access to the whole `CircuitConfig` vs `FriConfig` -- sort of necessary for the above fix, and I don't think there's much downside. - Remove `cap_height` from `FriConfig` -- didn't really need it any more after giving more methods access to `CircuitConfig`, and having a single copy of the param feels cleaner/safer to me. * PR feedback --- src/bin/bench_recursion.rs | 1 - src/fri/commitment.rs | 23 ++++++++++++++--------- src/fri/mod.rs | 2 -- src/fri/prover.rs | 24 ++++++++++++++++-------- src/fri/recursive_verifier.rs | 10 ++++------ src/gadgets/arithmetic_extension.rs | 2 +- src/gadgets/interpolation.rs | 2 +- src/plonk/circuit_data.rs | 16 +++++++++++++--- src/plonk/recursive_verifier.rs | 2 -- src/util/mod.rs | 2 +- 10 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 7067bd49..d3e4e1e0 100644 --- a/src/bin/bench_recursion.rs +++ b/src/bin/bench_recursion.rs @@ -32,7 +32,6 @@ fn bench_prove, const D: usize>() -> Result<()> { proof_of_work_bits: 20, reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], num_query_rounds: 35, - cap_height: 1, }, }; diff --git a/src/fri/commitment.rs b/src/fri/commitment.rs index d62fa33d..7e7dab6e 100644 --- a/src/fri/commitment.rs +++ b/src/fri/commitment.rs @@ -205,7 +205,7 @@ impl PolynomialBatchCommitment { lde_final_poly, lde_final_values, challenger, - &config.fri_config, + &config, timing, ); @@ -281,8 +281,8 @@ mod tests { proof_of_work_bits: 2, reduction_arity_bits: vec![2, 3, 1, 2], num_query_rounds: 3, - cap_height: 1, }; + // We only care about `fri_config, num_constants`, and `num_routed_wires` here. let common_data = CommonCircuitData { config: CircuitConfig { @@ -300,12 +300,12 @@ mod tests { circuit_digest: HashOut::from_partial(vec![]), }; - let lpcs = (0..4) + let commitments = (0..4) .map(|i| { PolynomialBatchCommitment::::from_values( gen_random_test_case(ks[i], degree_bits), common_data.config.rate_bits, - PlonkPolynomials::polynomials(i).blinding, + common_data.config.zero_knowledge && PlonkPolynomials::polynomials(i).blinding, common_data.config.cap_height, &mut TimingTree::default(), ) @@ -314,7 +314,12 @@ mod tests { let zeta = gen_random_point::(degree_bits); let (proof, os) = PolynomialBatchCommitment::open_plonk::( - &[&lpcs[0], &lpcs[1], &lpcs[2], &lpcs[3]], + &[ + &commitments[0], + &commitments[1], + &commitments[2], + &commitments[3], + ], zeta, &mut Challenger::new(), &common_data, @@ -322,10 +327,10 @@ mod tests { ); let merkle_caps = &[ - lpcs[0].merkle_tree.cap.clone(), - lpcs[1].merkle_tree.cap.clone(), - lpcs[2].merkle_tree.cap.clone(), - lpcs[3].merkle_tree.cap.clone(), + commitments[0].merkle_tree.cap.clone(), + commitments[1].merkle_tree.cap.clone(), + commitments[2].merkle_tree.cap.clone(), + commitments[3].merkle_tree.cap.clone(), ]; verify_fri_proof( diff --git a/src/fri/mod.rs b/src/fri/mod.rs index 55a41abd..716260a3 100644 --- a/src/fri/mod.rs +++ b/src/fri/mod.rs @@ -16,6 +16,4 @@ pub struct FriConfig { /// Number of query rounds to perform. pub num_query_rounds: usize, - - pub cap_height: usize, } diff --git a/src/fri/prover.rs b/src/fri/prover.rs index 52db4579..c1f53a1c 100644 --- a/src/fri/prover.rs +++ b/src/fri/prover.rs @@ -8,6 +8,7 @@ use crate::hash::hash_types::HashOut; use crate::hash::hashing::hash_n_to_1; use crate::hash::merkle_tree::MerkleTree; use crate::iop::challenger::Challenger; +use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::plonk_common::reduce_with_powers; use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::timed; @@ -22,7 +23,7 @@ pub fn fri_proof, const D: usize>( // Evaluation of the polynomial on the large domain. lde_polynomial_values: PolynomialValues, challenger: &mut Challenger, - config: &FriConfig, + config: &CircuitConfig, timing: &mut TimingTree, ) -> FriProof { let n = lde_polynomial_values.values.len(); @@ -45,12 +46,17 @@ pub fn fri_proof, const D: usize>( let pow_witness = timed!( timing, "find for proof-of-work witness", - fri_proof_of_work(current_hash, config) + fri_proof_of_work(current_hash, &config.fri_config) ); // Query phase - let query_round_proofs = - fri_prover_query_rounds(initial_merkle_trees, &trees, challenger, n, config); + let query_round_proofs = fri_prover_query_rounds( + initial_merkle_trees, + &trees, + challenger, + n, + &config.fri_config, + ); FriProof { commit_phase_merkle_caps: trees.iter().map(|t| t.cap.clone()).collect(), @@ -64,14 +70,14 @@ fn fri_committed_trees, const D: usize>( mut coeffs: PolynomialCoeffs, mut values: PolynomialValues, challenger: &mut Challenger, - config: &FriConfig, + config: &CircuitConfig, ) -> (Vec>, PolynomialCoeffs) { let mut trees = Vec::new(); let mut shift = F::MULTIPLICATIVE_GROUP_GENERATOR; - let num_reductions = config.reduction_arity_bits.len(); + let num_reductions = config.fri_config.reduction_arity_bits.len(); for i in 0..num_reductions { - let arity = 1 << config.reduction_arity_bits[i]; + let arity = 1 << config.fri_config.reduction_arity_bits[i]; reverse_index_bits_in_place(&mut values.values); let chunked_values = values @@ -97,7 +103,9 @@ fn fri_committed_trees, const D: usize>( values = coeffs.coset_fft(shift.into()) } - coeffs.trim(); + /// The coefficients being removed here should always be zero. + coeffs.coeffs.truncate(coeffs.len() >> config.rate_bits); + challenger.observe_extension_elements(&coeffs.coeffs); (trees, coeffs) } diff --git a/src/fri/recursive_verifier.rs b/src/fri/recursive_verifier.rs index bf07639f..c9f15aec 100644 --- a/src/fri/recursive_verifier.rs +++ b/src/fri/recursive_verifier.rs @@ -291,15 +291,13 @@ impl, const D: usize> CircuitBuilder { round_proof: &FriQueryRoundTarget, common_data: &CommonCircuitData, ) { - let config = &common_data.config.fri_config; + let config = &common_data.config; let n_log = log2_strict(n); // TODO: Do we need to range check `x_index` to a target smaller than `p`? let x_index = challenger.get_challenge(self); let mut x_index_bits = self.low_bits(x_index, n_log, 64); - let cap_index = self.le_sum( - x_index_bits[x_index_bits.len() - common_data.config.fri_config.cap_height..] - .into_iter(), - ); + let cap_index = self + .le_sum(x_index_bits[x_index_bits.len() - common_data.config.cap_height..].into_iter()); with_context!( self, "check FRI initial proof", @@ -349,7 +347,7 @@ impl, const D: usize> CircuitBuilder { ) ); - for (i, &arity_bits) in config.reduction_arity_bits.iter().enumerate() { + for (i, &arity_bits) in config.fri_config.reduction_arity_bits.iter().enumerate() { let evals = &round_proof.steps[i].evals; // Split x_index into the index of the coset x is in, and the index of x within that coset. diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index 8b7c11e3..7ab8d359 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -712,7 +712,7 @@ mod tests { type FF = QuarticCrandallField; const D: usize = 4; - let config = CircuitConfig::large_config(); + let config = CircuitConfig::large_zk_config(); let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index 92090d90..9d48a204 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -113,7 +113,7 @@ mod tests { fn test_interpolate2() -> Result<()> { type F = CrandallField; type FF = QuarticCrandallField; - let config = CircuitConfig::large_config(); + let config = CircuitConfig::large_zk_config(); let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); diff --git a/src/plonk/circuit_data.rs b/src/plonk/circuit_data.rs index 2441d810..3b9becab 100644 --- a/src/plonk/circuit_data.rs +++ b/src/plonk/circuit_data.rs @@ -48,7 +48,6 @@ impl Default for CircuitConfig { proof_of_work_bits: 1, reduction_arity_bits: vec![1, 1, 1, 1], num_query_rounds: 1, - cap_height: 1, }, } } @@ -66,14 +65,25 @@ impl CircuitConfig { security_bits: 128, rate_bits: 3, num_challenges: 3, - zero_knowledge: true, + zero_knowledge: false, cap_height: 1, + fri_config: FriConfig { + proof_of_work_bits: 1, + reduction_arity_bits: vec![1], + num_query_rounds: 1, + }, + } + } + + pub(crate) fn large_zk_config() -> Self { + CircuitConfig { + zero_knowledge: true, fri_config: FriConfig { proof_of_work_bits: 1, reduction_arity_bits: vec![1, 1, 1, 1], num_query_rounds: 1, - cap_height: 1, }, + ..Self::large_config() } } } diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index ea35d505..27e8f2fb 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -375,7 +375,6 @@ mod tests { proof_of_work_bits: 1, reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], num_query_rounds: 40, - cap_height: 1, }, }; let (proof_with_pis, vd, cd) = { @@ -431,7 +430,6 @@ mod tests { proof_of_work_bits: 1, reduction_arity_bits: vec![2, 2, 2, 2, 2, 2], num_query_rounds: 40, - cap_height: 3, }, }; let (proof_with_pis, vd, cd) = { diff --git a/src/util/mod.rs b/src/util/mod.rs index 7ee995f5..b468ab35 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -26,7 +26,7 @@ pub(crate) fn log2_ceil(n: usize) -> usize { /// Computes `log_2(n)`, panicking if `n` is not a power of two. pub(crate) fn log2_strict(n: usize) -> usize { - assert!(n.is_power_of_two(), "Not a power of two"); + assert!(n.is_power_of_two(), "Not a power of two: {}", n); log2_ceil(n) }