From 95859f01e0ed6ad9cdc850e69b18a7d8824701e9 Mon Sep 17 00:00:00 2001 From: moana Date: Thu, 5 Oct 2023 12:59:41 +0200 Subject: [PATCH 1/2] Add `size` method to `Circuit` trait This change also removes the need to preallocate the circuit builder which in turn removes the need to pass the public parameters when compressing a circuit. --- src/composer.rs | 37 +++++++++++++++---------------- src/composer/builder.rs | 8 +++---- src/composer/circuit.rs | 12 ++++++++++ src/composer/compiler.rs | 20 ++++------------- src/composer/compiler/compress.rs | 24 +++++++++----------- src/debugger.rs | 7 ++++++ src/runtime.rs | 9 ++++++++ tests/composer.rs | 2 +- 8 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/composer.rs b/src/composer.rs index 045fbe92..8d953da4 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -60,7 +60,7 @@ pub trait Composer: Sized + Index { since = "13.0", note = "this function is meant for internal use. call `initialized` instead" )] - fn uninitialized(capacity: usize) -> Self; + fn uninitialized() -> Self; /// Constraints count fn constraints(&self) -> usize; @@ -82,6 +82,22 @@ pub trait Composer: Sized + Index { /// PLONK runtime controller fn runtime(&mut self) -> &mut Runtime; + /// Initialize the constraint system with dummy gates + fn initialized() -> Self { + #[allow(deprecated)] + let mut slf = Self::uninitialized(); + + let zero = slf.append_witness(0); + let one = slf.append_witness(1); + + slf.assert_equal_constant(zero, 0, None); + slf.assert_equal_constant(one, 1, None); + + slf.append_dummy_gates(); + + slf + } + /// Allocate a witness value into the composer and return its index. fn append_witness>(&mut self, witness: W) -> Witness { let witness = witness.into(); @@ -378,23 +394,6 @@ pub trait Composer: Sized + Index { Ok(WitnessPoint::new(acc_x, acc_y)) } - /// Initialize the constraint system with dummy gates - fn initialized(capacity: usize) -> Self { - #[allow(deprecated)] - let mut slf = Self::uninitialized(capacity); - - let zero = slf.append_witness(0); - let one = slf.append_witness(1); - - slf.assert_equal_constant(zero, 0, None); - slf.assert_equal_constant(one, 1, None); - - slf.append_dummy_gates(); - slf.append_dummy_gates(); - - slf - } - /// Append a new width-4 poly gate/constraint. /// /// The constraint added will enforce the following: @@ -1051,7 +1050,7 @@ pub trait Composer: Sized + Index { where C: Circuit, { - let mut builder = Self::initialized(constraints); + let mut builder = Self::initialized(); circuit.circuit(&mut builder)?; diff --git a/src/composer/builder.rs b/src/composer/builder.rs index 2fb51166..03734283 100644 --- a/src/composer/builder.rs +++ b/src/composer/builder.rs @@ -77,13 +77,13 @@ impl ops::Index for Builder { } impl Composer for Builder { - fn uninitialized(capacity: usize) -> Self { + fn uninitialized() -> Self { Self { - constraints: Vec::with_capacity(capacity), + constraints: Vec::new(), public_inputs: HashMap::new(), - witnesses: Vec::with_capacity(capacity), + witnesses: Vec::new(), perm: Permutation::new(), - runtime: Runtime::with_capacity(capacity), + runtime: Runtime::new(), } } diff --git a/src/composer/circuit.rs b/src/composer/circuit.rs index ffb545bd..deba2055 100644 --- a/src/composer/circuit.rs +++ b/src/composer/circuit.rs @@ -16,4 +16,16 @@ pub trait Circuit: Default { fn circuit(&self, composer: &mut C) -> Result<(), Error> where C: Composer; + + /// Returns the size of the circuit. + fn size(&self) -> usize + where + C: Composer, + { + let mut composer = C::initialized(); + match self.circuit(&mut composer) { + Ok(_) => composer.constraints(), + Err(_) => 0, + } + } } diff --git a/src/composer/compiler.rs b/src/composer/compiler.rs index 4d02593c..82c1c09d 100644 --- a/src/composer/compiler.rs +++ b/src/composer/compiler.rs @@ -35,9 +35,7 @@ impl Compiler { where C: Circuit, { - let max_size = Self::max_size(pp); - let mut builder = Builder::initialized(max_size); - + let mut builder = Builder::initialized(); C::default().circuit(&mut builder)?; Self::compile_with_builder(pp, label, &builder) @@ -54,9 +52,7 @@ impl Compiler { where C: Circuit, { - let max_size = Self::max_size(pp); - let mut builder = Builder::initialized(max_size); - + let mut builder = Builder::initialized(); circuit.circuit(&mut builder)?; Self::compile_with_builder(pp, label, &builder) @@ -65,14 +61,11 @@ impl Compiler { /// Return a bytes representation of a compressed circuit, capable of /// generating its prover and verifier instances. #[cfg(feature = "alloc")] - pub fn compress(pp: &PublicParameters) -> Result, Error> + pub fn compress() -> Result, Error> where C: Circuit, { - compress::CompressedCircuit::from_circuit::( - pp, - compress::Version::V2, - ) + compress::CompressedCircuit::from_circuit::(compress::Version::V2) } /// Generates a [Prover] and [Verifier] from a buffer created by @@ -85,11 +78,6 @@ impl Compiler { compress::CompressedCircuit::from_bytes(pp, label, compressed) } - /// Returns the maximum constraints length for the parameters. - fn max_size(pp: &PublicParameters) -> usize { - (pp.commit_key.powers_of_g.len() - 1) >> 1 - } - /// Create a new arguments set from a given circuit instance /// /// Use the default implementation of the circuit diff --git a/src/composer/compiler/compress.rs b/src/composer/compiler/compress.rs index f9c9cf06..069fab06 100644 --- a/src/composer/compiler/compress.rs +++ b/src/composer/compiler/compress.rs @@ -89,19 +89,15 @@ pub struct CompressedCircuit { witnesses: usize, scalars: Vec<[u8; BlsScalar::SIZE]>, polynomials: Vec, - circuit: Vec, + constraints: Vec, } impl CompressedCircuit { - pub fn from_circuit( - pp: &PublicParameters, - version: Version, - ) -> Result, Error> + pub fn from_circuit(version: Version) -> Result, Error> where C: Circuit, { - let max_size = Compiler::max_size(pp); - let mut builder = Builder::initialized(max_size); + let mut builder = Builder::initialized(); C::default().circuit(&mut builder)?; Ok(Self::from_builder(version, builder)) } @@ -114,11 +110,11 @@ impl CompressedCircuit { let witnesses = builder.witnesses.len(); let polynomials = builder.constraints; - let circuit = polynomials.into_iter(); + let constraints = polynomials.into_iter(); let mut scalars = version.into_scalars(); let base_scalars_len = scalars.len(); let mut polynomials = HashMap::new(); - let circuit = circuit + let constraints = constraints .map( |Polynomial { q_m, @@ -213,12 +209,12 @@ impl CompressedCircuit { witnesses, scalars, polynomials, - circuit, + constraints, }; let mut buf = Vec::with_capacity( 1 + compressed.scalars.len() * BlsScalar::SIZE + compressed.polynomials.len() * 88 - + compressed.circuit.len() * 40, + + compressed.constraints.len() * 40, ); compressed.pack(&mut buf); miniz_oxide::deflate::compress_to_vec(&buf, 10) @@ -239,7 +235,7 @@ impl CompressedCircuit { witnesses, scalars, polynomials, - circuit, + constraints, }, ) = Self::unpack(&compressed) .map_err(|_| Error::InvalidCompressedCircuit)?; @@ -258,7 +254,7 @@ impl CompressedCircuit { #[allow(deprecated)] // we use `uninitialized` because the decompressor will also contain the // dummy constraints, if they were part of the prover when encoding. - let mut builder = Builder::uninitialized(circuit.len()); + let mut builder = Builder::uninitialized(); let mut pi = 0; (0..witnesses).for_each(|_| { @@ -274,7 +270,7 @@ impl CompressedCircuit { w_d, w_o, }, - ) in circuit.into_iter().enumerate() + ) in constraints.into_iter().enumerate() { let CompressedPolynomial { q_m, diff --git a/src/debugger.rs b/src/debugger.rs index b9e967e8..87514804 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -181,6 +181,13 @@ impl Debugger { } } + pub(crate) fn new() -> Self { + Self { + witnesses: Vec::new(), + constraints: Vec::new(), + } + } + pub(crate) fn with_capacity(capacity: usize) -> Self { Self { witnesses: Vec::with_capacity(capacity), diff --git a/src/runtime.rs b/src/runtime.rs index a23aca1a..b3c939a0 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -42,6 +42,15 @@ pub struct Runtime { } impl Runtime { + /// Create a new PLONK runtime + #[allow(unused_variables)] + pub fn new() -> Self { + Self { + #[cfg(feature = "debug")] + debugger: Debugger::new(), + } + } + /// Create a new PLONK runtime with the provided capacity #[allow(unused_variables)] pub fn with_capacity(capacity: usize) -> Self { diff --git a/tests/composer.rs b/tests/composer.rs index 79ecb863..7818827a 100644 --- a/tests/composer.rs +++ b/tests/composer.rs @@ -87,7 +87,7 @@ fn circuit_with_all_gates() { let (prover, verifier) = Compiler::compile::(&pp, label) .expect("failed to compile circuit"); - let compressed = Compiler::compress::(&pp) + let compressed = Compiler::compress::() .expect("failed to compress circuit"); let (decompressed_prover, decompressed_verifier) = From 0e0b3d4213544b62bb5e89efdb1b18cce463369e Mon Sep 17 00:00:00 2001 From: moana Date: Thu, 5 Oct 2023 15:02:11 +0200 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e69dd1..ae3c5f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `size` method to the `Circuit` trait [#767] + +### Removed + +- Remove public parametes as parameters for circuit compression [#767] + ## [0.15.0] - 2023-08-30 ### Fixed