From f9deb040b25be747a5f01e262eecb61b36d3087b Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Mon, 8 Apr 2024 11:30:46 +0800 Subject: [PATCH 01/11] feat!: remove the "compress_selectors" field from PK & VK --- halo2_backend/src/plonk.rs | 4 ---- halo2_proofs/src/plonk/keygen.rs | 29 ++++++++++++++++++++--------- halo2_proofs/src/plonk/prover.rs | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/halo2_backend/src/plonk.rs b/halo2_backend/src/plonk.rs index e386371fac..770c1130f0 100644 --- a/halo2_backend/src/plonk.rs +++ b/halo2_backend/src/plonk.rs @@ -52,9 +52,6 @@ pub struct VerifyingKey { cs_degree: usize, /// The representative of this `VerifyingKey` in transcripts. transcript_repr: C::Scalar, - /// Legacy field that indicates wether the circuit was compiled with compressed selectors or - /// not using the legacy API. - pub compress_selectors: Option, } // Current version of the VK @@ -187,7 +184,6 @@ impl VerifyingKey { cs_degree, // Temporary, this is not pinned. transcript_repr: C::Scalar::ZERO, - compress_selectors: None, }; let mut hasher = Blake2bParams::new() diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index 3fc407315a..fd54ada8bd 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -9,7 +9,7 @@ use halo2_frontend::plonk::Circuit; use halo2_middleware::ff::FromUniformBytes; /// Generate a `VerifyingKey` from an instance of `Circuit`. -/// By default, selector compression is turned **off**. +/// By default, selector compression is turned **ON**. pub fn keygen_vk<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, @@ -38,9 +38,7 @@ where C::Scalar: FromUniformBytes<64>, { let (compiled_circuit, _, _) = compile_circuit(params.k(), circuit, compress_selectors)?; - let mut vk = keygen_vk_v2(params, &compiled_circuit)?; - vk.compress_selectors = Some(compress_selectors); - Ok(vk) + Ok(keygen_vk_v2(params, &compiled_circuit)?) } /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. @@ -54,10 +52,23 @@ where P: Params<'params, C>, ConcreteCircuit: Circuit, { - let (compiled_circuit, _, _) = compile_circuit( - params.k(), - circuit, - vk.compress_selectors.unwrap_or_default(), - )?; + keygen_pk_custom(params, vk, circuit, true) +} + +/// Generate a `ProvingKey` from an instance of `Circuit`. +/// +/// The selector compression optimization is turned on only if `compress_selectors` is `true`. +pub fn keygen_pk_custom<'params, C, P, ConcreteCircuit>( + params: &P, + vk: VerifyingKey, + circuit: &ConcreteCircuit, + compress_selectors: bool, +) -> Result, Error> +where + C: CurveAffine, + P: Params<'params, C>, + ConcreteCircuit: Circuit, +{ + let (compiled_circuit, _, _) = compile_circuit(params.k(), circuit, compress_selectors)?; Ok(keygen_pk_v2(params, vk, &compiled_circuit)?) } diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index cd4524c364..df04705608 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -35,7 +35,7 @@ where return Err(Error::Backend(ErrorBack::InvalidInstances)); } let (config, cs, _) = compile_circuit_cs::<_, ConcreteCircuit>( - pk.get_vk().compress_selectors.unwrap_or_default(), + true, #[cfg(feature = "circuit-params")] circuits[0].params(), ); From 3b254ae5b57553bee250d0c6de5348f21154eab8 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:43:53 +0800 Subject: [PATCH 02/11] feat!: add the "compress_selectors" param to "create_proof" func --- halo2_proofs/benches/plonk.rs | 1 + halo2_proofs/examples/serialization.rs | 1 + halo2_proofs/examples/shuffle.rs | 2 ++ halo2_proofs/examples/shuffle_api.rs | 2 ++ halo2_proofs/examples/vector-ops-unblinded.rs | 2 ++ halo2_proofs/src/plonk/keygen.rs | 1 + halo2_proofs/src/plonk/prover.rs | 6 +++- halo2_proofs/tests/frontend_backend_split.rs | 2 ++ halo2_proofs/tests/plonk_api.rs | 33 ++++++++++++++----- 9 files changed, 41 insertions(+), 9 deletions(-) diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index 7551fde229..e9c6954359 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -289,6 +289,7 @@ fn criterion_benchmark(c: &mut Criterion) { create_proof::, ProverIPA, _, _, _, _>( params, pk, + true, &[circuit], &[&[]], rng, diff --git a/halo2_proofs/examples/serialization.rs b/halo2_proofs/examples/serialization.rs index 4a83392e37..d0fcb7eebc 100644 --- a/halo2_proofs/examples/serialization.rs +++ b/halo2_proofs/examples/serialization.rs @@ -167,6 +167,7 @@ fn main() { >( ¶ms, &pk, + compress_selectors, &[circuit], &[instances], OsRng, diff --git a/halo2_proofs/examples/shuffle.rs b/halo2_proofs/examples/shuffle.rs index f61d17fd09..8c91fc34e8 100644 --- a/halo2_proofs/examples/shuffle.rs +++ b/halo2_proofs/examples/shuffle.rs @@ -279,6 +279,7 @@ fn test_prover( let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -286,6 +287,7 @@ fn test_prover( create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, + compress_selectors, &[circuit], &[&[]], OsRng, diff --git a/halo2_proofs/examples/shuffle_api.rs b/halo2_proofs/examples/shuffle_api.rs index f3080cd393..f498700a64 100644 --- a/halo2_proofs/examples/shuffle_api.rs +++ b/halo2_proofs/examples/shuffle_api.rs @@ -155,6 +155,7 @@ where let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -162,6 +163,7 @@ where create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, + compress_selectors, &[circuit], &[&[]], OsRng, diff --git a/halo2_proofs/examples/vector-ops-unblinded.rs b/halo2_proofs/examples/vector-ops-unblinded.rs index 386d6b34a3..688b16e4bb 100644 --- a/halo2_proofs/examples/vector-ops-unblinded.rs +++ b/halo2_proofs/examples/vector-ops-unblinded.rs @@ -478,6 +478,7 @@ where let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -485,6 +486,7 @@ where create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, + compress_selectors, &[circuit], &[&[&instances]], OsRng, diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index fd54ada8bd..99228b9159 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -42,6 +42,7 @@ where } /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. +/// By default, selector compression is turned **ON**. pub fn keygen_pk<'params, C, P, ConcreteCircuit>( params: &P, vk: VerifyingKey, diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index df04705608..fafc40c61e 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -23,6 +23,7 @@ pub fn create_proof< >( params: &'params Scheme::ParamsProver, pk: &ProvingKey, + compress_selectors: bool, circuits: &[ConcreteCircuit], instances: &[&[&[Scheme::Scalar]]], rng: R, @@ -35,7 +36,7 @@ where return Err(Error::Backend(ErrorBack::InvalidInstances)); } let (config, cs, _) = compile_circuit_cs::<_, ConcreteCircuit>( - true, + compress_selectors, #[cfg(feature = "circuit-params")] circuits[0].params(), ); @@ -99,12 +100,14 @@ fn test_create_proof() { let params: ParamsKZG = ParamsKZG::setup(3, OsRng); let vk = keygen_vk(¶ms, &MyCircuit).expect("keygen_vk should not fail"); let pk = keygen_pk(¶ms, vk, &MyCircuit).expect("keygen_pk should not fail"); + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); // Create proof with wrong number of instances let proof = create_proof::, ProverSHPLONK<_>, _, _, _, _>( ¶ms, &pk, + compress_selectors, &[MyCircuit, MyCircuit], &[], OsRng, @@ -119,6 +122,7 @@ fn test_create_proof() { create_proof::, ProverSHPLONK<_>, _, _, _, _>( ¶ms, &pk, + true, &[MyCircuit, MyCircuit], &[&[], &[]], OsRng, diff --git a/halo2_proofs/tests/frontend_backend_split.rs b/halo2_proofs/tests/frontend_backend_split.rs index 76249f48e8..7a3717d7f6 100644 --- a/halo2_proofs/tests/frontend_backend_split.rs +++ b/halo2_proofs/tests/frontend_backend_split.rs @@ -520,6 +520,7 @@ fn test_mycircuit_full_legacy() { let start = Instant::now(); let vk = keygen_vk(¶ms, &circuit).expect("keygen_vk should not fail"); let pk = keygen_pk(¶ms, vk.clone(), &circuit).expect("keygen_pk should not fail"); + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default println!("Keygen: {:?}", start.elapsed()); // Proving @@ -534,6 +535,7 @@ fn test_mycircuit_full_legacy() { create_proof::, ProverSHPLONK<'_, Bn256>, _, _, _, _>( ¶ms, &pk, + compress_selectors, &[circuit], &[instances_slice], &mut rng, diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index cd25fd9ba8..19ccc71392 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -451,7 +451,9 @@ fn plonk_api() { }}; } - fn keygen(params: &Scheme::ParamsProver) -> ProvingKey + fn keygen( + params: &Scheme::ParamsProver, + ) -> (ProvingKey, bool) where Scheme::Scalar: FromUniformBytes<64> + WithSmallOrderMulGroup<3>, { @@ -464,7 +466,11 @@ fn plonk_api() { // Initialize the proving key let vk = keygen_vk(params, &empty_circuit).expect("keygen_vk should not fail"); - keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail") + let pk = keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail"); + + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default + + (pk, compress_selectors) } fn create_proof< @@ -478,6 +484,7 @@ fn plonk_api() { rng: R, params: &'params Scheme::ParamsProver, pk: &ProvingKey, + compress_selectors: bool, ) -> Vec where Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>, @@ -494,6 +501,7 @@ fn plonk_api() { create_plonk_proof::( params, pk, + compress_selectors, &[circuit.clone(), circuit.clone()], &[&[&[instance]], &[&[instance]]], rng, @@ -556,10 +564,13 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let (pk, compress_selectors) = keygen::>(¶ms); let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, + rng, + ¶ms, + &pk, + compress_selectors, ); let verifier_params = params.verifier_params(); @@ -585,10 +596,13 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let (pk, compress_selectors) = keygen::>(¶ms); let proof = create_proof::<_, ProverSHPLONK<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, + rng, + ¶ms, + &pk, + compress_selectors, ); let verifier_params = params.verifier_params(); @@ -614,10 +628,13 @@ fn plonk_api() { let params = ParamsIPA::::new(K); let rng = OsRng; - let pk = keygen::>(¶ms); + let (pk, compress_selectors) = keygen::>(¶ms); let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, + rng, + ¶ms, + &pk, + compress_selectors, ); let verifier_params = params.verifier_params(); From dea0c6c480dc4bfed21abcbd99d36090e2e3dd92 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:53:42 +0800 Subject: [PATCH 03/11] chore: add the comments regarding the use of keygen utils --- halo2_proofs/src/plonk/keygen.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index 99228b9159..af64de7289 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -10,6 +10,10 @@ use halo2_middleware::ff::FromUniformBytes; /// Generate a `VerifyingKey` from an instance of `Circuit`. /// By default, selector compression is turned **ON**. +/// +/// **NOTE**: This `keygen_vk` is legacy one, assuming that `compress_selector: true`. +/// Hence, this one MUST be paired with `keygen_pk` util. +/// In addition, when using this for key generation, user MUST use `compress_selectors: true`. pub fn keygen_vk<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, @@ -26,6 +30,9 @@ where /// Generate a `VerifyingKey` from an instance of `Circuit`. /// /// The selector compression optimization is turned on only if `compress_selectors` is `true`. +/// +/// **NOTE**: This `keygen_vk_custom` MUST share the same `compress_selectors` with `keygen_pk_custom`. +/// Otherwise, the user would get unmatching pk/vk pair. pub fn keygen_vk_custom<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, @@ -43,6 +50,10 @@ where /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. /// By default, selector compression is turned **ON**. +/// +/// **NOTE**: This `keygen_pk` is legacy one, assuming that `compress_selector: true`. +/// Hence, this one MUST be paired with `keygen_vk` util. +/// In addition, when using this for key generation, user MUST use `compress_selectors: true`. pub fn keygen_pk<'params, C, P, ConcreteCircuit>( params: &P, vk: VerifyingKey, @@ -59,6 +70,9 @@ where /// Generate a `ProvingKey` from an instance of `Circuit`. /// /// The selector compression optimization is turned on only if `compress_selectors` is `true`. +/// +/// **NOTE**: This `keygen_pk_custom` MUST share the same `compress_selectors` with `keygen_vk_custom`. +/// Otherwise, the user would get unmatching pk/vk pair. pub fn keygen_pk_custom<'params, C, P, ConcreteCircuit>( params: &P, vk: VerifyingKey, From b4ed72142bf12521b4665c870b6eb65a41e86e21 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:21:14 +0800 Subject: [PATCH 04/11] fix: update the "halo2_proofs::benches::plonk.rs" code --- halo2_proofs/benches/plonk.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index e9c6954359..cb0b88f52a 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -266,7 +266,7 @@ fn criterion_benchmark(c: &mut Criterion) { } } - fn keygen(k: u32) -> (ParamsIPA, ProvingKey) { + fn keygen(k: u32) -> (ParamsIPA, ProvingKey, bool) { let params: ParamsIPA = ParamsIPA::new(k); let empty_circuit: MyCircuit = MyCircuit { a: Value::unknown(), @@ -274,10 +274,16 @@ fn criterion_benchmark(c: &mut Criterion) { }; 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"); - (params, pk) + let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default + (params, pk, compress_selectors) } - fn prover(k: u32, params: &ParamsIPA, pk: &ProvingKey) -> Vec { + fn prover( + k: u32, + params: &ParamsIPA, + pk: &ProvingKey, + compress_selectors: bool, + ) -> Vec { let rng = OsRng; let circuit: MyCircuit = MyCircuit { @@ -289,7 +295,7 @@ fn criterion_benchmark(c: &mut Criterion) { create_proof::, ProverIPA, _, _, _, _>( params, pk, - true, + compress_selectors, &[circuit], &[&[]], rng, @@ -319,13 +325,13 @@ fn criterion_benchmark(c: &mut Criterion) { let mut prover_group = c.benchmark_group("plonk-prover"); prover_group.sample_size(10); for k in k_range.clone() { - let (params, pk) = keygen(k); + let (params, pk, compress_selectors) = keygen(k); prover_group.bench_with_input( BenchmarkId::from_parameter(k), &(k, ¶ms, &pk), |b, &(k, params, pk)| { - b.iter(|| prover(k, params, pk)); + b.iter(|| prover(k, params, pk, compress_selectors)); }, ); } @@ -333,8 +339,8 @@ fn criterion_benchmark(c: &mut Criterion) { let mut verifier_group = c.benchmark_group("plonk-verifier"); for k in k_range { - let (params, pk) = keygen(k); - let proof = prover(k, ¶ms, &pk); + let (params, pk, compress_selectors) = keygen(k); + let proof = prover(k, ¶ms, &pk, compress_selectors); verifier_group.bench_with_input( BenchmarkId::from_parameter(k), From d87aab28685f1f77be370bdadad1099506628f3b Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Tue, 9 Apr 2024 10:07:51 +0800 Subject: [PATCH 05/11] chore: use the correct param for "test_create_proof" test --- halo2_proofs/src/plonk/prover.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index fafc40c61e..ac59b44266 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -122,7 +122,7 @@ fn test_create_proof() { create_proof::, ProverSHPLONK<_>, _, _, _, _>( ¶ms, &pk, - true, + compress_selectors, &[MyCircuit, MyCircuit], &[&[], &[]], OsRng, From 456caa24538029be10478360089e0b4d8d2c71ab Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Tue, 9 Apr 2024 10:26:15 +0800 Subject: [PATCH 06/11] chore: update the comments --- halo2_proofs/src/plonk/keygen.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index af64de7289..0c514b77f1 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -11,8 +11,8 @@ use halo2_middleware::ff::FromUniformBytes; /// Generate a `VerifyingKey` from an instance of `Circuit`. /// By default, selector compression is turned **ON**. /// -/// **NOTE**: This `keygen_vk` is legacy one, assuming that `compress_selector: true`. -/// Hence, this one MUST be paired with `keygen_pk` util. +/// **NOTE**: This `keygen_vk` is legacy one, assuming that `compress_selector: true`. +/// Hence, it is HIGHLY recommended to pair this util with `keygen_pk`. /// In addition, when using this for key generation, user MUST use `compress_selectors: true`. pub fn keygen_vk<'params, C, P, ConcreteCircuit>( params: &P, @@ -31,8 +31,10 @@ where /// /// The selector compression optimization is turned on only if `compress_selectors` is `true`. /// -/// **NOTE**: This `keygen_vk_custom` MUST share the same `compress_selectors` with `keygen_pk_custom`. -/// Otherwise, the user would get unmatching pk/vk pair. +/// **NOTE**: This `keygen_vk_custom` MUST share the same `compress_selectors` with +/// `ProvingKey` generation process. +/// Otherwise, the user could get unmatching pk/vk pair. +/// Hence, it is HIGHLY recommended to pair this util with `keygen_pk_custom`. pub fn keygen_vk_custom<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, @@ -51,8 +53,8 @@ where /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. /// By default, selector compression is turned **ON**. /// -/// **NOTE**: This `keygen_pk` is legacy one, assuming that `compress_selector: true`. -/// Hence, this one MUST be paired with `keygen_vk` util. +/// **NOTE**: This `keygen_pk` is legacy one, assuming that `compress_selector: true`. +/// Hence, it is HIGHLY recommended to pair this util with `keygen_vk`. /// In addition, when using this for key generation, user MUST use `compress_selectors: true`. pub fn keygen_pk<'params, C, P, ConcreteCircuit>( params: &P, @@ -71,8 +73,10 @@ where /// /// The selector compression optimization is turned on only if `compress_selectors` is `true`. /// -/// **NOTE**: This `keygen_pk_custom` MUST share the same `compress_selectors` with `keygen_vk_custom`. -/// Otherwise, the user would get unmatching pk/vk pair. +/// **NOTE**: This `keygen_pk_custom` MUST share the same `compress_selectors` with +/// `VerifyingKey` generation process. +/// Otherwise, the user could get unmatching pk/vk pair. +/// Hence, it is HIGHLY recommended to pair this util with `keygen_vk_custom`. pub fn keygen_pk_custom<'params, C, P, ConcreteCircuit>( params: &P, vk: VerifyingKey, From 3c8e4c4c75080e25d9650cf893ef63de6cccfe38 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:47:59 +0800 Subject: [PATCH 07/11] fix: roll back "create_proof" func --- halo2_proofs/benches/plonk.rs | 21 +++++-------- halo2_proofs/examples/serialization.rs | 1 - halo2_proofs/examples/shuffle.rs | 2 -- halo2_proofs/examples/shuffle_api.rs | 2 -- halo2_proofs/examples/vector-ops-unblinded.rs | 2 -- halo2_proofs/src/plonk/prover.rs | 2 -- halo2_proofs/tests/frontend_backend_split.rs | 2 -- halo2_proofs/tests/plonk_api.rs | 31 +++++-------------- 8 files changed, 15 insertions(+), 48 deletions(-) diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index cb0b88f52a..7551fde229 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -266,7 +266,7 @@ fn criterion_benchmark(c: &mut Criterion) { } } - fn keygen(k: u32) -> (ParamsIPA, ProvingKey, bool) { + fn keygen(k: u32) -> (ParamsIPA, ProvingKey) { let params: ParamsIPA = ParamsIPA::new(k); let empty_circuit: MyCircuit = MyCircuit { a: Value::unknown(), @@ -274,16 +274,10 @@ fn criterion_benchmark(c: &mut Criterion) { }; 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 compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default - (params, pk, compress_selectors) + (params, pk) } - fn prover( - k: u32, - params: &ParamsIPA, - pk: &ProvingKey, - compress_selectors: bool, - ) -> Vec { + fn prover(k: u32, params: &ParamsIPA, pk: &ProvingKey) -> Vec { let rng = OsRng; let circuit: MyCircuit = MyCircuit { @@ -295,7 +289,6 @@ fn criterion_benchmark(c: &mut Criterion) { create_proof::, ProverIPA, _, _, _, _>( params, pk, - compress_selectors, &[circuit], &[&[]], rng, @@ -325,13 +318,13 @@ fn criterion_benchmark(c: &mut Criterion) { let mut prover_group = c.benchmark_group("plonk-prover"); prover_group.sample_size(10); for k in k_range.clone() { - let (params, pk, compress_selectors) = keygen(k); + let (params, pk) = keygen(k); prover_group.bench_with_input( BenchmarkId::from_parameter(k), &(k, ¶ms, &pk), |b, &(k, params, pk)| { - b.iter(|| prover(k, params, pk, compress_selectors)); + b.iter(|| prover(k, params, pk)); }, ); } @@ -339,8 +332,8 @@ fn criterion_benchmark(c: &mut Criterion) { let mut verifier_group = c.benchmark_group("plonk-verifier"); for k in k_range { - let (params, pk, compress_selectors) = keygen(k); - let proof = prover(k, ¶ms, &pk, compress_selectors); + let (params, pk) = keygen(k); + let proof = prover(k, ¶ms, &pk); verifier_group.bench_with_input( BenchmarkId::from_parameter(k), diff --git a/halo2_proofs/examples/serialization.rs b/halo2_proofs/examples/serialization.rs index d0fcb7eebc..4a83392e37 100644 --- a/halo2_proofs/examples/serialization.rs +++ b/halo2_proofs/examples/serialization.rs @@ -167,7 +167,6 @@ fn main() { >( ¶ms, &pk, - compress_selectors, &[circuit], &[instances], OsRng, diff --git a/halo2_proofs/examples/shuffle.rs b/halo2_proofs/examples/shuffle.rs index 8c91fc34e8..f61d17fd09 100644 --- a/halo2_proofs/examples/shuffle.rs +++ b/halo2_proofs/examples/shuffle.rs @@ -279,7 +279,6 @@ fn test_prover( let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -287,7 +286,6 @@ fn test_prover( create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, - compress_selectors, &[circuit], &[&[]], OsRng, diff --git a/halo2_proofs/examples/shuffle_api.rs b/halo2_proofs/examples/shuffle_api.rs index f498700a64..f3080cd393 100644 --- a/halo2_proofs/examples/shuffle_api.rs +++ b/halo2_proofs/examples/shuffle_api.rs @@ -155,7 +155,6 @@ where let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -163,7 +162,6 @@ where create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, - compress_selectors, &[circuit], &[&[]], OsRng, diff --git a/halo2_proofs/examples/vector-ops-unblinded.rs b/halo2_proofs/examples/vector-ops-unblinded.rs index 688b16e4bb..386d6b34a3 100644 --- a/halo2_proofs/examples/vector-ops-unblinded.rs +++ b/halo2_proofs/examples/vector-ops-unblinded.rs @@ -478,7 +478,6 @@ where let params = ParamsIPA::::new(k); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let proof = { let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -486,7 +485,6 @@ where create_proof::, ProverIPA, _, _, _, _>( ¶ms, &pk, - compress_selectors, &[circuit], &[&[&instances]], OsRng, diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index ac59b44266..6f5369bc31 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -100,14 +100,12 @@ fn test_create_proof() { let params: ParamsKZG = ParamsKZG::setup(3, OsRng); let vk = keygen_vk(¶ms, &MyCircuit).expect("keygen_vk should not fail"); let pk = keygen_pk(¶ms, vk, &MyCircuit).expect("keygen_pk should not fail"); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); // Create proof with wrong number of instances let proof = create_proof::, ProverSHPLONK<_>, _, _, _, _>( ¶ms, &pk, - compress_selectors, &[MyCircuit, MyCircuit], &[], OsRng, diff --git a/halo2_proofs/tests/frontend_backend_split.rs b/halo2_proofs/tests/frontend_backend_split.rs index 7a3717d7f6..76249f48e8 100644 --- a/halo2_proofs/tests/frontend_backend_split.rs +++ b/halo2_proofs/tests/frontend_backend_split.rs @@ -520,7 +520,6 @@ fn test_mycircuit_full_legacy() { let start = Instant::now(); let vk = keygen_vk(¶ms, &circuit).expect("keygen_vk should not fail"); let pk = keygen_pk(¶ms, vk.clone(), &circuit).expect("keygen_pk should not fail"); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default println!("Keygen: {:?}", start.elapsed()); // Proving @@ -535,7 +534,6 @@ fn test_mycircuit_full_legacy() { create_proof::, ProverSHPLONK<'_, Bn256>, _, _, _, _>( ¶ms, &pk, - compress_selectors, &[circuit], &[instances_slice], &mut rng, diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index 19ccc71392..e8d65e9133 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -451,9 +451,7 @@ fn plonk_api() { }}; } - fn keygen( - params: &Scheme::ParamsProver, - ) -> (ProvingKey, bool) + fn keygen(params: &Scheme::ParamsProver) -> ProvingKey where Scheme::Scalar: FromUniformBytes<64> + WithSmallOrderMulGroup<3>, { @@ -468,9 +466,7 @@ fn plonk_api() { let pk = keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail"); - let compress_selectors = true; // legacy "keygen_vk" & "keygen_pk" compress selectors by default - - (pk, compress_selectors) + pk } fn create_proof< @@ -484,7 +480,6 @@ fn plonk_api() { rng: R, params: &'params Scheme::ParamsProver, pk: &ProvingKey, - compress_selectors: bool, ) -> Vec where Scheme::Scalar: Ord + WithSmallOrderMulGroup<3> + FromUniformBytes<64>, @@ -501,7 +496,6 @@ fn plonk_api() { create_plonk_proof::( params, pk, - compress_selectors, &[circuit.clone(), circuit.clone()], &[&[&[instance]], &[&[instance]]], rng, @@ -564,13 +558,10 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let (pk, compress_selectors) = keygen::>(¶ms); + let pk = keygen::>(¶ms); let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, - ¶ms, - &pk, - compress_selectors, + rng, ¶ms, &pk, ); let verifier_params = params.verifier_params(); @@ -596,13 +587,10 @@ fn plonk_api() { let params = ParamsKZG::::new(K); let rng = OsRng; - let (pk, compress_selectors) = keygen::>(¶ms); + let pk = keygen::>(¶ms); let proof = create_proof::<_, ProverSHPLONK<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, - ¶ms, - &pk, - compress_selectors, + rng, ¶ms, &pk, ); let verifier_params = params.verifier_params(); @@ -628,13 +616,10 @@ fn plonk_api() { let params = ParamsIPA::::new(K); let rng = OsRng; - let (pk, compress_selectors) = keygen::>(¶ms); + let pk = keygen::>(¶ms); let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, - ¶ms, - &pk, - compress_selectors, + rng, ¶ms, &pk, ); let verifier_params = params.verifier_params(); From 56f10ac782277a87bc38ba187774dfabcae96779 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:49:51 +0800 Subject: [PATCH 08/11] feat: add "create_proof_custom" func --- halo2_proofs/src/plonk.rs | 4 +- halo2_proofs/src/plonk/prover.rs | 109 +++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index c018961c87..bc9d5dd18b 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -12,9 +12,9 @@ mod verifier { pub use halo2_backend::plonk::verifier::verify_proof; } -pub use keygen::{keygen_pk, keygen_vk, keygen_vk_custom}; +pub use keygen::{keygen_pk, keygen_pk_custom, keygen_vk, keygen_vk_custom}; -pub use prover::create_proof; +pub use prover::{create_proof, create_proof_custom}; pub use verifier::verify_proof; pub use error::Error; diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 6f5369bc31..ef45ac54a0 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -20,6 +20,57 @@ pub fn create_proof< R: RngCore, T: TranscriptWrite, ConcreteCircuit: Circuit, +>( + params: &'params Scheme::ParamsProver, + pk: &ProvingKey, + circuits: &[ConcreteCircuit], + instances: &[&[&[Scheme::Scalar]]], + rng: R, + transcript: &mut T, +) -> Result<(), Error> +where + Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, +{ + if circuits.len() != instances.len() { + return Err(Error::Backend(ErrorBack::InvalidInstances)); + } + // This `create_proof` func is the legacy one, assuming that `compress_selectors: true`. + let (config, cs, _) = compile_circuit_cs::<_, ConcreteCircuit>( + true, + #[cfg(feature = "circuit-params")] + circuits[0].params(), + ); + let mut witness_calcs: Vec<_> = circuits + .iter() + .enumerate() + .map(|(i, circuit)| WitnessCalculator::new(params.k(), circuit, &config, &cs, instances[i])) + .collect(); + let mut prover = ProverV2::::new(params, pk, instances, rng, transcript)?; + let mut challenges = HashMap::new(); + let phases = prover.phases().to_vec(); + for phase in phases.iter() { + let mut witnesses = Vec::with_capacity(circuits.len()); + for witness_calc in witness_calcs.iter_mut() { + witnesses.push(witness_calc.calc(*phase, &challenges)?); + } + challenges = prover.commit_phase(*phase, witnesses).unwrap(); + } + Ok(prover.create_proof()?) +} + +/// This creates a proof for the provided `circuit` when given the public +/// parameters `params` and the proving key [`ProvingKey`] that was +/// generated previously for the same circuit. The provided `instances` +/// are zero-padded internally. +/// In addition, this needs the `compress_selectors` field. +pub fn create_proof_custom< + 'params, + Scheme: CommitmentScheme, + P: Prover<'params, Scheme>, + E: EncodedChallenge, + R: RngCore, + T: TranscriptWrite, + ConcreteCircuit: Circuit, >( params: &'params Scheme::ParamsProver, pk: &ProvingKey, @@ -118,6 +169,64 @@ fn test_create_proof() { // Create proof with correct number of instances create_proof::, ProverSHPLONK<_>, _, _, _, _>( + ¶ms, + &pk, + &[MyCircuit, MyCircuit], + &[&[], &[]], + OsRng, + &mut transcript, + ) + .expect("proof generation should not fail"); +} + +#[test] +fn test_create_proof_custom() { + use crate::{ + circuit::SimpleFloorPlanner, + plonk::{keygen_pk_custom, keygen_vk_custom, ConstraintSystem, ErrorFront}, + poly::kzg::{ + commitment::{KZGCommitmentScheme, ParamsKZG}, + multiopen::ProverSHPLONK, + }, + transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer}, + }; + use halo2_middleware::ff::Field; + use halo2curves::bn256::Bn256; + use rand_core::OsRng; + + #[derive(Clone, Copy)] + struct MyCircuit; + + impl Circuit for MyCircuit { + type Config = (); + type FloorPlanner = SimpleFloorPlanner; + #[cfg(feature = "circuit-params")] + type Params = (); + + fn without_witnesses(&self) -> Self { + *self + } + + fn configure(_meta: &mut ConstraintSystem) -> Self::Config {} + + fn synthesize( + &self, + _config: Self::Config, + _layouter: impl crate::circuit::Layouter, + ) -> Result<(), ErrorFront> { + Ok(()) + } + } + + let params: ParamsKZG = ParamsKZG::setup(3, OsRng); + let compress_selectors = true; + let vk = keygen_vk_custom(¶ms, &MyCircuit, compress_selectors) + .expect("keygen_vk_custom should not fail"); + let pk = keygen_pk_custom(¶ms, vk, &MyCircuit, compress_selectors) + .expect("keygen_pk_custom should not fail"); + let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); + + create_proof_custom::, ProverSHPLONK<_>, _, _, _, _>( ¶ms, &pk, compress_selectors, From 221c76e690a5260d64466a7be0edec9c098b1bc9 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:54:57 +0800 Subject: [PATCH 09/11] chore: clippy --- halo2_proofs/tests/plonk_api.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index e8d65e9133..cd25fd9ba8 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -464,9 +464,7 @@ fn plonk_api() { // Initialize the proving key let vk = keygen_vk(params, &empty_circuit).expect("keygen_vk should not fail"); - let pk = keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail"); - - pk + keygen_pk(params, vk, &empty_circuit).expect("keygen_pk should not fail") } fn create_proof< From 9074fad671b75e775db455e52587069c9ac5d3b8 Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Wed, 10 Apr 2024 21:14:05 +0800 Subject: [PATCH 10/11] chore: remove duplicate in "create_proof" func --- halo2_proofs/src/plonk/prover.rs | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index ef45ac54a0..ab4af8227f 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -31,31 +31,9 @@ pub fn create_proof< where Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, { - if circuits.len() != instances.len() { - return Err(Error::Backend(ErrorBack::InvalidInstances)); - } - // This `create_proof` func is the legacy one, assuming that `compress_selectors: true`. - let (config, cs, _) = compile_circuit_cs::<_, ConcreteCircuit>( - true, - #[cfg(feature = "circuit-params")] - circuits[0].params(), - ); - let mut witness_calcs: Vec<_> = circuits - .iter() - .enumerate() - .map(|(i, circuit)| WitnessCalculator::new(params.k(), circuit, &config, &cs, instances[i])) - .collect(); - let mut prover = ProverV2::::new(params, pk, instances, rng, transcript)?; - let mut challenges = HashMap::new(); - let phases = prover.phases().to_vec(); - for phase in phases.iter() { - let mut witnesses = Vec::with_capacity(circuits.len()); - for witness_calc in witness_calcs.iter_mut() { - witnesses.push(witness_calc.calc(*phase, &challenges)?); - } - challenges = prover.commit_phase(*phase, witnesses).unwrap(); - } - Ok(prover.create_proof()?) + create_proof_custom::( + params, pk, true, circuits, instances, rng, transcript, + ) } /// This creates a proof for the provided `circuit` when given the public From 8b3bdf5a59a3b3247b0605af2a384bbf9c88505b Mon Sep 17 00:00:00 2001 From: duguorong <80258679+duguorong009@users.noreply.github.com> Date: Thu, 11 Apr 2024 21:48:44 +0800 Subject: [PATCH 11/11] chore: fmt + clippy --- halo2_proofs/src/plonk.rs | 2 +- halo2_proofs/src/plonk/prover.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 8674174036..5c475d699b 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -14,7 +14,7 @@ mod verifier { pub use keygen::{keygen_pk, keygen_pk_custom, keygen_vk, keygen_vk_custom}; -pub use prover::{create_proof, create_proof_with_engine, create_proof_custom_with_engine}; +pub use prover::{create_proof, create_proof_custom_with_engine, create_proof_with_engine}; pub use verifier::verify_proof; pub use error::Error; diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 1b627212ca..01e220f6a8 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -37,7 +37,9 @@ pub fn create_proof_with_engine< where Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, { - create_proof_custom_with_engine::(engine, params, pk, true, circuits, instances, rng, transcript) + create_proof_custom_with_engine::( + engine, params, pk, true, circuits, instances, rng, transcript, + ) } /// This creates a proof for the provided `circuit` when given the public @@ -74,6 +76,7 @@ where /// generated previously for the same circuit. The provided `instances` /// are zero-padded internally. /// In addition, this needs the `compress_selectors` field. +#[allow(clippy::too_many_arguments)] pub fn create_proof_custom_with_engine< 'params, Scheme: CommitmentScheme, @@ -241,7 +244,7 @@ fn test_create_proof_custom() { .expect("keygen_pk_custom should not fail"); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); let engine = PlonkEngineConfig::build_default(); - + create_proof_custom_with_engine::, ProverSHPLONK<_>, _, _, _, _, _>( engine, ¶ms,