diff --git a/halo2_gadgets/benches/poseidon.rs b/halo2_gadgets/benches/poseidon.rs index 744546129f..2768cd3491 100644 --- a/halo2_gadgets/benches/poseidon.rs +++ b/halo2_gadgets/benches/poseidon.rs @@ -32,6 +32,8 @@ use halo2_proofs::{ transcript::{TranscriptReadBuffer, TranscriptWriterBuffer}, }; +const ZK: bool = true; + #[derive(Clone, Copy)] struct HashCircuit where @@ -204,8 +206,9 @@ fn bench_poseidon( }; // Initialize the proving key - let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); + let vk = keygen_vk::<_, _, _, ZK>(¶ms, &empty_circuit).expect("keygen_vk should not fail"); + let pk = + keygen_pk::<_, _, _, ZK>(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); let prover_name = name.to_string() + "-prover"; let verifier_name = name.to_string() + "-verifier"; @@ -228,7 +231,7 @@ fn bench_poseidon( b.iter(|| { // Create a proof let mut transcript = Blake2bWrite::<_, EqAffine, Challenge255<_>>::init(vec![]); - create_proof::, ProverIPA<_>, _, _, _, _>( + create_proof::, ProverIPA<_>, _, _, _, _, ZK>( ¶ms, &pk, &[circuit], @@ -242,7 +245,7 @@ fn bench_poseidon( // Create a proof let mut transcript = Blake2bWrite::<_, EqAffine, Challenge255<_>>::init(vec![]); - create_proof::, ProverIPA<_>, _, _, _, _>( + create_proof::, ProverIPA<_>, _, _, _, _, ZK>( ¶ms, &pk, &[circuit], @@ -257,7 +260,14 @@ fn bench_poseidon( b.iter(|| { let strategy = SingleStrategy::new(¶ms); let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); - assert!(verify_proof(¶ms, pk.get_vk(), strategy, &[&[]], &mut transcript).is_ok()); + assert!(verify_proof::<_, _, _, _, _, ZK>( + ¶ms, + pk.get_vk(), + strategy, + &[&[]], + &mut transcript + ) + .is_ok()); }); }); } diff --git a/halo2_gadgets/benches/sha256.rs b/halo2_gadgets/benches/sha256.rs index 670956cb0d..411c451ca5 100644 --- a/halo2_gadgets/benches/sha256.rs +++ b/halo2_gadgets/benches/sha256.rs @@ -29,6 +29,8 @@ use halo2_proofs::{ transcript::{TranscriptReadBuffer, TranscriptWriterBuffer}, }; +const ZK: bool = true; + #[allow(dead_code)] fn bench(name: &str, k: u32, c: &mut Criterion) { #[derive(Default)] @@ -106,8 +108,9 @@ fn bench(name: &str, k: u32, c: &mut Criterion) { let empty_circuit: MyCircuit = MyCircuit {}; // Initialize the proving key - let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); + let vk = keygen_vk::<_, _, _, ZK>(¶ms, &empty_circuit).expect("keygen_vk should not fail"); + let pk = + keygen_pk::<_, _, _, ZK>(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); let circuit: MyCircuit = MyCircuit {}; @@ -128,7 +131,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) { let proof_path = Path::new("./benches/sha256_assets/sha256_proof"); if File::open(&proof_path).is_err() { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); - create_proof::, ProverIPA<_>, _, _, _, _>( + create_proof::, ProverIPA<_>, _, _, _, _, ZK>( ¶ms, &pk, &[circuit], @@ -153,7 +156,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) { use halo2_proofs::poly::VerificationStrategy; let strategy = AccumulatorStrategy::new(¶ms); let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); - let strategy = verify_proof::, VerifierIPA<_>, _, _, _>( + let strategy = verify_proof::, VerifierIPA<_>, _, _, _, ZK>( ¶ms, pk.get_vk(), strategy, diff --git a/halo2_gadgets/src/ecc.rs b/halo2_gadgets/src/ecc.rs index 08f34b15f2..52946e02fb 100644 --- a/halo2_gadgets/src/ecc.rs +++ b/halo2_gadgets/src/ecc.rs @@ -895,9 +895,11 @@ pub(crate) mod tests { #[test] fn ecc_chip() { + const ZK: bool = true; + let k = 13; let circuit = MyCircuit { test_errors: true }; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } @@ -906,13 +908,15 @@ pub(crate) mod tests { fn print_ecc_chip() { use plotters::prelude::*; + const ZK: bool = true; + let root = BitMapBackend::new("ecc-chip-layout.png", (1024, 7680)).into_drawing_area(); root.fill(&WHITE).unwrap(); let root = root.titled("Ecc Chip Layout", ("sans-serif", 60)).unwrap(); let circuit = MyCircuit { test_errors: false }; halo2_proofs::dev::CircuitLayout::default() - .render(13, &circuit, &root) + .render::<_, _, _, ZK>(13, &circuit, &root) .unwrap(); } } diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs index 844d88d134..16c489405e 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs @@ -403,6 +403,8 @@ pub mod tests { Ok(()) } + const ZK: bool = true; + #[test] fn invalid_magnitude_sign() { use crate::{ @@ -562,7 +564,7 @@ pub mod tests { ]; for circuit in circuits.iter() { - let prover = MockProver::::run(11, circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, circuit, vec![]).unwrap(); circuit.magnitude_error.assert_if_known(|magnitude_error| { assert_eq!( prover.verify(), @@ -620,7 +622,7 @@ pub mod tests { .y() }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![ diff --git a/halo2_gadgets/src/poseidon/pow5.rs b/halo2_gadgets/src/poseidon/pow5.rs index 7b9862e5b6..51a94e3f45 100644 --- a/halo2_gadgets/src/poseidon/pow5.rs +++ b/halo2_gadgets/src/poseidon/pow5.rs @@ -711,9 +711,11 @@ mod tests { #[test] fn poseidon_permute() { + const ZK: bool = true; + let k = 6; let circuit = PermuteCircuit::(PhantomData); - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } @@ -810,6 +812,8 @@ mod tests { #[test] fn poseidon_hash() { + const ZK: bool = true; + let rng = OsRng; let message = [Fp::random(rng), Fp::random(rng)]; @@ -822,12 +826,14 @@ mod tests { output: Value::known(output), _spec: PhantomData, }; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } #[test] fn poseidon_hash_longer_input() { + const ZK: bool = true; + let rng = OsRng; let message = [Fp::random(rng), Fp::random(rng), Fp::random(rng)]; @@ -840,12 +846,14 @@ mod tests { output: Value::known(output), _spec: PhantomData, }; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } #[test] fn hash_test_vectors() { + const ZK: bool = true; + for tv in crate::poseidon::primitives::test_vectors::fp::hash() { let message = [ pallas::Base::from_repr(tv.input[0]).unwrap(), @@ -860,7 +868,7 @@ mod tests { output: Value::known(output), _spec: PhantomData, }; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } } @@ -870,6 +878,8 @@ mod tests { fn print_poseidon_chip() { use plotters::prelude::*; + const ZK: bool = true; + let root = BitMapBackend::new("poseidon-chip-layout.png", (1024, 768)).into_drawing_area(); root.fill(&WHITE).unwrap(); let root = root @@ -882,7 +892,7 @@ mod tests { _spec: PhantomData, }; halo2_proofs::dev::CircuitLayout::default() - .render(6, &circuit, &root) + .render::<_, _, _, ZK>(6, &circuit, &root) .unwrap(); } } diff --git a/halo2_gadgets/src/sha256/table16.rs b/halo2_gadgets/src/sha256/table16.rs index c4919158bc..879d2b8809 100644 --- a/halo2_gadgets/src/sha256/table16.rs +++ b/halo2_gadgets/src/sha256/table16.rs @@ -460,6 +460,8 @@ mod tests { }; use halo2curves::pasta::pallas; + const ZK: bool = true; + #[test] fn print_sha256_circuit() { use plotters::prelude::*; @@ -509,7 +511,7 @@ mod tests { let circuit = MyCircuit {}; halo2_proofs::dev::CircuitLayout::default() - .render::(17, &circuit, &root) + .render::(17, &circuit, &root) .unwrap(); } } diff --git a/halo2_gadgets/src/sha256/table16/compression.rs b/halo2_gadgets/src/sha256/table16/compression.rs index 62deb42937..63b355b064 100644 --- a/halo2_gadgets/src/sha256/table16/compression.rs +++ b/halo2_gadgets/src/sha256/table16/compression.rs @@ -947,6 +947,8 @@ mod tests { }; use halo2curves::pasta::pallas; + const ZK: bool = true; + #[test] fn compress() { struct MyCircuit {} @@ -996,7 +998,7 @@ mod tests { let circuit: MyCircuit = MyCircuit {}; - let prover = match MockProver::::run(17, &circuit, vec![]) { + let prover = match MockProver::::run::<_, ZK>(17, &circuit, vec![]) { Ok(prover) => prover, Err(e) => panic!("{:?}", e), }; diff --git a/halo2_gadgets/src/sha256/table16/message_schedule.rs b/halo2_gadgets/src/sha256/table16/message_schedule.rs index 690e086c49..d2a421c30e 100644 --- a/halo2_gadgets/src/sha256/table16/message_schedule.rs +++ b/halo2_gadgets/src/sha256/table16/message_schedule.rs @@ -404,6 +404,8 @@ mod tests { }; use halo2curves::pasta::pallas; + const ZK: bool = true; + #[test] fn message_schedule() { struct MyCircuit {} @@ -446,7 +448,7 @@ mod tests { let circuit: MyCircuit = MyCircuit {}; - let prover = match MockProver::::run(17, &circuit, vec![]) { + let prover = match MockProver::::run::<_, ZK>(17, &circuit, vec![]) { Ok(prover) => prover, Err(e) => panic!("{:?}", e), }; diff --git a/halo2_gadgets/src/sha256/table16/spread_table.rs b/halo2_gadgets/src/sha256/table16/spread_table.rs index 3e1488e9ac..f13232be14 100644 --- a/halo2_gadgets/src/sha256/table16/spread_table.rs +++ b/halo2_gadgets/src/sha256/table16/spread_table.rs @@ -295,6 +295,8 @@ mod tests { }; use halo2curves::pasta::Fp; + const ZK: bool = true; + #[test] fn lookup_table() { /// This represents an advice column at a certain row in the ConstraintSystem @@ -439,7 +441,7 @@ mod tests { let circuit: MyCircuit = MyCircuit {}; - let prover = match MockProver::::run(17, &circuit, vec![]) { + let prover = match MockProver::::run::<_, ZK>(17, &circuit, vec![]) { Ok(prover) => prover, Err(e) => panic!("{:?}", e), }; diff --git a/halo2_gadgets/src/sinsemilla.rs b/halo2_gadgets/src/sinsemilla.rs index 3cec450ea1..f52aa9d1cf 100644 --- a/halo2_gadgets/src/sinsemilla.rs +++ b/halo2_gadgets/src/sinsemilla.rs @@ -731,9 +731,11 @@ pub(crate) mod tests { #[test] fn sinsemilla_chip() { + const ZK: bool = true; + let k = 11; let circuit = MyCircuit {}; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } @@ -742,6 +744,8 @@ pub(crate) mod tests { fn print_sinsemilla_chip() { use plotters::prelude::*; + const ZK: bool = true; + let root = BitMapBackend::new("sinsemilla-hash-layout.png", (1024, 7680)).into_drawing_area(); root.fill(&WHITE).unwrap(); @@ -749,7 +753,7 @@ pub(crate) mod tests { let circuit = MyCircuit {}; halo2_proofs::dev::CircuitLayout::default() - .render(11, &circuit, &root) + .render::<_, _, _, ZK>(11, &circuit, &root) .unwrap(); } } diff --git a/halo2_gadgets/src/sinsemilla/merkle.rs b/halo2_gadgets/src/sinsemilla/merkle.rs index a9ae781d5c..f17ededabe 100644 --- a/halo2_gadgets/src/sinsemilla/merkle.rs +++ b/halo2_gadgets/src/sinsemilla/merkle.rs @@ -357,6 +357,8 @@ pub mod tests { #[test] fn merkle_chip() { + const ZK: bool = true; + let mut rng = OsRng; // Choose a random leaf and position @@ -376,7 +378,7 @@ pub mod tests { merkle_path: Value::known(path.try_into().unwrap()), }; - let prover = MockProver::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } @@ -385,6 +387,8 @@ pub mod tests { fn print_merkle_chip() { use plotters::prelude::*; + const ZK: bool = true; + let root = BitMapBackend::new("merkle-path-layout.png", (1024, 7680)).into_drawing_area(); root.fill(&WHITE).unwrap(); let root = root.titled("MerkleCRH Path", ("sans-serif", 60)).unwrap(); @@ -392,7 +396,7 @@ pub mod tests { let circuit = MyCircuit::default(); halo2_proofs::dev::CircuitLayout::default() .show_labels(false) - .render(11, &circuit, &root) + .render::<_, _, _, ZK>(11, &circuit, &root) .unwrap(); } } diff --git a/halo2_gadgets/src/utilities.rs b/halo2_gadgets/src/utilities.rs index fa50f7e8e8..6e2691afd0 100644 --- a/halo2_gadgets/src/utilities.rs +++ b/halo2_gadgets/src/utilities.rs @@ -312,15 +312,17 @@ mod tests { } } + const ZK: bool = true; + for i in 0..8 { let circuit: MyCircuit<8> = MyCircuit(i); - let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } { let circuit: MyCircuit<8> = MyCircuit(8); - let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(3, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::ConstraintNotSatisfied { diff --git a/halo2_gadgets/src/utilities/cond_swap.rs b/halo2_gadgets/src/utilities/cond_swap.rs index 9dc1afa3ef..ad0f4c28d5 100644 --- a/halo2_gadgets/src/utilities/cond_swap.rs +++ b/halo2_gadgets/src/utilities/cond_swap.rs @@ -266,6 +266,8 @@ mod tests { } } + const ZK: bool = true; + let rng = OsRng; // Test swap case @@ -275,7 +277,7 @@ mod tests { b: Value::known(Base::random(rng)), swap: Value::known(true), }; - let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -286,7 +288,7 @@ mod tests { b: Value::known(Base::random(rng)), swap: Value::known(false), }; - let prover = MockProver::::run(3, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(3, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } } diff --git a/halo2_gadgets/src/utilities/decompose_running_sum.rs b/halo2_gadgets/src/utilities/decompose_running_sum.rs index 89508f176c..5b71940b58 100644 --- a/halo2_gadgets/src/utilities/decompose_running_sum.rs +++ b/halo2_gadgets/src/utilities/decompose_running_sum.rs @@ -237,6 +237,8 @@ mod tests { strict: bool, } + const ZK: bool = true; + impl< F: FieldExt + PrimeFieldBits, const WORD_NUM_BITS: usize, @@ -309,7 +311,7 @@ mod tests { alpha: Value::known(alpha), strict: true, }; - let prover = MockProver::::run(8, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(8, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -327,7 +329,7 @@ mod tests { alpha: Value::known(alpha), strict: true, }; - let prover = MockProver::::run(8, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(8, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -345,7 +347,7 @@ mod tests { alpha: Value::known(alpha), strict: true, }; - let prover = MockProver::::run(8, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(8, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![ @@ -384,7 +386,7 @@ mod tests { alpha: Value::known(alpha), strict: false, }; - let prover = MockProver::::run(8, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(8, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } } diff --git a/halo2_gadgets/src/utilities/lookup_range_check.rs b/halo2_gadgets/src/utilities/lookup_range_check.rs index f97654c38b..addc2612e8 100644 --- a/halo2_gadgets/src/utilities/lookup_range_check.rs +++ b/halo2_gadgets/src/utilities/lookup_range_check.rs @@ -485,13 +485,15 @@ mod tests { } } + const ZK: bool = true; + { let circuit: MyCircuit = MyCircuit { num_words: 6, _marker: PhantomData, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } } @@ -542,13 +544,15 @@ mod tests { } } + const ZK: bool = true; + // Edge case: zero bits { let circuit: MyCircuit = MyCircuit { element: Value::known(pallas::Base::zero()), num_bits: 0, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -558,7 +562,7 @@ mod tests { element: Value::known(pallas::Base::from((1 << K) - 1)), num_bits: K, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -568,7 +572,7 @@ mod tests { element: Value::known(pallas::Base::from((1 << 6) - 1)), num_bits: 6, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())); } @@ -578,7 +582,7 @@ mod tests { element: Value::known(pallas::Base::from(1 << 6)), num_bits: 6, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::Lookup { @@ -598,7 +602,7 @@ mod tests { element: Value::known(pallas::Base::from(1 << K)), num_bits: 6, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![ @@ -637,7 +641,7 @@ mod tests { element: Value::known(element), num_bits: num_bits as usize, }; - let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + let prover = MockProver::::run::<_, ZK>(11, &circuit, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::Lookup { diff --git a/halo2_proofs/benches/dev_lookup.rs b/halo2_proofs/benches/dev_lookup.rs index bb6cfdadbf..96da47f17b 100644 --- a/halo2_proofs/benches/dev_lookup.rs +++ b/halo2_proofs/benches/dev_lookup.rs @@ -12,6 +12,8 @@ use std::marker::PhantomData; use criterion::{BenchmarkId, Criterion}; +const ZK: bool = true; + fn criterion_benchmark(c: &mut Criterion) { #[derive(Clone, Default)] struct MyCircuit { @@ -94,7 +96,8 @@ fn criterion_benchmark(c: &mut Criterion) { let circuit = MyCircuit:: { _marker: PhantomData, }; - let prover = MockProver::run(k, &circuit, vec![]).unwrap(); + + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); assert_eq!(prover.verify(), Ok(())) } diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index a679961463..7e7953e139 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -26,6 +26,8 @@ use std::marker::PhantomData; use criterion::{BenchmarkId, Criterion}; +const ZK: bool = true; + fn criterion_benchmark(c: &mut Criterion) { /// This represents an advice column at a certain row in the ConstraintSystem #[derive(Copy, Clone, Debug)] @@ -271,8 +273,10 @@ fn criterion_benchmark(c: &mut Criterion) { a: Value::unknown(), k, }; - let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail"); + let vk = + keygen_vk::<_, _, _, ZK>(¶ms, &empty_circuit).expect("keygen_vk should not fail"); + let pk = keygen_pk::<_, _, _, ZK>(¶ms, vk, &empty_circuit) + .expect("keygen_pk should not fail"); (params, pk) } @@ -285,7 +289,7 @@ fn criterion_benchmark(c: &mut Criterion) { }; let mut transcript = Blake2bWrite::<_, _, Challenge255>::init(vec![]); - create_proof::, ProverIPA, _, _, _, _>( + create_proof::, ProverIPA, _, _, _, _, ZK>( params, pk, &[circuit], @@ -300,7 +304,10 @@ fn criterion_benchmark(c: &mut Criterion) { fn verifier(params: &ParamsIPA, vk: &VerifyingKey, proof: &[u8]) { let strategy = SingleStrategy::new(params); let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(proof); - assert!(verify_proof(params, vk, strategy, &[&[]], &mut transcript).is_ok()); + assert!( + verify_proof::<_, _, _, _, _, ZK>(params, vk, strategy, &[&[]], &mut transcript) + .is_ok() + ); } let k_range = 8..=16; diff --git a/halo2_proofs/examples/circuit-layout.rs b/halo2_proofs/examples/circuit-layout.rs index beb99502bd..3c9265e567 100644 --- a/halo2_proofs/examples/circuit-layout.rs +++ b/halo2_proofs/examples/circuit-layout.rs @@ -272,6 +272,8 @@ impl Circuit for MyCircuit { // ANCHOR: dev-graph fn main() { + const ZK: bool = true; + // Prepare the circuit you want to render. // You don't need to include any witness variables. let a = Fp::random(OsRng); @@ -299,7 +301,7 @@ fn main() { .show_labels(false) // Render the circuit onto your area! // The first argument is the size parameter for the circuit. - .render(5, &circuit, &root) + .render::<_, _, _, ZK>(5, &circuit, &root) .unwrap(); } // ANCHOR_END: dev-graph diff --git a/halo2_proofs/examples/shuffle.rs b/halo2_proofs/examples/shuffle.rs index 1926074371..65f71b653d 100644 --- a/halo2_proofs/examples/shuffle.rs +++ b/halo2_proofs/examples/shuffle.rs @@ -253,12 +253,12 @@ impl Circuit for MyCircuit( +fn test_mock_prover( k: u32, circuit: MyCircuit, expected: Result<(), Vec<(metadata::Constraint, FailureLocation)>>, ) { - let prover = MockProver::run::<_>(k, &circuit, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![]).unwrap(); match (prover.verify(), expected) { (Ok(_), Ok(_)) => {} (Err(err), Err(expected)) => { @@ -280,19 +280,19 @@ fn test_mock_prover( }; } -fn test_prover( +fn test_prover( k: u32, circuit: MyCircuit, expected: bool, ) { let params = ParamsIPA::::new(k); - let vk = keygen_vk(¶ms, &circuit).unwrap(); - let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); + let vk = keygen_vk::<_, _, _, ZK>(¶ms, &circuit).unwrap(); + let pk = keygen_pk::<_, _, _, ZK>(¶ms, vk, &circuit).unwrap(); let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); - create_proof::, ProverIPA, _, _, _, _>( + create_proof::, ProverIPA, _, _, _, _, ZK>( ¶ms, &pk, &[circuit], @@ -309,7 +309,7 @@ fn test_prover( let strategy = AccumulatorStrategy::new(¶ms); let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); - verify_proof::, VerifierIPA, _, _, _>( + verify_proof::, VerifierIPA, _, _, _, ZK>( ¶ms, pk.get_vk(), strategy, @@ -324,6 +324,7 @@ fn test_prover( } fn main() { + const ZK: bool = true; const W: usize = 4; const H: usize = 32; const K: u32 = 8; @@ -331,8 +332,8 @@ fn main() { let circuit = &MyCircuit::<_, W, H>::rand(&mut OsRng); { - test_mock_prover(K, circuit.clone(), Ok(())); - test_prover::(K, circuit.clone(), true); + test_mock_prover::<_, W, H, ZK>(K, circuit.clone(), Ok(())); + test_prover::(K, circuit.clone(), true); } #[cfg(not(feature = "sanity-checks"))] @@ -345,7 +346,7 @@ fn main() { shuffled }); - test_mock_prover( + test_mock_prover::<_, W, H, ZK>( K, circuit.clone(), Err(vec![( @@ -356,6 +357,6 @@ fn main() { }, )]), ); - test_prover::(K, circuit, false); + test_prover::(K, circuit, false); } } diff --git a/halo2_proofs/examples/simple-example.rs b/halo2_proofs/examples/simple-example.rs index c5e7a9f282..64a602e10c 100644 --- a/halo2_proofs/examples/simple-example.rs +++ b/halo2_proofs/examples/simple-example.rs @@ -306,6 +306,9 @@ fn main() { use halo2_proofs::dev::MockProver; use halo2curves::pasta::Fp; + const ZK: bool = true; + const ZKFREE: bool = false; + // ANCHOR: test-circuit // The number of rows in our circuit cannot exceed 2^k. Since our example // circuit is very small, we can pick a very small value here. @@ -327,14 +330,29 @@ fn main() { // Arrange the public input. We expose the multiplication result in row 0 // of the instance column, so we position it there in our public inputs. let mut public_inputs = vec![c]; + { + // Given the correct public input, our circuit will verify. + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![public_inputs.clone()]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + // If we try some other public input, the proof will fail! + public_inputs[0] += Fp::one(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![public_inputs]).unwrap(); + assert!(prover.verify().is_err()); + // ANCHOR_END: test-circuit + } - // Given the correct public input, our circuit will verify. - let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap(); - assert_eq!(prover.verify(), Ok(())); - - // If we try some other public input, the proof will fail! - public_inputs[0] += Fp::one(); - let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap(); - assert!(prover.verify().is_err()); - // ANCHOR_END: test-circuit + let mut public_inputs = vec![c]; + { + // Given the correct public input, our circuit will verify. + let prover = + MockProver::run::<_, ZKFREE>(k, &circuit, vec![public_inputs.clone()]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + // If we try some other public input, the proof will fail! + public_inputs[0] += Fp::one(); + let prover = MockProver::run::<_, ZKFREE>(k, &circuit, vec![public_inputs]).unwrap(); + assert!(prover.verify().is_err()); + // ANCHOR_END: test-circuit + } } diff --git a/halo2_proofs/examples/two-chip.rs b/halo2_proofs/examples/two-chip.rs index 61d40f93ca..09c53b3204 100644 --- a/halo2_proofs/examples/two-chip.rs +++ b/halo2_proofs/examples/two-chip.rs @@ -501,6 +501,9 @@ fn main() { use halo2curves::pasta::Fp; use rand_core::OsRng; + const ZK: bool = true; + const ZKFREE: bool = false; + // ANCHOR: test-circuit // The number of rows in our circuit cannot exceed 2^k. Since our example // circuit is very small, we can pick a very small value here. @@ -523,14 +526,29 @@ fn main() { // Arrange the public input. We expose the multiplication result in row 0 // of the instance column, so we position it there in our public inputs. let mut public_inputs = vec![d]; + { + // Given the correct public input, our circuit will verify. + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![public_inputs.clone()]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + // If we try some other public input, the proof will fail! + public_inputs[0] += Fp::one(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![public_inputs]).unwrap(); + assert!(prover.verify().is_err()); + // ANCHOR_END: test-circuit + } - // Given the correct public input, our circuit will verify. - let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap(); - assert_eq!(prover.verify(), Ok(())); - - // If we try some other public input, the proof will fail! - public_inputs[0] += Fp::one(); - let prover = MockProver::run(k, &circuit, vec![public_inputs]).unwrap(); - assert!(prover.verify().is_err()); - // ANCHOR_END: test-circuit + let mut public_inputs = vec![c]; + { + // Given the correct public input, our circuit will verify. + let prover = + MockProver::run::<_, ZKFREE>(k, &circuit, vec![public_inputs.clone()]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + + // If we try some other public input, the proof will fail! + public_inputs[0] += Fp::one(); + let prover = MockProver::run::<_, ZK>(k, &circuit, vec![public_inputs]).unwrap(); + assert!(prover.verify().is_err()); + // ANCHOR_END: test-circuit + } } diff --git a/halo2_proofs/src/circuit/floor_planner/single_pass.rs b/halo2_proofs/src/circuit/floor_planner/single_pass.rs index 3798efbe54..0c773b398d 100644 --- a/halo2_proofs/src/circuit/floor_planner/single_pass.rs +++ b/halo2_proofs/src/circuit/floor_planner/single_pass.rs @@ -466,6 +466,8 @@ mod tests { #[test] fn not_enough_columns_for_constants() { + const ZK: bool = true; + struct MyCircuit {} impl Circuit for MyCircuit { @@ -503,7 +505,7 @@ mod tests { let circuit = MyCircuit {}; assert!(matches!( - MockProver::run(3, &circuit, vec![]).unwrap_err(), + MockProver::run::<_, ZK>(3, &circuit, vec![]).unwrap_err(), Error::NotEnoughColumnsForConstants, )); } diff --git a/halo2_proofs/src/circuit/floor_planner/v1.rs b/halo2_proofs/src/circuit/floor_planner/v1.rs index 62207a91a7..fc09671175 100644 --- a/halo2_proofs/src/circuit/floor_planner/v1.rs +++ b/halo2_proofs/src/circuit/floor_planner/v1.rs @@ -504,6 +504,8 @@ mod tests { #[test] fn not_enough_columns_for_constants() { + const ZK: bool = true; + struct MyCircuit {} impl Circuit for MyCircuit { @@ -541,7 +543,7 @@ mod tests { let circuit = MyCircuit {}; assert!(matches!( - MockProver::run(3, &circuit, vec![]).unwrap_err(), + MockProver::run::<_, ZK>(3, &circuit, vec![]).unwrap_err(), Error::NotEnoughColumnsForConstants, )); } diff --git a/halo2_proofs/src/dev.rs b/halo2_proofs/src/dev.rs index b5b92d390f..24e646d7ae 100644 --- a/halo2_proofs/src/dev.rs +++ b/halo2_proofs/src/dev.rs @@ -250,8 +250,8 @@ impl Mul for Value { /// /// // This circuit has no public inputs. /// let instance = vec![]; -/// -/// let prover = MockProver::::run(K, &circuit, instance).unwrap(); +/// const ZK :bool = true; +/// let prover = MockProver::::run::<_, ZK>(K, &circuit, instance).unwrap(); /// assert_eq!( /// prover.verify(), /// Err(vec![VerifyFailure::ConstraintNotSatisfied { @@ -270,7 +270,7 @@ impl Mul for Value { /// /// // If we provide a too-small K, we get an error. /// assert!(matches!( -/// MockProver::::run(2, &circuit, vec![]).unwrap_err(), +/// MockProver::::run::<_, ZK>(2, &circuit, vec![]).unwrap_err(), /// Error::NotEnoughRowsAvailable { /// current_k, /// } if current_k == 2, @@ -489,7 +489,7 @@ impl Assignment for MockProver { impl MockProver { /// Runs a synthetic keygen-and-prove operation on the given circuit, collecting data /// about the constraints and their assignments. - pub fn run>( + pub fn run, const ZK: bool>( k: u32, circuit: &ConcreteCircuit, instance: Vec>, @@ -500,7 +500,7 @@ impl MockProver { let config = ConcreteCircuit::configure(&mut cs); let cs = cs; - if n < cs.minimum_rows() { + if n < cs.minimum_rows::() { return Err(Error::not_enough_rows_available(k)); } @@ -511,7 +511,7 @@ impl MockProver { let instance = instance .into_iter() .map(|mut instance| { - if instance.len() > n - (cs.blinding_factors() + 1) { + if instance.len() > cs.usable_rows::(n).end { return Err(Error::InstanceTooLarge); } @@ -524,8 +524,7 @@ impl MockProver { let fixed = vec![vec![CellValue::Unassigned; n]; cs.num_fixed_columns]; let selectors = vec![vec![false; n]; cs.num_selectors]; // Advice columns contain blinding factors. - let blinding_factors = cs.blinding_factors(); - let usable_rows = n - (blinding_factors + 1); + let usable_rows = cs.usable_rows::(n).end; let advice = vec![ { let mut column = vec![CellValue::Unassigned; n]; @@ -568,7 +567,7 @@ impl MockProver { ConcreteCircuit::FloorPlanner::synthesize(&mut prover, circuit, config, constants)?; - let (cs, selector_polys) = prover.cs.compress_selectors(prover.selectors.clone()); + let (cs, selector_polys) = prover.cs.compress_selectors::(prover.selectors.clone()); prover.cs = cs; prover.fixed.extend(selector_polys.into_iter().map(|poly| { let mut v = vec![CellValue::Unassigned; n]; @@ -661,8 +660,7 @@ impl MockProver { .iter() .enumerate() .flat_map(|(gate_index, gate)| { - let blinding_rows = - (self.n as usize - (self.cs.blinding_factors() + 1))..(self.n as usize); + let blinding_rows = self.usable_rows.end..self.n as usize; (gate_row_ids .clone() .into_iter() @@ -1027,8 +1025,7 @@ impl MockProver { .iter() .enumerate() .flat_map(|(gate_index, gate)| { - let blinding_rows = - (self.n as usize - (self.cs.blinding_factors() + 1))..(self.n as usize); + let blinding_rows = self.usable_rows.end..self.n as usize; (gate_row_ids .clone() .into_par_iter() @@ -1333,6 +1330,7 @@ mod tests { #[test] fn unassigned_cell() { + const ZK: bool = true; const K: u32 = 4; #[derive(Clone)] @@ -1390,8 +1388,7 @@ mod tests { ) } } - - let prover = MockProver::run(K, &FaultyCircuit {}, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(K, &FaultyCircuit {}, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::CellNotAssigned { @@ -1406,6 +1403,7 @@ mod tests { #[test] fn bad_lookup() { + const ZK: bool = true; const K: u32 = 4; #[derive(Clone)] @@ -1519,7 +1517,7 @@ mod tests { } } - let prover = MockProver::run(K, &FaultyCircuit {}, vec![]).unwrap(); + let prover = MockProver::run::<_, ZK>(K, &FaultyCircuit {}, vec![]).unwrap(); assert_eq!( prover.verify(), Err(vec![VerifyFailure::Lookup { diff --git a/halo2_proofs/src/dev/cost.rs b/halo2_proofs/src/dev/cost.rs index ad6f8b1eec..84e016e70e 100644 --- a/halo2_proofs/src/dev/cost.rs +++ b/halo2_proofs/src/dev/cost.rs @@ -139,7 +139,7 @@ impl> CircuitCost Self { + pub fn measure(k: usize, circuit: &ConcreteCircuit) -> Self { // Collect the layout details. let mut cs = ConstraintSystem::default(); let config = ConcreteCircuit::configure(&mut cs); @@ -153,9 +153,9 @@ impl> CircuitCost(assembly.selectors); - assert!((1 << k) >= cs.minimum_rows()); + assert!((1 << k) >= cs.minimum_rows::()); // Figure out how many point sets we have due to queried cells. let mut column_queries: HashMap, HashSet> = HashMap::new(); @@ -191,11 +191,11 @@ impl> CircuitCost(); let permutation_cols = cs.permutation.get_columns().len(); if permutation_cols > max_deg - 2 { // permutation_product_poly for chaining chunks. - point_sets.insert(vec![-((cs.blinding_factors() + 1) as i32), 0, 1]); + point_sets.insert(vec![-((cs.blinding_factors::() + 1) as i32), 0, 1]); } CircuitCost { diff --git a/halo2_proofs/src/dev/graph/layout.rs b/halo2_proofs/src/dev/graph/layout.rs index 81f45a9010..25032fceb3 100644 --- a/halo2_proofs/src/dev/graph/layout.rs +++ b/halo2_proofs/src/dev/graph/layout.rs @@ -36,7 +36,7 @@ use crate::{ /// /// let circuit = MyCircuit::default(); /// let k = 5; // Suitable size for MyCircuit -/// CircuitLayout::default().render(k, &circuit, &drawing_area).unwrap(); +/// CircuitLayout::default().render::<_, _, _, true>(k, &circuit, &drawing_area).unwrap(); /// ``` #[derive(Debug, Default)] pub struct CircuitLayout { @@ -85,7 +85,7 @@ impl CircuitLayout { } /// Renders the given circuit on the given drawing area. - pub fn render, DB: DrawingBackend>( + pub fn render, DB: DrawingBackend, const ZK: bool>( self, k: u32, circuit: &ConcreteCircuit, @@ -106,7 +106,7 @@ impl CircuitLayout { cs.constants.clone(), ) .unwrap(); - let (cs, selector_polys) = cs.compress_selectors(layout.selectors); + let (cs, selector_polys) = cs.compress_selectors::(layout.selectors); let non_selector_fixed_columns = cs.num_fixed_columns - selector_polys.len(); // Figure out what order to render the columns in. @@ -171,7 +171,7 @@ impl CircuitLayout { } // Mark the unusable rows of the circuit. - let usable_rows = n - (cs.blinding_factors() + 1); + let usable_rows = n - (cs.blinding_factors::() + 1); if view_bottom > usable_rows { root.draw(&Rectangle::new( [(0, usable_rows), (total_columns, view_bottom)], diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index f9a6587af6..06f746bac0 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -53,14 +53,14 @@ pub struct VerifyingKey { } impl VerifyingKey { - fn from_parts( + fn from_parts( domain: EvaluationDomain, fixed_commitments: Vec, permutation: permutation::VerifyingKey, cs: ConstraintSystem, ) -> Self { // Compute cached values. - let cs_degree = cs.degree(); + let cs_degree = cs.degree::(); let mut vk = Self { domain, diff --git a/halo2_proofs/src/plonk/circuit.rs b/halo2_proofs/src/plonk/circuit.rs index 7ad8d8b8e1..1f41dd34ba 100644 --- a/halo2_proofs/src/plonk/circuit.rs +++ b/halo2_proofs/src/plonk/circuit.rs @@ -3,7 +3,7 @@ use core::ops::{Add, Mul}; use ff::Field; use std::{ convert::TryFrom, - ops::{Neg, Sub}, + ops::{Neg, Range, Sub}, }; use super::{lookup, permutation, Assigned, Error}; @@ -1677,7 +1677,10 @@ impl ConstraintSystem { /// find which fixed column corresponds with a given `Selector`. /// /// Do not call this twice. Yes, this should be a builder pattern instead. - pub(crate) fn compress_selectors(mut self, selectors: Vec>) -> (Self, Vec>) { + pub(crate) fn compress_selectors( + mut self, + selectors: Vec>, + ) -> (Self, Vec>) { // The number of provided selector assignments must be the number we // counted for this constraint system. assert_eq!(selectors.len(), self.num_selectors); @@ -1695,7 +1698,7 @@ impl ConstraintSystem { // We will not increase the degree of the constraint system, so we limit // ourselves to the largest existing degree constraint. - let max_degree = self.degree(); + let max_degree = self.degree::(); let mut new_columns = vec![]; let (polys, selector_assignment) = compress_selectors::process( @@ -1900,7 +1903,7 @@ impl ConstraintSystem { /// Compute the degree of the constraint system (the maximum degree of all /// constraints). - pub fn degree(&self) -> usize { + pub fn degree(&self) -> usize { // The permutation argument will serve alongside the gates, so must be // accounted for. let mut degree = self.permutation.required_degree(); @@ -1911,7 +1914,7 @@ impl ConstraintSystem { degree, self.lookups .iter() - .map(|l| l.required_degree()) + .map(|l| l.required_degree::()) .max() .unwrap_or(1), ); @@ -1932,7 +1935,11 @@ impl ConstraintSystem { /// Compute the number of blinding factors necessary to perfectly blind /// each of the prover's witness polynomials. - pub fn blinding_factors(&self) -> usize { + pub fn blinding_factors(&self) -> usize { + if !ZK { + return 0; + } + // All of the prover's advice columns are evaluated at no more than let factors = *self.num_advice_queries.iter().max().unwrap_or(&1); // distinct points during gate checks. @@ -1959,16 +1966,29 @@ impl ConstraintSystem { factors + 1 } + /// Returns usable rows of circuit. + pub fn usable_rows(&self, n: usize) -> Range { + if ZK { + 0..n - (self.blinding_factors::() + 1) + } else { + 0..n + } + } + /// Returns the minimum necessary rows that need to exist in order to /// account for e.g. blinding factors. - pub fn minimum_rows(&self) -> usize { - self.blinding_factors() // m blinding factors - + 1 // for l_{-(m + 1)} (l_last) - + 1 // for l_0 (just for extra breathing room for the permutation - // argument, to essentially force a separation in the - // permutation polynomial between the roles of l_last, l_0 - // and the interstitial values.) - + 1 // for at least one row + pub fn minimum_rows(&self) -> usize { + if !ZK { + return 1; // for at least one row + } + + self.blinding_factors::() // m blinding factors + + 1 // for l_{-(m + 1)} (l_last) + + 1 // for l_0 (just for extra breathing room for the permutation + // argument, to essentially force a separation in the + // permutation polynomial between the roles of l_last, l_0 + // and the interstitial values.) + + 1 // for at least one row } /// Returns number of fixed columns diff --git a/halo2_proofs/src/plonk/evaluation.rs b/halo2_proofs/src/plonk/evaluation.rs index f324a4d438..fc6fab7476 100644 --- a/halo2_proofs/src/plonk/evaluation.rs +++ b/halo2_proofs/src/plonk/evaluation.rs @@ -277,7 +277,7 @@ impl Evaluator { } /// Evaluate h poly - pub(in crate::plonk) fn evaluate_h( + pub(in crate::plonk) fn evaluate_h( &self, pk: &ProvingKey, advice_polys: &[&[Polynomial]], @@ -364,9 +364,13 @@ impl Evaluator { // Permutations let sets = &permutation.sets; if !sets.is_empty() { - let blinding_factors = pk.vk.cs.blinding_factors(); + let blinding_factors = pk.vk.cs.blinding_factors::(); let last_rotation = Rotation(-((blinding_factors + 1) as i32)); - let chunk_len = pk.vk.cs.degree() - 2; + let chunk_len = if ZK || pk.vk.permutation.commitments().len() >= pk.vk.cs_degree { + pk.vk.cs_degree - 2 + } else { + pk.vk.cs_degree - 1 + }; let delta_start = beta * &C::Scalar::ZETA; let first_set = sets.first().unwrap(); @@ -384,36 +388,49 @@ impl Evaluator { // l_0(X) * (1 - z_0(X)) = 0 *value = *value * y + ((one - first_set.permutation_product_coset[idx]) * l0[idx]); - // Enforce only for the last set. - // l_last(X) * (z_l(X)^2 - z_l(X)) = 0 - *value = *value * y - + ((last_set.permutation_product_coset[idx] - * last_set.permutation_product_coset[idx] - - last_set.permutation_product_coset[idx]) - * l_last[idx]); - // Except for the first set, enforce. - // l_0(X) * (z_i(X) - z_{i-1}(\omega^(last) X)) = 0 - for (set_idx, set) in sets.iter().enumerate() { - if set_idx != 0 { - *value = *value * y - + ((set.permutation_product_coset[idx] - - permutation.sets[set_idx - 1].permutation_product_coset - [r_last]) - * l0[idx]); + + if ZK { + // Enforce only for the last set. + // l_last(X) * (z_l(X)^2 - z_l(X)) = 0 + *value = *value * y + + ((last_set.permutation_product_coset[idx] + * last_set.permutation_product_coset[idx] + - last_set.permutation_product_coset[idx]) + * l_last[idx]); + + // Except for the first set, enforce. + // l_0(X) * (z_i(X) - z_{i-1}(\omega^(last) X)) = 0 + for (set_idx, set) in sets.iter().enumerate() { + if set_idx != 0 { + *value = *value * y + + ((set.permutation_product_coset[idx] + - permutation.sets[set_idx - 1] + .permutation_product_coset[r_last]) + * l0[idx]); + } } } + // And for all the sets we enforce: // (1 - (l_last(X) + l_blind(X))) * ( // z_i(\omega X) \prod_j (p(X) + \beta s_j(X) + \gamma) // - z_i(X) \prod_j (p(X) + \delta^j \beta X + \gamma) // ) let mut current_delta = delta_start * beta_term; - for ((set, columns), cosets) in sets + for (((set, next_set), columns), cosets) in sets .iter() + .zip(sets.iter().cycle().skip(1)) .zip(p.columns.chunks(chunk_len)) .zip(pk.permutation.cosets.chunks(chunk_len)) { - let mut left = set.permutation_product_coset[r_next]; + let mut left = if ZK || sets.len() == 1 { + set.permutation_product_coset[r_next] + } else { + set.permutation_product_coset[r_next] + + l_last[idx] + * (next_set.permutation_product_coset[r_next] + - set.permutation_product_coset[r_next]) + }; for (values, permutation) in columns .iter() .map(|&column| match column.column_type() { @@ -436,7 +453,12 @@ impl Evaluator { current_delta *= &C::Scalar::DELTA; } - *value = *value * y + ((left - right) * l_active_row[idx]); + *value = *value * y + + if ZK { + (left - right) * l_active_row[idx] + } else { + left - right + }; } beta_term *= &extended_omega; } @@ -487,33 +509,49 @@ impl Evaluator { let a_minus_s = permuted_input_coset[idx] - permuted_table_coset[idx]; // l_0(X) * (1 - z(X)) = 0 *value = *value * y + ((one - product_coset[idx]) * l0[idx]); - // l_last(X) * (z(X)^2 - z(X)) = 0 - *value = *value * y - + ((product_coset[idx] * product_coset[idx] - product_coset[idx]) - * l_last[idx]); + if ZK { + // l_last(X) * (z(X)^2 - z(X)) = 0 + *value = *value * y + + ((product_coset[idx] * product_coset[idx] - product_coset[idx]) + * l_last[idx]); + } // (1 - (l_last(X) + l_blind(X))) * ( // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) // (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) // ) = 0 *value = *value * y - + ((product_coset[r_next] - * (permuted_input_coset[idx] + beta) - * (permuted_table_coset[idx] + gamma) - - product_coset[idx] * table_value) - * l_active_row[idx]); - // Check that the first values in the permuted input expression and permuted - // fixed expression are the same. - // l_0(X) * (a'(X) - s'(X)) = 0 - *value = *value * y + (a_minus_s * l0[idx]); + + if ZK { + (product_coset[r_next] + * (permuted_input_coset[idx] + beta) + * (permuted_table_coset[idx] + gamma) + - product_coset[idx] * table_value) + * l_active_row[idx] + } else { + product_coset[r_next] + * (permuted_input_coset[idx] + beta) + * (permuted_table_coset[idx] + gamma) + - product_coset[idx] * table_value + }; + if ZK { + // Check that the first values in the permuted input expression and permuted + // fixed expression are the same. + // l_0(X) * (a'(X) - s'(X)) = 0 + *value = *value * y + (a_minus_s * l0[idx]); + } // Check that each value in the permuted lookup input expression is either // equal to the value above it, or the value at the same index in the // permuted table expression. // (1 - (l_last + l_blind)) * (a′(X) − s′(X))⋅(a′(X) − a′(\omega^{-1} X)) = 0 *value = *value * y - + (a_minus_s - * (permuted_input_coset[idx] - permuted_input_coset[r_prev]) - * l_active_row[idx]); + + if ZK { + a_minus_s + * (permuted_input_coset[idx] - permuted_input_coset[r_prev]) + * l_active_row[idx] + } else { + a_minus_s + * (permuted_input_coset[idx] - permuted_input_coset[r_prev]) + }; } }); } diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index 39cef34c0f..bd59ee4521 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -24,7 +24,7 @@ use crate::{ }, }; -pub(crate) fn create_domain( +pub(crate) fn create_domain( k: u32, ) -> ( EvaluationDomain, @@ -38,7 +38,7 @@ where let mut cs = ConstraintSystem::default(); let config = ConcreteCircuit::configure(&mut cs); - let degree = cs.degree(); + let degree = cs.degree::(); let domain = EvaluationDomain::new(degree as u32, k); @@ -192,7 +192,7 @@ impl Assignment for Assembly { } /// Generate a `VerifyingKey` from an instance of `Circuit`. -pub fn keygen_vk<'params, C, P, ConcreteCircuit>( +pub fn keygen_vk<'params, C, P, ConcreteCircuit, const ZK: bool>( params: &P, circuit: &ConcreteCircuit, ) -> Result, Error> @@ -201,9 +201,9 @@ where P: Params<'params, C>, ConcreteCircuit: Circuit, { - let (domain, cs, config) = create_domain::(params.k()); + let (domain, cs, config) = create_domain::(params.k()); - if (params.n() as usize) < cs.minimum_rows() { + if (params.n() as usize) < cs.minimum_rows::() { return Err(Error::not_enough_rows_available(params.k())); } @@ -212,7 +212,7 @@ where fixed: vec![domain.empty_lagrange_assigned(); cs.num_fixed_columns], permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation), selectors: vec![vec![false; params.n() as usize]; cs.num_selectors], - usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1), + usable_rows: cs.usable_rows::(params.n() as usize), _marker: std::marker::PhantomData, }; @@ -225,7 +225,7 @@ where )?; let mut fixed = batch_invert_assigned(assembly.fixed); - let (cs, selector_polys) = cs.compress_selectors(assembly.selectors); + let (cs, selector_polys) = cs.compress_selectors::(assembly.selectors); fixed.extend( selector_polys .into_iter() @@ -241,7 +241,7 @@ where .map(|poly| params.commit_lagrange(poly, Blind::default()).to_affine()) .collect(); - Ok(VerifyingKey::from_parts( + Ok(VerifyingKey::from_parts::( domain, fixed_commitments, permutation_vk, @@ -250,7 +250,7 @@ where } /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. -pub fn keygen_pk<'params, C, P, ConcreteCircuit>( +pub fn keygen_pk<'params, C, P, ConcreteCircuit, const ZK: bool>( params: &P, vk: VerifyingKey, circuit: &ConcreteCircuit, @@ -265,7 +265,7 @@ where let cs = cs; - if (params.n() as usize) < cs.minimum_rows() { + if (params.n() as usize) < cs.minimum_rows::() { return Err(Error::not_enough_rows_available(params.k())); } @@ -274,7 +274,7 @@ where fixed: vec![vk.domain.empty_lagrange_assigned(); cs.num_fixed_columns], permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation), selectors: vec![vec![false; params.n() as usize]; cs.num_selectors], - usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1), + usable_rows: cs.usable_rows::(params.n() as usize), _marker: std::marker::PhantomData, }; @@ -287,7 +287,7 @@ where )?; let mut fixed = batch_invert_assigned(assembly.fixed); - let (cs, selector_polys) = cs.compress_selectors(assembly.selectors); + let (cs, selector_polys) = cs.compress_selectors::(assembly.selectors); fixed.extend( selector_polys .into_iter() @@ -318,16 +318,31 @@ where // Compute l_blind(X) which evaluates to 1 for each blinding factor row // and 0 otherwise over the domain. let mut l_blind = vk.domain.empty_lagrange(); - for evaluation in l_blind[..].iter_mut().rev().take(cs.blinding_factors()) { + for evaluation in l_blind[..] + .iter_mut() + .rev() + .take(cs.blinding_factors::()) + { *evaluation = C::Scalar::one(); } + let l_blind = vk.domain.lagrange_to_coeff(l_blind); let l_blind = vk.domain.coeff_to_extended(l_blind); + // ZK: // Compute l_last(X) which evaluates to 1 on the first inactive row (just // before the blinding factors) and 0 otherwise over the domain + // + // Non-ZK: + // Compute l_last(X) which evaluates to 1 on the last row and 0 otherwise + // over the domain let mut l_last = vk.domain.empty_lagrange(); - l_last[params.n() as usize - cs.blinding_factors() - 1] = C::Scalar::one(); + if ZK { + l_last[params.n() as usize - cs.blinding_factors::() - 1] = C::Scalar::one(); + } else { + l_last[params.n() as usize - 1] = C::Scalar::one(); + } + let l_last = vk.domain.lagrange_to_coeff(l_last); let l_last = vk.domain.coeff_to_extended(l_last); diff --git a/halo2_proofs/src/plonk/lookup.rs b/halo2_proofs/src/plonk/lookup.rs index 68cda75d37..7abaa66b32 100644 --- a/halo2_proofs/src/plonk/lookup.rs +++ b/halo2_proofs/src/plonk/lookup.rs @@ -34,9 +34,30 @@ impl Argument { } } - pub(crate) fn required_degree(&self) -> usize { + pub(crate) fn required_degree(&self) -> usize { assert_eq!(self.input_expressions.len(), self.table_expressions.len()); + let mut input_degree = 1; + for expr in self.input_expressions.iter() { + input_degree = std::cmp::max(input_degree, expr.degree()); + } + let mut table_degree = 1; + for expr in self.table_expressions.iter() { + table_degree = std::cmp::max(table_degree, expr.degree()); + } + + if !ZK { + // In basic grand-product the z(X) transition is enforced on every row, + // which also allow us to rely on wrap-around to check the last value of + // z(X) to be 1. + return std::cmp::max( + // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) + 3, + // z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) + 1 + input_degree + table_degree, + ); + } + // The first value in the permutation poly should be one. // degree 2: // l_0(X) * (1 - z(X)) = 0 @@ -61,15 +82,7 @@ impl Argument { // value of a' is the same as the current value. // degree 3: // (1 - (l_last(X) + l_blind(X))) * (a′(X) − s′(X))⋅(a′(X) − a′(\omega^{-1} X)) = 0 - let mut input_degree = 1; - for expr in self.input_expressions.iter() { - input_degree = std::cmp::max(input_degree, expr.degree()); - } - let mut table_degree = 1; - for expr in self.table_expressions.iter() { - table_degree = std::cmp::max(table_degree, expr.degree()); - } - + // // In practice because input_degree and table_degree are initialized to // one, the latter half of this max() invocation is at least 4 always, // rendering this call pointless except to be explicit in case we change diff --git a/halo2_proofs/src/plonk/lookup/prover.rs b/halo2_proofs/src/plonk/lookup/prover.rs index f5d87d061e..817594ab2d 100644 --- a/halo2_proofs/src/plonk/lookup/prover.rs +++ b/halo2_proofs/src/plonk/lookup/prover.rs @@ -69,6 +69,7 @@ impl Argument { E: EncodedChallenge, R: RngCore, T: TranscriptWrite, + const ZK: bool, >( &self, pk: &ProvingKey, @@ -114,14 +115,15 @@ impl Argument { let compressed_table_expression = compress_expressions(&self.table_expressions); // Permute compressed (InputExpression, TableExpression) pair - let (permuted_input_expression, permuted_table_expression) = permute_expression_pair( - pk, - params, - domain, - &mut rng, - &compressed_input_expression, - &compressed_table_expression, - )?; + let (permuted_input_expression, permuted_table_expression) = + permute_expression_pair::<_, _, _, ZK>( + pk, + params, + domain, + &mut rng, + &compressed_input_expression, + &compressed_table_expression, + )?; // Closure to construct commitment to vector of values let mut commit_values = |values: &Polynomial| { @@ -170,6 +172,7 @@ impl Permuted { E: EncodedChallenge, R: RngCore, T: TranscriptWrite, + const ZK: bool, >( self, pk: &ProvingKey, @@ -179,7 +182,7 @@ impl Permuted { mut rng: R, transcript: &mut T, ) -> Result, Error> { - let blinding_factors = pk.vk.cs.blinding_factors(); + let blinding_factors = pk.vk.cs.blinding_factors::(); // Goal is to compute the products of fractions // // Numerator: (\theta^{m-1} a_0(\omega^i) + \theta^{m-2} a_1(\omega^i) + ... + \theta a_{m-2}(\omega^i) + a_{m-1}(\omega^i) + \beta) @@ -254,7 +257,7 @@ impl Permuted { // It can be used for debugging purposes. { // While in Lagrange basis, check that product is correctly constructed - let u = (params.n() as usize) - (blinding_factors + 1); + let u = pk.vk.cs.usable_rows::(params.n() as usize).end; // l_0(X) * (1 - z(X)) = 0 assert_eq!(z[0], C::Scalar::one()); @@ -262,7 +265,7 @@ impl Permuted { // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) for i in 0..u { - let mut left = z[i + 1]; + let mut left = z[(i + 1) % params.n() as usize]; let permuted_input_value = &self.permuted_input_expression[i]; let permuted_table_value = &self.permuted_table_expression[i]; @@ -284,7 +287,7 @@ impl Permuted { // l_last(X) * (z(X)^2 - z(X)) = 0 // Assertion will fail only when soundness is broken, in which // case this z[u] value will be zero. (bad!) - assert_eq!(z[u], C::Scalar::one()); + assert_eq!(z[u % params.n() as usize], C::Scalar::one()); } let product_blind = Blind(C::Scalar::random(rng)); @@ -294,7 +297,7 @@ impl Permuted { // Hash product commitment transcript.write_point(product_commitment)?; - Ok(Committed:: { + Ok(Committed { permuted_input_poly: self.permuted_input_poly, permuted_input_blind: self.permuted_input_blind, permuted_table_poly: self.permuted_table_poly, @@ -388,7 +391,13 @@ type ExpressionPair = (Polynomial, Polynomial, R: RngCore>( +fn permute_expression_pair< + 'params, + C: CurveAffine, + P: Params<'params, C>, + R: RngCore, + const ZK: bool, +>( pk: &ProvingKey, params: &P, domain: &EvaluationDomain, @@ -396,8 +405,7 @@ fn permute_expression_pair<'params, C: CurveAffine, P: Params<'params, C>, R: Rn input_expression: &Polynomial, table_expression: &Polynomial, ) -> Result, Error> { - let blinding_factors = pk.vk.cs.blinding_factors(); - let usable_rows = params.n() as usize - (blinding_factors + 1); + let usable_rows = pk.vk.cs.usable_rows::(params.n() as usize).end; let mut permuted_input_expression: Vec = input_expression.to_vec(); permuted_input_expression.truncate(usable_rows); @@ -448,8 +456,9 @@ fn permute_expression_pair<'params, C: CurveAffine, P: Params<'params, C>, R: Rn assert!(repeated_input_rows.is_empty()); permuted_input_expression - .extend((0..(blinding_factors + 1)).map(|_| C::Scalar::random(&mut rng))); - permuted_table_coeffs.extend((0..(blinding_factors + 1)).map(|_| C::Scalar::random(&mut rng))); + .extend((usable_rows..params.n() as usize).map(|_| C::Scalar::random(&mut rng))); + permuted_table_coeffs + .extend((usable_rows..params.n() as usize).map(|_| C::Scalar::random(&mut rng))); assert_eq!(permuted_input_expression.len(), params.n() as usize); assert_eq!(permuted_table_coeffs.len(), params.n() as usize); diff --git a/halo2_proofs/src/plonk/lookup/verifier.rs b/halo2_proofs/src/plonk/lookup/verifier.rs index 88041c29b3..59cad3a20b 100644 --- a/halo2_proofs/src/plonk/lookup/verifier.rs +++ b/halo2_proofs/src/plonk/lookup/verifier.rs @@ -90,7 +90,7 @@ impl Committed { } impl Evaluated { - pub(in crate::plonk) fn expressions<'a>( + pub(in crate::plonk) fn expressions<'a, const ZK: bool>( &'a self, l_0: C::Scalar, l_last: C::Scalar, @@ -136,35 +136,58 @@ impl Evaluated { * &(compress_expressions(&argument.input_expressions) + &*beta) * &(compress_expressions(&argument.table_expressions) + &*gamma); - (left - &right) * &active_rows + if ZK { + (left - &right) * &active_rows + } else { + left - &right + } }; std::iter::empty() - .chain( - // l_0(X) * (1 - z'(X)) = 0 - Some(l_0 * &(C::Scalar::one() - &self.product_eval)), - ) - .chain( - // l_last(X) * (z(X)^2 - z(X)) = 0 - Some(l_last * &(self.product_eval.square() - &self.product_eval)), - ) - .chain( - // (1 - (l_last(X) + l_blind(X))) * ( - // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) - // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) - // ) = 0 - Some(product_expression()), - ) - .chain(Some( - // l_0(X) * (a'(X) - s'(X)) = 0 - l_0 * &(self.permuted_input_eval - &self.permuted_table_eval), - )) - .chain(Some( - // (1 - (l_last(X) + l_blind(X))) * (a′(X) − s′(X))⋅(a′(X) − a′(\omega^{-1} X)) = 0 - (self.permuted_input_eval - &self.permuted_table_eval) - * &(self.permuted_input_eval - &self.permuted_input_inv_eval) - * &active_rows, - )) + // l_0(X) * (1 - z'(X)) = 0 + .chain(Some(l_0 * &(C::Scalar::one() - &self.product_eval))) + // ZK: + // l_last(X) * (z(X)^2 - z(X)) = 0 + .chain(if ZK { + Some(l_last * &(self.product_eval.square() - &self.product_eval)) + } else { + None + }) + // ZK: + // (1 - (l_last(X) + l_blind(X))) * ( + // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) + // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) + // ) = 0 + // + // Non-ZK: + // z(\omega X) (a'(X) + \beta) (s'(X) + \gamma) + // - z(X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) + // = 0 + .chain(Some(product_expression())) + // ZK: + // l_0(X) * (a'(X) - s'(X)) = 0 + .chain(if ZK { + Some(l_0 * &(self.permuted_input_eval - &self.permuted_table_eval)) + } else { + None + }) + // ZK: + // (1 - (l_last(X) + l_blind(X))) * (a′(X) − s′(X))⋅(a′(X) − a′(\omega^{-1} X)) = 0 + // + // Non-ZK: + // (a′(X) − s′(X))⋅(a′(X) − a′(\omega^{-1} X)) = 0 + .chain(if ZK { + Some( + (self.permuted_input_eval - &self.permuted_table_eval) + * &(self.permuted_input_eval - &self.permuted_input_inv_eval) + * &active_rows, + ) + } else { + Some( + (self.permuted_input_eval - &self.permuted_table_eval) + * &(self.permuted_input_eval - &self.permuted_input_inv_eval), + ) + }) } pub(in crate::plonk) fn queries<'r, M: MSM + 'r>( diff --git a/halo2_proofs/src/plonk/permutation/prover.rs b/halo2_proofs/src/plonk/permutation/prover.rs index cddc02348a..b93d3a75e6 100644 --- a/halo2_proofs/src/plonk/permutation/prover.rs +++ b/halo2_proofs/src/plonk/permutation/prover.rs @@ -49,6 +49,7 @@ impl Argument { E: EncodedChallenge, R: RngCore, T: TranscriptWrite, + const ZK: bool, >( &self, params: &P, @@ -69,8 +70,12 @@ impl Argument { // will never underflow because of the requirement of at least a degree // 3 circuit for the permutation argument. assert!(pk.vk.cs_degree >= 3); - let chunk_len = pk.vk.cs_degree - 2; - let blinding_factors = pk.vk.cs.blinding_factors(); + let chunk_len = if ZK || self.columns.len() >= pk.vk.cs_degree { + pk.vk.cs_degree - 2 + } else { + pk.vk.cs_degree - 1 + }; + let blinding_factors = pk.vk.cs.blinding_factors::(); // Each column gets its own delta power. let mut deltaomega = C::Scalar::one(); @@ -158,12 +163,17 @@ impl Argument { z.push(tmp); } let mut z = domain.lagrange_from_vec(z); - // Set blinding factors - for z in &mut z[params.n() as usize - blinding_factors..] { - *z = C::Scalar::random(&mut rng); + if ZK { + // Set blinding factors + for z in &mut z[params.n() as usize - blinding_factors..] { + *z = C::Scalar::random(&mut rng); + } + // Set new last_z + last_z = z[params.n() as usize - (blinding_factors + 1)]; + } else { + // Set new last_z + last_z = *z.last().unwrap() * modified_values.last().unwrap(); } - // Set new last_z - last_z = z[params.n() as usize - (blinding_factors + 1)]; let blind = Blind(C::Scalar::random(&mut rng)); @@ -233,14 +243,18 @@ impl super::ProvingKey { } impl Constructed { - pub(in crate::plonk) fn evaluate, T: TranscriptWrite>( + pub(in crate::plonk) fn evaluate< + E: EncodedChallenge, + T: TranscriptWrite, + const ZK: bool, + >( self, pk: &plonk::ProvingKey, x: ChallengeX, transcript: &mut T, ) -> Result, Error> { let domain = &pk.vk.domain; - let blinding_factors = pk.vk.cs.blinding_factors(); + let blinding_factors = pk.vk.cs.blinding_factors::(); { let mut sets = self.sets.iter(); @@ -261,16 +275,18 @@ impl Constructed { transcript.write_scalar(*eval)?; } - // If we have any remaining sets to process, evaluate this set at omega^u - // so we can constrain the last value of its running product to equal the - // first value of the next set's running product, chaining them together. - if sets.len() > 0 { - let permutation_product_last_eval = eval_polynomial( - &set.permutation_product_poly, - domain.rotate_omega(*x, Rotation(-((blinding_factors + 1) as i32))), - ); - - transcript.write_scalar(permutation_product_last_eval)?; + if ZK { + // If we have any remaining sets to process, evaluate this set at omega^u + // so we can constrain the last value of its running product to equal the + // first value of the next set's running product, chaining them together. + if sets.len() > 0 { + let permutation_product_last_eval = eval_polynomial( + &set.permutation_product_poly, + domain.rotate_omega(*x, Rotation(-((blinding_factors + 1) as i32))), + ); + + transcript.write_scalar(permutation_product_last_eval)?; + } } } } @@ -280,12 +296,12 @@ impl Constructed { } impl Evaluated { - pub(in crate::plonk) fn open<'a>( + pub(in crate::plonk) fn open<'a, const ZK: bool>( &'a self, pk: &'a plonk::ProvingKey, x: ChallengeX, ) -> impl Iterator> + Clone { - let blinding_factors = pk.vk.cs.blinding_factors(); + let blinding_factors = pk.vk.cs.blinding_factors::(); let x_next = pk.vk.domain.rotate_omega(*x, Rotation::next()); let x_last = pk .vk @@ -310,7 +326,7 @@ impl Evaluated { // Open it at \omega^{last} x for all but the last set. This rotation is only // sensical for the first row, but we only use this rotation in a constraint // that is gated on l_0. - .chain( + .chain(if ZK { self.constructed .sets .iter() @@ -322,7 +338,10 @@ impl Evaluated { poly: &set.permutation_product_poly, blind: set.permutation_product_blind, }) - }), - ) + }) + .collect() + } else { + Vec::new() + }) } } diff --git a/halo2_proofs/src/plonk/permutation/verifier.rs b/halo2_proofs/src/plonk/permutation/verifier.rs index 2e7a707a07..363cf68eb0 100644 --- a/halo2_proofs/src/plonk/permutation/verifier.rs +++ b/halo2_proofs/src/plonk/permutation/verifier.rs @@ -34,12 +34,17 @@ impl Argument { C: CurveAffine, E: EncodedChallenge, T: TranscriptRead, + const ZK: bool, >( &self, vk: &plonk::VerifyingKey, transcript: &mut T, ) -> Result, Error> { - let chunk_len = vk.cs_degree - 2; + let chunk_len = if ZK || self.columns.len() >= vk.cs_degree { + vk.cs_degree - 2 + } else { + vk.cs_degree - 1 + }; let permutation_product_commitments = self .columns @@ -69,7 +74,7 @@ impl VerifyingKey { } impl Committed { - pub(crate) fn evaluate, T: TranscriptRead>( + pub(crate) fn evaluate, T: TranscriptRead, const ZK: bool>( self, transcript: &mut T, ) -> Result, Error> { @@ -80,7 +85,7 @@ impl Committed { while let Some(permutation_product_commitment) = iter.next() { let permutation_product_eval = transcript.read_scalar()?; let permutation_product_next_eval = transcript.read_scalar()?; - let permutation_product_last_eval = if iter.len() > 0 { + let permutation_product_last_eval = if ZK && iter.len() > 0 { Some(transcript.read_scalar()?) } else { None @@ -99,7 +104,7 @@ impl Committed { } impl Evaluated { - pub(in crate::plonk) fn expressions<'a>( + pub(in crate::plonk) fn expressions<'a, const ZK: bool>( &'a self, vk: &'a plonk::VerifyingKey, p: &'a Argument, @@ -114,7 +119,11 @@ impl Evaluated { gamma: ChallengeGamma, x: ChallengeX, ) -> impl Iterator + 'a { - let chunk_len = vk.cs_degree - 2; + let chunk_len = if ZK || p.columns.len() >= vk.cs_degree { + vk.cs_degree - 2 + } else { + vk.cs_degree - 1 + }; iter::empty() // Enforce only for the first set. // l_0(X) * (1 - z_0(X)) = 0 @@ -124,14 +133,23 @@ impl Evaluated { }), ) // Enforce only for the last set. + // + // ZK: // l_last(X) * (z_l(X)^2 - z_l(X)) = 0 - .chain(self.sets.last().map(|last_set| { - (last_set.permutation_product_eval.square() - &last_set.permutation_product_eval) - * &l_last - })) + .chain(if ZK { + self.sets.last().map(|last_set| { + (last_set.permutation_product_eval.square() + - &last_set.permutation_product_eval) + * &l_last + }) + } else { + None + }) // Except for the first set, enforce. + // + // ZK: // l_0(X) * (z_i(X) - z_{i-1}(\omega^(last) X)) = 0 - .chain( + .chain(if ZK { self.sets .iter() .skip(1) @@ -142,24 +160,65 @@ impl Evaluated { last_set.permutation_product_last_eval.unwrap(), ) }) - .map(move |(set, prev_last)| (set - &prev_last) * &l_0), - ) + .map(move |(set, prev_last)| (set - &prev_last) * &l_0) + .collect() + } else { + Vec::new() + }) // And for all the sets we enforce: + // + // ZK: // (1 - (l_last(X) + l_blind(X))) * ( // z_i(\omega X) \prod (p(X) + \beta s_i(X) + \gamma) // - z_i(X) \prod (p(X) + \delta^i \beta X + \gamma) // ) + // + // Non-ZK: + // + // ((1 - l_last(X)) * z_i(\omega X) + l_last(X) * z_{i+1}(\omega X)) * \prod_j (p(X) + \beta s_j(X) + \gamma) + // - z_i(X) \prod_j (p(X) + \delta^j \beta X + \gamma) + // = 0 .chain( self.sets .iter() + .zip(self.sets.iter().cycle().skip(1)) .zip(p.columns.chunks(chunk_len)) .zip(common.permutation_evals.chunks(chunk_len)) .enumerate() - .map(move |(chunk_index, ((set, columns), permutation_evals))| { - let mut left = set.permutation_product_next_eval; - for (eval, permutation_eval) in columns - .iter() - .map(|&column| match column.column_type() { + .map( + move |(chunk_index, (((set, next_set), columns), permutation_evals))| { + let mut left = if ZK || self.sets.len() == 1 { + set.permutation_product_next_eval + } else { + (C::Scalar::one() - l_last) * set.permutation_product_next_eval + + l_last * next_set.permutation_product_next_eval + }; + for (eval, permutation_eval) in columns + .iter() + .map(|&column| match column.column_type() { + Any::Advice(_) => { + advice_evals + [vk.cs.get_any_query_index(column, Rotation::cur())] + } + Any::Fixed => { + fixed_evals + [vk.cs.get_any_query_index(column, Rotation::cur())] + } + Any::Instance => { + instance_evals + [vk.cs.get_any_query_index(column, Rotation::cur())] + } + }) + .zip(permutation_evals.iter()) + { + left *= &(eval + &(*beta * permutation_eval) + &*gamma); + } + + let mut right = set.permutation_product_eval; + let mut current_delta = (*beta * &*x) + * &(C::Scalar::DELTA + .pow_vartime(&[(chunk_index * chunk_len) as u64])); + for eval in columns.iter().map(|&column| match column.column_type() { Any::Advice(_) => { advice_evals[vk.cs.get_any_query_index(column, Rotation::cur())] } @@ -170,41 +229,27 @@ impl Evaluated { instance_evals [vk.cs.get_any_query_index(column, Rotation::cur())] } - }) - .zip(permutation_evals.iter()) - { - left *= &(eval + &(*beta * permutation_eval) + &*gamma); - } - - let mut right = set.permutation_product_eval; - let mut current_delta = (*beta * &*x) - * &(C::Scalar::DELTA.pow_vartime(&[(chunk_index * chunk_len) as u64])); - for eval in columns.iter().map(|&column| match column.column_type() { - Any::Advice(_) => { - advice_evals[vk.cs.get_any_query_index(column, Rotation::cur())] - } - Any::Fixed => { - fixed_evals[vk.cs.get_any_query_index(column, Rotation::cur())] + }) { + right *= &(eval + ¤t_delta + &*gamma); + current_delta *= &C::Scalar::DELTA; } - Any::Instance => { - instance_evals[vk.cs.get_any_query_index(column, Rotation::cur())] - } - }) { - right *= &(eval + ¤t_delta + &*gamma); - current_delta *= &C::Scalar::DELTA; - } - (left - &right) * (C::Scalar::one() - &(l_last + &l_blind)) - }), + if ZK { + (left - &right) * (C::Scalar::one() - &(l_last + &l_blind)) + } else { + left - &right + } + }, + ), ) } - pub(in crate::plonk) fn queries<'r, M: MSM + 'r>( + pub(in crate::plonk) fn queries<'r, M: MSM + 'r, const ZK: bool>( &'r self, vk: &'r plonk::VerifyingKey, x: ChallengeX, ) -> impl Iterator> + Clone { - let blinding_factors = vk.cs.blinding_factors(); + let blinding_factors = vk.cs.blinding_factors::(); let x_next = vk.domain.rotate_omega(*x, Rotation::next()); let x_last = vk .domain @@ -227,13 +272,22 @@ impl Evaluated { ))) })) // Open it at \omega^{last} x for all but the last set - .chain(self.sets.iter().rev().skip(1).flat_map(move |set| { - Some(VerifierQuery::new_commitment( - &set.permutation_product_commitment, - x_last, - set.permutation_product_last_eval.unwrap(), - )) - })) + .chain(if ZK { + self.sets + .iter() + .rev() + .skip(1) + .flat_map(move |set| { + Some(VerifierQuery::new_commitment( + &set.permutation_product_commitment, + x_last, + set.permutation_product_last_eval.unwrap(), + )) + }) + .collect() + } else { + Vec::new() + }) } } diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 65a01873d2..bdffe86ec5 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -46,6 +46,7 @@ pub fn create_proof< R: RngCore, T: TranscriptWrite, ConcreteCircuit: Circuit, + const ZK: bool, >( params: &'params Scheme::ParamsProver, pk: &ProvingKey, @@ -84,7 +85,7 @@ pub fn create_proof< .map(|values| { let mut poly = domain.empty_lagrange(); assert_eq!(poly.len(), params.n() as usize); - if values.len() > (poly.len() - (meta.blinding_factors() + 1)) { + if ZK && values.len() > meta.usable_rows::(params.n() as usize).end { return Err(Error::InstanceTooLarge); } for (poly, value) in poly.iter_mut().zip(values.iter()) { @@ -283,7 +284,7 @@ pub fn create_proof< ]; let mut challenges = HashMap::::with_capacity(meta.num_challenges); - let unusable_rows_start = params.n() as usize - (meta.blinding_factors() + 1); + let unusable_rows_start = meta.usable_rows::(params.n() as usize).end; for current_phase in pk.vk.cs.phases() { let column_indices = meta .advice_column_phase @@ -338,10 +339,12 @@ pub fn create_proof< .collect(), ); - // Add blinding factors to advice columns - for advice_values in &mut advice_values { - for cell in &mut advice_values[unusable_rows_start..] { - *cell = Scheme::Scalar::random(&mut rng); + // Add blinding factors to advice columns if ZK is enabled + if ZK { + for advice in &mut advice_values { + for cell in &mut advice[unusable_rows_start..] { + *cell = Scheme::Scalar::random(&mut rng); + } } } @@ -405,7 +408,7 @@ pub fn create_proof< .lookups .iter() .map(|lookup| { - lookup.commit_permuted( + lookup.commit_permuted::<_, _, _, _, _, ZK>( pk, params, domain, @@ -433,7 +436,7 @@ pub fn create_proof< .iter() .zip(advice.iter()) .map(|(instance, advice)| { - pk.vk.cs.permutation.commit( + pk.vk.cs.permutation.commit::<_, _, _, _, _, ZK>( params, pk, &pk.permutation, @@ -454,13 +457,18 @@ pub fn create_proof< // Construct and commit to products for each lookup lookups .into_iter() - .map(|lookup| lookup.commit_product(pk, params, beta, gamma, &mut rng, transcript)) + .map(|lookup| { + lookup.commit_product::<_, _, _, _, ZK>( + pk, params, beta, gamma, &mut rng, transcript, + ) + }) .collect::, _>>() }) .collect::, _>>()?; // Commit to the vanishing argument's random polynomial for blinding h(x_3) - let vanishing = vanishing::Argument::commit(params, domain, &mut rng, transcript)?; + let vanishing = + vanishing::Argument::commit::<_, _, _, _, ZK>(params, domain, &mut rng, transcript)?; // Obtain challenge for keeping all separate gates linearly independent let y: ChallengeY<_> = transcript.squeeze_challenge_scalar(); @@ -485,7 +493,7 @@ pub fn create_proof< .collect(); // Evaluate the h(X) polynomial - let h_poly = pk.ev.evaluate_h( + let h_poly = pk.ev.evaluate_h::( pk, &advice .iter() @@ -566,7 +574,7 @@ pub fn create_proof< transcript.write_scalar(*eval)?; } - let vanishing = vanishing.evaluate(x, xn, domain, transcript)?; + let vanishing = vanishing.evaluate::<_, _, ZK>(x, xn, domain, transcript)?; // Evaluate common permutation data pk.permutation.evaluate(x, transcript)?; @@ -574,7 +582,11 @@ pub fn create_proof< // Evaluate the permutations, if any, at omega^i x. let permutations: Vec> = permutations .into_iter() - .map(|permutation| -> Result<_, _> { permutation.construct().evaluate(pk, x, transcript) }) + .map(|permutation| -> Result<_, _> { + permutation + .construct() + .evaluate::<_, _, ZK>(pk, x, transcript) + }) .collect::, _>>()?; // Evaluate the lookups, if any, at omega^i x. @@ -618,7 +630,7 @@ pub fn create_proof< blind: advice.advice_blinds[column.index()], }), ) - .chain(permutation.open(pk, x)) + .chain(permutation.open::(pk, x)) .chain(lookups.iter().flat_map(move |p| p.open(pk, x)).into_iter()) }) .chain( @@ -634,7 +646,7 @@ pub fn create_proof< ) .chain(pk.permutation.open(x)) // We query the h(X) polynomial at x - .chain(vanishing.open(x)); + .chain(vanishing.open::(x)); let prover = P::new(params); prover diff --git a/halo2_proofs/src/plonk/vanishing/prover.rs b/halo2_proofs/src/plonk/vanishing/prover.rs index cc52273b59..3ade8a5f34 100644 --- a/halo2_proofs/src/plonk/vanishing/prover.rs +++ b/halo2_proofs/src/plonk/vanishing/prover.rs @@ -40,23 +40,34 @@ impl Argument { E: EncodedChallenge, R: RngCore, T: TranscriptWrite, + const ZK: bool, >( params: &P, domain: &EvaluationDomain, mut rng: R, transcript: &mut T, ) -> Result, Error> { - // Sample a random polynomial of degree n - 1 let mut random_poly = domain.empty_coeff(); - for coeff in random_poly.iter_mut() { - *coeff = C::Scalar::random(&mut rng); + + if ZK { + // Sample a random polynomial of degree n - 1 + for coeff in random_poly.iter_mut() { + *coeff = C::Scalar::random(&mut rng); + } } - // Sample a random blinding factor - let random_blind = Blind(C::Scalar::random(rng)); + + let random_blind = if ZK { + // Sample a random blinding factor + Blind(C::Scalar::random(rng)) + } else { + Blind::default() + }; // Commit - let c = params.commit(&random_poly, random_blind).to_affine(); - transcript.write_point(c)?; + if ZK { + let c = params.commit(&random_poly, random_blind).to_affine(); + transcript.write_point(c)?; + } Ok(Committed { random_poly, @@ -121,7 +132,11 @@ impl Committed { } impl Constructed { - pub(in crate::plonk) fn evaluate, T: TranscriptWrite>( + pub(in crate::plonk) fn evaluate< + E: EncodedChallenge, + T: TranscriptWrite, + const ZK: bool, + >( self, x: ChallengeX, xn: C::Scalar, @@ -142,8 +157,10 @@ impl Constructed { acc * Blind(xn) + *eval }); - let random_eval = eval_polynomial(&self.committed.random_poly, *x); - transcript.write_scalar(random_eval)?; + if ZK { + let random_eval = eval_polynomial(&self.committed.random_poly, *x); + transcript.write_scalar(random_eval)?; + } Ok(Evaluated { h_poly, @@ -154,7 +171,7 @@ impl Constructed { } impl Evaluated { - pub(in crate::plonk) fn open( + pub(in crate::plonk) fn open( &self, x: ChallengeX, ) -> impl Iterator> + Clone { @@ -164,10 +181,14 @@ impl Evaluated { poly: &self.h_poly, blind: self.h_blind, })) - .chain(Some(ProverQuery { - point: *x, - poly: &self.committed.random_poly, - blind: self.committed.random_blind, - })) + .chain(if ZK { + Some(ProverQuery { + point: *x, + poly: &self.committed.random_poly, + blind: self.committed.random_blind, + }) + } else { + None + }) } } diff --git a/halo2_proofs/src/plonk/vanishing/verifier.rs b/halo2_proofs/src/plonk/vanishing/verifier.rs index 3570dee6c1..52fdcd8749 100644 --- a/halo2_proofs/src/plonk/vanishing/verifier.rs +++ b/halo2_proofs/src/plonk/vanishing/verifier.rs @@ -41,10 +41,15 @@ impl Argument { pub(in crate::plonk) fn read_commitments_before_y< E: EncodedChallenge, T: TranscriptRead, + const ZK: bool, >( transcript: &mut T, ) -> Result, Error> { - let random_poly_commitment = transcript.read_point()?; + let random_poly_commitment = if ZK { + transcript.read_point()? + } else { + C::default() + }; Ok(Committed { random_poly_commitment, @@ -72,11 +77,19 @@ impl Committed { } impl Constructed { - pub(in crate::plonk) fn evaluate_after_x, T: TranscriptRead>( + pub(in crate::plonk) fn evaluate_after_x< + E: EncodedChallenge, + T: TranscriptRead, + const ZK: bool, + >( self, transcript: &mut T, ) -> Result, Error> { - let random_eval = transcript.read_scalar()?; + let random_eval = if ZK { + transcript.read_scalar()? + } else { + C::Scalar::zero() + }; Ok(PartiallyEvaluated { h_commitments: self.h_commitments, @@ -119,7 +132,7 @@ impl PartiallyEvaluated { } impl> Evaluated { - pub(in crate::plonk) fn queries( + pub(in crate::plonk) fn queries( &self, x: ChallengeX, ) -> impl Iterator> + Clone { @@ -129,10 +142,14 @@ impl> Evaluated { *x, self.expected_h_eval, ))) - .chain(Some(VerifierQuery::new_commitment( - &self.random_poly_commitment, - *x, - self.random_eval, - ))) + .chain(if ZK { + Some(VerifierQuery::new_commitment( + &self.random_poly_commitment, + *x, + self.random_eval, + )) + } else { + None + }) } } diff --git a/halo2_proofs/src/plonk/verifier.rs b/halo2_proofs/src/plonk/verifier.rs index e6a2327e7b..708b72170a 100644 --- a/halo2_proofs/src/plonk/verifier.rs +++ b/halo2_proofs/src/plonk/verifier.rs @@ -31,6 +31,7 @@ pub fn verify_proof< E: EncodedChallenge, T: TranscriptRead, Strategy: VerificationStrategy<'params, Scheme, V>, + const ZK: bool, >( params: &'params Scheme::ParamsVerifier, vk: &VerifyingKey, @@ -52,7 +53,10 @@ pub fn verify_proof< instance .iter() .map(|instance| { - if instance.len() > params.n() as usize - (vk.cs.blinding_factors() + 1) { + if ZK + && instance.len() + > params.n() as usize - (vk.cs.blinding_factors::() + 1) + { return Err(Error::InstanceTooLarge); } let mut poly = instance.to_vec(); @@ -142,7 +146,9 @@ pub fn verify_proof< let permutations_committed = (0..num_proofs) .map(|_| { // Hash each permutation product commitment - vk.cs.permutation.read_product_commitments(vk, transcript) + vk.cs + .permutation + .read_product_commitments::<_, _, _, ZK>(vk, transcript) }) .collect::, _>>()?; @@ -157,7 +163,7 @@ pub fn verify_proof< }) .collect::, _>>()?; - let vanishing = vanishing::Argument::read_commitments_before_y(transcript)?; + let vanishing = vanishing::Argument::read_commitments_before_y::<_, _, ZK>(transcript)?; // Sample y challenge, which keeps the gates linearly independent. let y: ChallengeY<_> = transcript.squeeze_challenge_scalar(); @@ -220,13 +226,13 @@ pub fn verify_proof< let fixed_evals = read_n_scalars(transcript, vk.cs.fixed_queries.len())?; - let vanishing = vanishing.evaluate_after_x(transcript)?; + let vanishing = vanishing.evaluate_after_x::<_, _, ZK>(transcript)?; let permutations_common = vk.permutation.evaluate(transcript)?; let permutations_evaluated = permutations_committed .into_iter() - .map(|permutation| permutation.evaluate(transcript)) + .map(|permutation| permutation.evaluate::<_, _, ZK>(transcript)) .collect::, _>>()?; let lookups_evaluated = lookups_committed @@ -245,7 +251,7 @@ pub fn verify_proof< // x^n let xn = x.pow(&[params.n() as u64, 0, 0, 0]); - let blinding_factors = vk.cs.blinding_factors(); + let blinding_factors = vk.cs.blinding_factors::(); let l_evals = vk .domain .l_i_range(*x, xn, (-((blinding_factors + 1) as i32))..=0); @@ -283,7 +289,7 @@ pub fn verify_proof< ) }) })) - .chain(permutation.expressions( + .chain(permutation.expressions::( vk, &vk.cs.permutation, &permutations_common, @@ -302,7 +308,7 @@ pub fn verify_proof< .iter() .zip(vk.cs.lookups.iter()) .flat_map(move |(p, argument)| { - p.expressions( + p.expressions::( l_0, l_last, l_blind, @@ -362,7 +368,7 @@ pub fn verify_proof< ) }, )) - .chain(permutation.queries(vk, x)) + .chain(permutation.queries::<_, ZK>(vk, x)) .chain( lookups .iter() @@ -385,7 +391,7 @@ pub fn verify_proof< }), ) .chain(permutations_common.queries(&vk.permutation, x)) - .chain(vanishing.queries(x)); + .chain(vanishing.queries::(x)); // We are now convinced the circuit is satisfied so long as the // polynomial commitments open to the correct values. diff --git a/halo2_proofs/src/plonk/verifier/batch.rs b/halo2_proofs/src/plonk/verifier/batch.rs index f07ba4141f..7e45fcdca8 100644 --- a/halo2_proofs/src/plonk/verifier/batch.rs +++ b/halo2_proofs/src/plonk/verifier/batch.rs @@ -86,7 +86,11 @@ impl BatchVerifier { /// This uses [`OsRng`] internally instead of taking an `R: RngCore` argument, because /// the internal parallelization requires access to a RNG that is guaranteed to not /// clone its internal state when shared between threads. - pub fn finalize(self, params: &ParamsVerifierIPA, vk: &VerifyingKey) -> bool { + pub fn finalize( + self, + params: &ParamsVerifierIPA, + vk: &VerifyingKey, + ) -> bool { fn accumulate_msm<'params, C: CurveAffine>( mut acc: MSMIPA<'params, C>, msm: MSMIPA<'params, C>, @@ -114,10 +118,11 @@ impl BatchVerifier { let strategy = BatchStrategy::new(params); let mut transcript = Blake2bRead::init(&item.proof[..]); - verify_proof(params, vk, strategy, &instances, &mut transcript).map_err(|e| { - tracing::debug!("Batch item {} failed verification: {}", i, e); - e - }) + verify_proof::<_, _, _, _, _, ZK>(params, vk, strategy, &instances, &mut transcript) + .map_err(|e| { + tracing::debug!("Batch item {} failed verification: {}", i, e); + e + }) }) .try_fold( || params.empty_msm(), diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index af63b5fb30..74d466c205 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -427,7 +427,7 @@ fn plonk_api() { // k that is too small for the minimum required number of rows. let much_too_small_params= <$scheme as CommitmentScheme>::ParamsProver::new(1); assert_matches!( - keygen_vk(&much_too_small_params, &empty_circuit), + keygen_vk::<_, _, _, ZK>(&much_too_small_params, &empty_circuit), Err(Error::NotEnoughRowsAvailable { current_k, }) if current_k == 1 @@ -437,7 +437,7 @@ fn plonk_api() { // k that is too small for the number of rows the circuit uses. let slightly_too_small_params = <$scheme as CommitmentScheme>::ParamsProver::new(K-1); assert_matches!( - keygen_vk(&slightly_too_small_params, &empty_circuit), + keygen_vk::<_, _, _, ZK>(&slightly_too_small_params, &empty_circuit), Err(Error::NotEnoughRowsAvailable { current_k, }) if current_k == K - 1 @@ -445,7 +445,7 @@ fn plonk_api() { }}; } - fn keygen( + fn keygen( params: &Scheme::ParamsProver, ) -> ProvingKey { let (_, _, lookup_table) = common!(Scheme); @@ -455,9 +455,10 @@ fn plonk_api() { }; // Initialize the proving key - let vk = keygen_vk(params, &empty_circuit).expect("keygen_vk should not fail"); + let vk = + keygen_vk::<_, _, _, ZK>(params, &empty_circuit).expect("keygen_vk should not fail"); - keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail") + keygen_pk::<_, _, _, ZK>(params, vk, &empty_circuit).expect("keygen_pk should not fail") } fn create_proof< @@ -467,6 +468,7 @@ fn plonk_api() { E: EncodedChallenge, R: RngCore, T: TranscriptWriterBuffer, Scheme::Curve, E>, + const ZK: bool, >( rng: R, params: &'params Scheme::ParamsProver, @@ -481,7 +483,7 @@ fn plonk_api() { let mut transcript = T::init(vec![]); - create_plonk_proof::( + create_plonk_proof::( params, pk, &[circuit.clone(), circuit.clone()], @@ -492,7 +494,7 @@ fn plonk_api() { .expect("proof generation should not fail"); // Check this circuit is satisfied. - let prover = match MockProver::run(K, &circuit, vec![vec![instance]]) { + let prover = match MockProver::run::<_, ZK>(K, &circuit, vec![vec![instance]]) { Ok(prover) => prover, Err(e) => panic!("{:?}", e), }; @@ -509,6 +511,7 @@ fn plonk_api() { E: EncodedChallenge, T: TranscriptReadBuffer<&'a [u8], Scheme::Curve, E>, Strategy: VerificationStrategy<'params, Scheme, V, Output = Strategy>, + const ZK: bool, >( params_verifier: &'params Scheme::ParamsVerifier, vk: &VerifyingKey, @@ -520,7 +523,7 @@ fn plonk_api() { let mut transcript = T::init(proof); let strategy = Strategy::new(params_verifier); - let strategy = verify_plonk_proof( + let strategy = verify_plonk_proof::<_, _, _, _, _, ZK>( params_verifier, vk, strategy, @@ -532,7 +535,7 @@ fn plonk_api() { assert!(strategy.finalize()); } - fn test_plonk_api_gwc() { + fn test_plonk_api_gwc() { use halo2_proofs::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; use halo2_proofs::poly::kzg::multiopen::{ProverGWC, VerifierGWC}; use halo2_proofs::poly::kzg::strategy::AccumulatorStrategy; @@ -544,9 +547,9 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let pk = keygen::, ZK>(¶ms); - let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( + let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>, ZK>( rng, ¶ms, &pk, ); @@ -558,10 +561,11 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, + ZK, >(verifier_params, pk.get_vk(), &proof[..]); } - fn test_plonk_api_shplonk() { + fn test_plonk_api_shplonk() { use halo2_proofs::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; use halo2_proofs::poly::kzg::multiopen::{ProverSHPLONK, VerifierSHPLONK}; use halo2_proofs::poly::kzg::strategy::AccumulatorStrategy; @@ -573,11 +577,12 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let pk = keygen::, ZK>(¶ms); - let proof = create_proof::<_, ProverSHPLONK<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, - ); + let proof = + create_proof::<_, ProverSHPLONK<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>, ZK>( + rng, ¶ms, &pk, + ); let verifier_params = params.verifier_params(); @@ -587,10 +592,11 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, + ZK, >(verifier_params, pk.get_vk(), &proof[..]); } - fn test_plonk_api_ipa() { + fn test_plonk_api_ipa() { use halo2_proofs::poly::ipa::commitment::{IPACommitmentScheme, ParamsIPA}; use halo2_proofs::poly::ipa::multiopen::{ProverIPA, VerifierIPA}; use halo2_proofs::poly::ipa::strategy::AccumulatorStrategy; @@ -602,9 +608,9 @@ fn plonk_api() { let params = ParamsIPA::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let pk = keygen::, ZK>(¶ms); - let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( + let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>, ZK>( rng, ¶ms, &pk, ); @@ -616,10 +622,11 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, + ZK, >(verifier_params, pk.get_vk(), &proof[..]); // Check that the verification key has not changed unexpectedly - { + if ZK { //panic!("{:#?}", pk.get_vk().pinned()); assert_eq!( format!("{:#?}", pk.get_vk().pinned()), @@ -1020,8 +1027,10 @@ fn plonk_api() { ); } } - - test_plonk_api_ipa(); - test_plonk_api_gwc(); - test_plonk_api_shplonk(); + test_plonk_api_ipa::(); + test_plonk_api_gwc::(); + test_plonk_api_shplonk::(); + test_plonk_api_ipa::(); + test_plonk_api_gwc::(); + test_plonk_api_shplonk::(); }