diff --git a/src/iop/generator.rs b/src/iop/generator.rs index 17567a4c..6ab1b412 100644 --- a/src/iop/generator.rs +++ b/src/iop/generator.rs @@ -1,3 +1,4 @@ +use std::convert::identity; use std::fmt::Debug; use crate::field::extension_field::target::ExtensionTarget; @@ -74,6 +75,11 @@ pub(crate) fn generate_partial_witness( pending_generator_indices = next_pending_generator_indices; } + + assert!( + generator_is_expired.into_iter().all(identity), + "Some generators weren't run." + ); } /// A generator participates in the generation of the witness. diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index 573e0532..8afec0e4 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -8,6 +8,7 @@ use crate::field::cosets::get_unique_coset_shifts; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::{Extendable, FieldExtension}; use crate::fri::commitment::PolynomialBatchCommitment; +use crate::gates::arithmetic::{ArithmeticExtensionGate, NUM_ARITHMETIC_OPS}; use crate::gates::constant::ConstantGate; use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate}; use crate::gates::gate_tree::Tree; @@ -527,6 +528,33 @@ impl, const D: usize> CircuitBuilder { wire_partition.get_sigma_polys(degree_log, k_is, subgroup) } + /// Fill the remaining unused arithmetic operations with zeros, so that all + /// `ArithmeticExtensionGenerator` are run. + fn fill_arithmetic_gates(&mut self) { + let zero = self.zero_extension(); + let remaining_arithmetic_gates = self.free_arithmetic.values().copied().collect::>(); + for (gate, i) in remaining_arithmetic_gates { + for j in i..NUM_ARITHMETIC_OPS { + let wires_multiplicand_0 = ExtensionTarget::from_range( + gate, + ArithmeticExtensionGate::::wires_ith_multiplicand_0(j), + ); + let wires_multiplicand_1 = ExtensionTarget::from_range( + gate, + ArithmeticExtensionGate::::wires_ith_multiplicand_1(j), + ); + let wires_addend = ExtensionTarget::from_range( + gate, + ArithmeticExtensionGate::::wires_ith_addend(j), + ); + + self.route_extension(zero, wires_multiplicand_0); + self.route_extension(zero, wires_multiplicand_1); + self.route_extension(zero, wires_addend); + } + } + } + pub fn print_gate_counts(&self, min_delta: usize) { self.context_log .filter(self.num_gates(), min_delta) @@ -538,6 +566,8 @@ impl, const D: usize> CircuitBuilder { let mut timing = TimingTree::new("preprocess", Level::Trace); let start = Instant::now(); + self.fill_arithmetic_gates(); + // Hash the public inputs, and route them to a `PublicInputGate` which will enforce that // those hash wires match the claimed public inputs. let public_inputs_hash = self.hash_n_to_hash(self.public_inputs.clone(), true);