Skip to content

Commit 256d76a

Browse files
arnaucubeax0
andauthored
add zk config, enabled by a feature (on by default) (#306)
* add zk config, enabled by a feature (on by default) * Update src/backends/plonky2/recursion/circuit.rs Co-authored-by: Ahmad Afuni <root@ahmadafuni.com> --------- Co-authored-by: Ahmad Afuni <root@ahmadafuni.com>
1 parent d5da9d8 commit 256d76a

File tree

3 files changed

+82
-20
lines changed

3 files changed

+82
-20
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ pretty_assertions = "1.4.1"
4343
jsonschema = "0.30.0"
4444

4545
[features]
46-
default = ["backend_plonky2"]
46+
default = ["backend_plonky2", "zk"]
4747
backend_plonky2 = ["plonky2"]
48+
zk = []
4849
metrics = []
4950
time = []

src/backends/plonky2/emptypod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ pub static STANDARD_EMPTY_POD_DATA: LazyLock<(EmptyPodVerifyTarget, CircuitData)
8888

8989
fn build() -> Result<(EmptyPodVerifyTarget, CircuitData)> {
9090
let params = &*DEFAULT_PARAMS;
91+
92+
#[cfg(not(feature = "zk"))]
9193
let config = CircuitConfig::standard_recursion_config();
94+
#[cfg(feature = "zk")]
95+
let config = CircuitConfig::standard_recursion_zk_config();
96+
9297
let mut builder = CircuitBuilder::<F, D>::new(config);
9398
let empty_pod_verify_target = EmptyPodVerifyCircuit {
9499
params: params.clone(),

src/backends/plonky2/recursion/circuit.rs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,12 @@ impl<I: InnerCircuit> RecursiveCircuit<I> {
164164

165165
/// builds the targets and returns also a ProverCircuitData
166166
pub fn build(params: &RecursiveParams, inner_params: &I::Params) -> Result<Self> {
167+
#[cfg(not(feature = "zk"))]
167168
let config = CircuitConfig::standard_recursion_config();
168-
let mut builder = CircuitBuilder::new(config.clone());
169+
#[cfg(feature = "zk")]
170+
let config = CircuitConfig::standard_recursion_zk_config();
171+
172+
let mut builder = CircuitBuilder::new(config);
169173

170174
let targets: RecursiveCircuitTarget<I> = Self::build_targets(
171175
&mut builder,
@@ -275,7 +279,11 @@ impl<I: InnerCircuit> RecursiveCircuit<I> {
275279
);
276280

277281
// build the actual RecursiveCircuit circuit data
282+
#[cfg(not(feature = "zk"))]
278283
let config = CircuitConfig::standard_recursion_config();
284+
#[cfg(feature = "zk")]
285+
let config = CircuitConfig::standard_recursion_zk_config();
286+
279287
let mut builder = CircuitBuilder::new(config);
280288

281289
let target = timed!(
@@ -295,7 +303,11 @@ impl<I: InnerCircuit> RecursiveCircuit<I> {
295303
inner_params: &I::Params,
296304
) -> Result<(RecursiveCircuitTarget<I>, CircuitData<F, C, D>)> {
297305
// build the actual RecursiveCircuit circuit data
306+
#[cfg(not(feature = "zk"))]
298307
let config = CircuitConfig::standard_recursion_config();
308+
#[cfg(feature = "zk")]
309+
let config = CircuitConfig::standard_recursion_zk_config();
310+
299311
let mut builder = CircuitBuilder::new(config);
300312

301313
let target = timed!(
@@ -398,9 +410,20 @@ fn standard_gates(config: &CircuitConfig) -> Vec<GateRef<F, D>> {
398410
/// Estimate the number of gates to verify a proof of `degree_bits` that uses the
399411
/// `standard_gates(&standard_recursion_config)`
400412
fn estimate_verif_num_gates(degree_bits: usize) -> usize {
401-
// Formula obtained via linear regression using `test_measure_recursion` results with
402-
// `standard_recursion_config`.
403-
let num_gates: usize = 236 * degree_bits + 1171;
413+
let num_gates: usize;
414+
415+
#[cfg(feature = "zk")]
416+
{
417+
// Formula obtained via linear regression using
418+
// `test_measure_zk_recursion` results with `standard_recursion_zk_config`.
419+
num_gates = 244 * degree_bits + 1127;
420+
}
421+
#[cfg(not(feature = "zk"))]
422+
{
423+
// Formula obtained via linear regression using `test_measure_recursion`
424+
// results with `standard_recursion_config`.
425+
let num_gates: usize = 236 * degree_bits + 1171;
426+
}
404427
// Add 2% for error because the results are not a clean line
405428
num_gates * 102 / 100
406429
}
@@ -417,6 +440,21 @@ fn estimate_gates_after_zk(degree_bits: usize) -> usize {
417440
}
418441
}
419442

443+
// how many blinding gates are in this zk circuit
444+
fn blinding_gates(degree_bits: usize) -> usize {
445+
// Table data obtained using `test_measure_zk_recursion`, and printing
446+
// `regular_poly_openings + 2 * z_openings` at method `blind` of the file
447+
// `plonky2/plonky2/src/plonk/circuit_builder.rs`.
448+
match degree_bits {
449+
0..=12 => 8326,
450+
13..=14 => 8998,
451+
15 => 10342,
452+
16 => 13030,
453+
17 => 10846,
454+
_ => panic!("not supported"),
455+
}
456+
}
457+
420458
pub fn common_data_for_recursion<I: InnerCircuit>(
421459
arity: usize,
422460
num_public_inputs: usize,
@@ -448,13 +486,22 @@ pub fn common_data_for_recursion<I: InnerCircuit>(
448486
let mut degree_bits = log2_ceil(inner_num_gates);
449487
loop {
450488
let verif_num_gates = estimate_verif_num_gates(degree_bits);
451-
// Leave space for public input hashing, a `PublicInputGate` and some `ConstantGate`s (that's
452-
// MAX_CONSTANT_GATES*2 constants in the standard_recursion_config).
453-
let total_num_gates = inner_num_gates
489+
490+
// Leave space for public input hashing, a `PublicInputGate` and some
491+
// `ConstantGate`s (that's MAX_CONSTANT_GATES*2 constants in the
492+
// standard_recursion_config). And if the zk feature is enabled, add
493+
// space for the blinding gates.
494+
let mut total_num_gates = inner_num_gates
454495
+ verif_num_gates * arity
455496
+ circuit_data.common.num_public_inputs.div_ceil(8)
456497
+ 1
457498
+ MAX_CONSTANT_GATES;
499+
500+
#[cfg(feature = "zk")]
501+
{
502+
total_num_gates += blinding_gates(degree_bits);
503+
}
504+
458505
if total_num_gates < (1 << degree_bits) {
459506
break;
460507
}
@@ -464,27 +511,36 @@ pub fn common_data_for_recursion<I: InnerCircuit>(
464511
let mut common_data = circuit_data.common.clone();
465512
common_data.fri_params.degree_bits = degree_bits;
466513
common_data.fri_params.reduction_arity_bits = vec![4, 4, 4];
514+
#[cfg(feature = "zk")]
515+
{
516+
common_data.fri_params.hiding = true;
517+
common_data.config.zero_knowledge = true;
518+
}
467519
Ok(common_data)
468520
}
469521

470522
/// Pad the circuit to match a given `CommonCircuitData`.
471523
pub fn pad_circuit(builder: &mut CircuitBuilder<F, D>, common_data: &CommonCircuitData<F, D>) {
472524
assert_eq!(common_data.config, builder.config);
473525
assert_eq!(common_data.num_public_inputs, builder.num_public_inputs());
474-
// TODO: We need to figure this out once we enable zero-knowledge
475-
// https://github.com/0xPARC/pod2/issues/248
476-
assert!(
477-
!common_data.config.zero_knowledge,
478-
"Degree calculation can be off if zero-knowledge is on."
479-
);
480526

481527
let degree = common_data.degree();
482528
// Need to account for public input hashing, a `PublicInputGate` and MAX_CONSTANT_GATES
483529
// `ConstantGate`. NOTE: the builder doesn't have any public method to see how many constants
484530
// have been registered, so we can't know exactly how many `ConstantGates` will be required.
485531
// We hope that no more than MAX_CONSTANT_GATES*2 constants are used :pray:. Maybe we should
486532
// make a PR to plonky2 to expose this?
487-
let num_gates = degree - common_data.num_public_inputs.div_ceil(8) - 1 - MAX_CONSTANT_GATES;
533+
let mut num_gates = degree - common_data.num_public_inputs.div_ceil(8) - 1 - MAX_CONSTANT_GATES;
534+
#[cfg(feature = "zk")]
535+
{
536+
// in the zk config case, account for the blinding gates, to avoid
537+
// padding to them too, because then plonky2's in the builder.build()
538+
// phase would add new blinding gates on top of the ones that we already
539+
// accounted for in the `common_data_for_recursion`, increasing (w.h.p.)
540+
// the degree of the circuit.
541+
num_gates -= blinding_gates(log2_ceil(degree));
542+
}
543+
488544
assert!(
489545
builder.num_gates() < num_gates,
490546
"builder has more gates ({}) than the padding target ({})",
@@ -678,22 +734,22 @@ mod tests {
678734
}
679735

680736
#[test]
681-
fn test_circuit_i() -> Result<()> {
737+
fn test_inner_circuit_i() -> Result<()> {
682738
let inner_params = ();
683739
let inp = HashOut::<F>::ZERO;
684740

685741
let inner_inputs = (inp, circuit1_io(inp));
686-
test_circuit_i_opt::<Circuit1>(&inner_params, inner_inputs)?;
742+
test_inner_circuit_i_opt::<Circuit1>(&inner_params, inner_inputs)?;
687743

688744
let inner_inputs = (inp, circuit2_io(inp));
689-
test_circuit_i_opt::<Circuit2>(&inner_params, inner_inputs)?;
745+
test_inner_circuit_i_opt::<Circuit2>(&inner_params, inner_inputs)?;
690746

691747
let inner_inputs = (inp, circuit3_io(inp));
692-
test_circuit_i_opt::<Circuit3>(&inner_params, inner_inputs)?;
748+
test_inner_circuit_i_opt::<Circuit3>(&inner_params, inner_inputs)?;
693749

694750
Ok(())
695751
}
696-
fn test_circuit_i_opt<IC: InnerCircuit>(
752+
fn test_inner_circuit_i_opt<IC: InnerCircuit>(
697753
inner_params: &IC::Params,
698754
inner_inputs: IC::Input,
699755
) -> Result<()> {

0 commit comments

Comments
 (0)