pad_circuit: use config to determine zk and check for underflow (#395)

This commit is contained in:
Daniel Gulotta 2025-08-25 08:12:04 -07:00 committed by GitHub
parent f76197c602
commit 122f9c3cac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -457,7 +457,6 @@ fn estimate_gates_after_zk(degree_bits: usize) -> usize {
} }
// how many blinding gates are in this zk circuit // how many blinding gates are in this zk circuit
#[cfg(feature = "zk")]
fn blinding_gates(degree_bits: usize) -> usize { fn blinding_gates(degree_bits: usize) -> usize {
// Table data obtained using `test_measure_zk_recursion`, and printing // Table data obtained using `test_measure_zk_recursion`, and printing
// `regular_poly_openings + 2 * z_openings` at method `blind` of the file // `regular_poly_openings + 2 * z_openings` at method `blind` of the file
@ -543,23 +542,28 @@ pub fn pad_circuit(builder: &mut CircuitBuilder<F, D>, common_data: &CommonCircu
assert_eq!(common_data.num_public_inputs, builder.num_public_inputs()); assert_eq!(common_data.num_public_inputs, builder.num_public_inputs());
let degree = common_data.degree(); let degree = common_data.degree();
// in the zk case, account for the blinding gates, to avoid
// padding to them too, because then plonky2's in the builder.build()
// phase would add new blinding gates on top of the ones that we already
// accounted for in the `common_data_for_recursion`, increasing (w.h.p.)
// the degree of the circuit.
let num_blinding_gates = if common_data.config.zero_knowledge {
blinding_gates(log2_ceil(degree))
} else {
0
};
// Need to account for public input hashing, a `PublicInputGate` and MAX_CONSTANT_GATES // Need to account for public input hashing, a `PublicInputGate` and MAX_CONSTANT_GATES
// `ConstantGate`. NOTE: the builder doesn't have any public method to see how many constants // `ConstantGate`. NOTE: the builder doesn't have any public method to see how many constants
// have been registered, so we can't know exactly how many `ConstantGates` will be required. // have been registered, so we can't know exactly how many `ConstantGates` will be required.
// We hope that no more than MAX_CONSTANT_GATES*2 constants are used :pray:. Maybe we should // We hope that no more than MAX_CONSTANT_GATES*2 constants are used :pray:. Maybe we should
// make a PR to plonky2 to expose this? // make a PR to plonky2 to expose this?
#[allow(unused_mut)] let degree_adjustment =
let mut num_gates = degree - common_data.num_public_inputs.div_ceil(8) - 1 - MAX_CONSTANT_GATES; common_data.num_public_inputs.div_ceil(8) + 1 + MAX_CONSTANT_GATES + num_blinding_gates;
#[cfg(feature = "zk")] assert!(
{ degree_adjustment <= degree,
// in the zk config case, account for the blinding gates, to avoid "calculated a negative padding target: {degree} - {degree_adjustment}"
// padding to them too, because then plonky2's in the builder.build() );
// phase would add new blinding gates on top of the ones that we already let num_gates = degree - degree_adjustment;
// accounted for in the `common_data_for_recursion`, increasing (w.h.p.)
// the degree of the circuit.
num_gates -= blinding_gates(log2_ceil(degree));
}
assert!( assert!(
builder.num_gates() < num_gates, builder.num_gates() < num_gates,
"builder has more gates ({}) than the padding target ({})", "builder has more gates ({}) than the padding target ({})",