From 27f8b802a2be0f1ff39cc438f7dd1d4b2b917977 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 30 Dec 2020 19:06:58 -0800 Subject: [PATCH 01/10] finalize method --- relations/src/r1cs/constraint_system.rs | 35 +++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index c001985d7..7afa20906 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -47,6 +47,10 @@ pub struct ConstraintSystem { /// The number of linear combinations pub num_linear_combinations: usize, + /// The parameter we aim to minimize in this constraint system (either the + /// number of constraints or their total weight). + pub optimization_goal: OptimizationGoal, + /// Assignments to the public input variables. This is empty if `self.mode /// == SynthesisMode::Setup`. pub instance_assignment: Vec, @@ -91,6 +95,16 @@ pub enum SynthesisMode { }, } +/// Defines the parameter to optimize for a `ConstraintSystem`. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub enum OptimizationGoal { + /// Minimize the number of constraints. + Constraints, + /// Minimize the total weight of the constraints (the number of nonzero + /// entries across all constraints). + Weight, +} + impl ConstraintSystem { #[inline] fn make_row(&self, l: &LinearCombination) -> Vec<(F, usize)> { @@ -109,7 +123,7 @@ impl ConstraintSystem { .collect() } - /// Construct an ampty `ConstraintSystem`. + /// Construct an empty `ConstraintSystem`. pub fn new() -> Self { Self { num_instance_variables: 1, @@ -131,6 +145,8 @@ impl ConstraintSystem { mode: SynthesisMode::Prove { construct_matrices: true, }, + + optimization_goal: OptimizationGoal::Constraints, } } @@ -149,6 +165,12 @@ impl ConstraintSystem { self.mode == SynthesisMode::Setup } + /// Check whether this constraint system aims to optimize weight, + /// rather than number of constraints. + pub fn is_optimizing_weight(&self) -> bool { + self.optimization_goal == OptimizationGoal::Weight + } + /// Check whether or not `self` will construct matrices. pub fn should_construct_matrices(&self) -> bool { match self.mode { @@ -481,10 +503,19 @@ impl ConstraintSystem { /// Useful for SNARKs like [\[Marlin\]](https://eprint.iacr.org/2019/1047) or /// [\[Fractal\]](https://eprint.iacr.org/2019/1076), where addition gates /// are not cheap. - pub fn reduce_constraint_weight(&mut self) { + fn reduce_constraint_weight(&mut self) { self.outline_lcs(); } + /// Finalize the constraint system (either by outlining or inlining, depending + /// on the set optimization mode). + pub fn finalize(&mut self) { + match self.optimization_goal { + OptimizationGoal::Constraints => self.inline_all_lcs(), + OptimizationGoal::Weight => self.outline_lcs(), + }; + } + /// This step must be called after constraint generation has completed, and /// after all symbolic LCs have been inlined into the places that they /// are used. From 31a16cdfccd0c0f28b8169a92281c2b61200b3cd Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 30 Dec 2020 21:41:08 -0800 Subject: [PATCH 02/10] setter/getter, and wrapprs in ConstraintSystemRef --- relations/src/r1cs/constraint_system.rs | 37 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index 7afa20906..4d9c6de06 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -165,10 +165,16 @@ impl ConstraintSystem { self.mode == SynthesisMode::Setup } - /// Check whether this constraint system aims to optimize weight, - /// rather than number of constraints. - pub fn is_optimizing_weight(&self) -> bool { - self.optimization_goal == OptimizationGoal::Weight + /// Check whether this constraint system aims to optimize weight or + /// number of constraints. + pub fn get_optimization_goal(&self) -> OptimizationGoal { + self.optimization_goal + } + + /// Specify whether this constraint system should aim to optimize weight + /// or number of constraints. + pub fn set_optimization_goal(&mut self, goal: OptimizationGoal) { + self.optimization_goal = goal; } /// Check whether or not `self` will construct matrices. @@ -813,6 +819,21 @@ impl ConstraintSystemRef { .map_or(0, |cs| cs.borrow().num_witness_variables) } + /// Check whether this constraint system aims to optimize weight or + /// number of constraints. + #[inline] + pub fn get_optimization_goal(&self) -> OptimizationGoal { + self.inner() + .map_or(OptimizationGoal::Constraints, |cs| cs.borrow().get_optimization_goal()) + } + + /// Specify whether this constraint system should aim to optimize weight + /// or number of constraints. + #[inline] + pub fn set_optimization_goal(&self, goal: OptimizationGoal) { + self.inner().map_or((), |cs| cs.borrow_mut().set_optimization_goal(goal)) + } + /// Check whether or not `self` will construct matrices. #[inline] pub fn should_construct_matrices(&self) -> bool { @@ -906,6 +927,14 @@ impl ConstraintSystemRef { } } + /// Finalize the constraint system (either by outlining or inlining, depending + /// on the set optimization mode). + pub fn finalize(&self) { + if let Some(cs) = self.inner() { + cs.borrow_mut().finalize() + } + } + /// This step must be called after constraint generation has completed, and /// after all symbolic LCs have been inlined into the places that they /// are used. From 4c4ad1c55a4df4a6aedd3db981eabb0323c97f22 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Wed, 30 Dec 2020 21:48:32 -0800 Subject: [PATCH 03/10] style --- relations/src/r1cs/constraint_system.rs | 57 ++++++++++++++----------- relations/src/r1cs/error.rs | 6 +-- relations/src/r1cs/impl_lc.rs | 6 +-- relations/src/r1cs/trace.rs | 2 +- snark/src/lib.rs | 26 +++++------ 5 files changed, 52 insertions(+), 45 deletions(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index 4d9c6de06..da8032a0f 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -266,7 +266,8 @@ impl ConstraintSystem { Ok(()) } - /// Count the number of times each LC is used within other LCs in the constraint system + /// Count the number of times each LC is used within other LCs in the + /// constraint system fn lc_num_times_used(&self, count_sinks: bool) -> Vec { let mut num_times_used = vec![0; self.lc_map.len()]; @@ -288,16 +289,17 @@ impl ConstraintSystem { /// Transform the map of linear combinations. /// Specifically, allow the creation of additional witness assignments. /// - /// This method is used as a subroutine of `inline_all_lcs` and `outline_lcs`. + /// This method is used as a subroutine of `inline_all_lcs` and + /// `outline_lcs`. /// - /// The transformer function is given a references of this constraint system (&self), - /// number of times used, and a mutable reference of the linear combination to be transformed. - /// (&ConstraintSystem, usize, &mut LinearCombination) - /// - /// The transformer function returns the number of new witness variables needed - /// and a vector of new witness assignments (if not in the setup mode). - /// (usize, Option>) + /// The transformer function is given a references of this constraint system + /// (&self), number of times used, and a mutable reference of the linear + /// combination to be transformed. (&ConstraintSystem, usize, + /// &mut LinearCombination) /// + /// The transformer function returns the number of new witness variables + /// needed and a vector of new witness assignments (if not in the setup + /// mode). (usize, Option>) pub fn transform_lc_map( &mut self, transformer: &mut dyn FnMut( @@ -337,14 +339,14 @@ impl ConstraintSystem { // Delete linear combinations that are no longer used. // // Deletion is safe for both outlining and inlining: - // * Inlining: the LC is substituted directly into all use - // sites, and so once it is fully inlined, it is redundant. + // * Inlining: the LC is substituted directly into all use sites, and so once it + // is fully inlined, it is redundant. // - // * Outlining: the LC is associated with a new variable `w`, - // and a new constraint of the form `lc_data * 1 = w`, where - // `lc_data` is the actual data in the linear combination. - // Furthermore, we replace its entry in `new_lc_map` with `(1, w)`. - // Once `w` is fully inlined, then we can delete the entry from `new_lc_map` + // * Outlining: the LC is associated with a new variable `w`, and a new + // constraint of the form `lc_data * 1 = w`, where `lc_data` is the actual + // data in the linear combination. Furthermore, we replace its entry in + // `new_lc_map` with `(1, w)`. Once `w` is fully inlined, then we can delete + // the entry from `new_lc_map` // num_times_used[lc_index.0] -= 1; if num_times_used[lc_index.0] == 0 { @@ -432,8 +434,9 @@ impl ConstraintSystem { // If true, the LC is replaced with 1 * this witness variable. // Otherwise, the LC is inlined. // - // Each iteration first updates the LC according to outlinings in prior iterations, - // and then sees if it should be outlined, and if so adds the outlining to the map. + // Each iteration first updates the LC according to outlinings in prior + // iterations, and then sees if it should be outlined, and if so adds + // the outlining to the map. // self.transform_lc_map(&mut |cs, num_times_used, inlined_lc| { let mut should_dedicate_a_witness_variable = false; @@ -513,8 +516,8 @@ impl ConstraintSystem { self.outline_lcs(); } - /// Finalize the constraint system (either by outlining or inlining, depending - /// on the set optimization mode). + /// Finalize the constraint system (either by outlining or inlining, + /// depending on the set optimization mode). pub fn finalize(&mut self) { match self.optimization_goal { OptimizationGoal::Constraints => self.inline_all_lcs(), @@ -641,7 +644,7 @@ impl ConstraintSystem { self.lc_assignment_cache.borrow_mut().insert(idx, value); Some(value) } - } + }, } } } @@ -823,15 +826,17 @@ impl ConstraintSystemRef { /// number of constraints. #[inline] pub fn get_optimization_goal(&self) -> OptimizationGoal { - self.inner() - .map_or(OptimizationGoal::Constraints, |cs| cs.borrow().get_optimization_goal()) + self.inner().map_or(OptimizationGoal::Constraints, |cs| { + cs.borrow().get_optimization_goal() + }) } /// Specify whether this constraint system should aim to optimize weight /// or number of constraints. #[inline] pub fn set_optimization_goal(&self, goal: OptimizationGoal) { - self.inner().map_or((), |cs| cs.borrow_mut().set_optimization_goal(goal)) + self.inner() + .map_or((), |cs| cs.borrow_mut().set_optimization_goal(goal)) } /// Check whether or not `self` will construct matrices. @@ -927,8 +932,8 @@ impl ConstraintSystemRef { } } - /// Finalize the constraint system (either by outlining or inlining, depending - /// on the set optimization mode). + /// Finalize the constraint system (either by outlining or inlining, + /// depending on the set optimization mode). pub fn finalize(&self) { if let Some(cs) = self.inner() { cs.borrow_mut().finalize() diff --git a/relations/src/r1cs/error.rs b/relations/src/r1cs/error.rs index 162b2b735..3a4136966 100644 --- a/relations/src/r1cs/error.rs +++ b/relations/src/r1cs/error.rs @@ -31,17 +31,17 @@ impl fmt::Display for SynthesisError { SynthesisError::MissingCS => write!(f, "the constraint system was `None`"), SynthesisError::AssignmentMissing => { write!(f, "an assignment for a variable could not be computed") - } + }, SynthesisError::DivisionByZero => write!(f, "division by zero"), SynthesisError::Unsatisfiable => write!(f, "unsatisfiable constraint system"), SynthesisError::PolynomialDegreeTooLarge => write!(f, "polynomial degree is too large"), SynthesisError::UnexpectedIdentity => { write!(f, "encountered an identity element in the CRS") - } + }, SynthesisError::MalformedVerifyingKey => write!(f, "malformed verifying key"), SynthesisError::UnconstrainedVariable => { write!(f, "auxiliary variable was unconstrained") - } + }, } } } diff --git a/relations/src/r1cs/impl_lc.rs b/relations/src/r1cs/impl_lc.rs index 1af389643..c56abce5e 100644 --- a/relations/src/r1cs/impl_lc.rs +++ b/relations/src/r1cs/impl_lc.rs @@ -228,16 +228,16 @@ where Ordering::Greater => { new_vec.push((push_fn(other[j].0), other[j].1)); j += 1; - } + }, Ordering::Less => { new_vec.push(*self_cur); i += 1; - } + }, Ordering::Equal => { new_vec.push((combine_fn(self_cur.0, other_cur.0), self_cur.1)); i += 1; j += 1; - } + }, }; } new_vec.extend_from_slice(&cur[i..]); diff --git a/relations/src/r1cs/trace.rs b/relations/src/r1cs/trace.rs index fe9570589..341d168d6 100644 --- a/relations/src/r1cs/trace.rs +++ b/relations/src/r1cs/trace.rs @@ -68,7 +68,7 @@ where id if id == TypeId::of::() => Some(self as *const _ as *const ()), id if id == TypeId::of::() => { Some(&self.get_context as *const _ as *const ()) - } + }, _ => None, } } diff --git a/snark/src/lib.rs b/snark/src/lib.rs index 46ffb2c1f..065f22111 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -35,8 +35,8 @@ pub trait SNARK { /// Errors encountered during setup, proving, or verification. type Error: 'static + ark_std::error::Error; - /// Takes in a description of a computation (specified in R1CS constraints), and - /// samples proving and verification keys for that circuit. + /// Takes in a description of a computation (specified in R1CS constraints), + /// and samples proving and verification keys for that circuit. fn circuit_specific_setup, R: RngCore + CryptoRng>( circuit: C, rng: &mut R, @@ -51,8 +51,8 @@ pub trait SNARK { ) -> Result; /// Checks that `proof` is a valid proof of the satisfaction of circuit - /// encoded in `circuit_vk`, with respect to the public input `public_input`. - /// as R1CS constraints). + /// encoded in `circuit_vk`, with respect to the public input + /// `public_input`. as R1CS constraints). fn verify( circuit_vk: &Self::VerifyingKey, public_input: &[F], @@ -68,8 +68,8 @@ pub trait SNARK { ) -> Result; /// Checks that `proof` is a valid proof of the satisfaction of circuit - /// encoded in `circuit_pvk`, with respect to the public input `public_input`. - /// as R1CS constraints). + /// encoded in `circuit_pvk`, with respect to the public input + /// `public_input`. as R1CS constraints). fn verify_with_processed_vk( circuit_pvk: &Self::ProcessedVerifyingKey, public_input: &[F], @@ -102,21 +102,23 @@ pub enum UniversalSetupIndexError { /// A SNARK with universal setup. That is, a SNARK where the trusted setup is /// circuit-independent. pub trait UniversalSetupSNARK: SNARK { - /// Specifies how to bound the size of public parameters required to generate - /// the index proving and verification keys for a given circuit. + /// Specifies how to bound the size of public parameters required to + /// generate the index proving and verification keys for a given + /// circuit. type ComputationBound: Clone + Default + Debug; /// Specifies the type of universal public parameters. type PublicParameters: Clone + Debug; - /// Specifies how to bound the size of public parameters required to generate - /// the index proving and verification keys for a given circuit. + /// Specifies how to bound the size of public parameters required to + /// generate the index proving and verification keys for a given + /// circuit. fn universal_setup( compute_bound: &Self::ComputationBound, rng: &mut R, ) -> Result; - /// Indexes the public parameters according to the circuit `circuit`, and outputs - /// circuit-specific proving and verification keys. + /// Indexes the public parameters according to the circuit `circuit`, and + /// outputs circuit-specific proving and verification keys. fn index, R: RngCore + CryptoRng>( pp: &Self::PublicParameters, circuit: C, From afd19bbb64fdbfe29b22462ffa7130c7ca7b92b7 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 31 Dec 2020 11:19:22 -0800 Subject: [PATCH 04/10] incorporate comments --- relations/src/r1cs/constraint_system.rs | 49 +++++++++++++------------ relations/src/r1cs/error.rs | 6 +-- relations/src/r1cs/impl_lc.rs | 6 +-- relations/src/r1cs/trace.rs | 2 +- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index da8032a0f..5ae957808 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -98,6 +98,8 @@ pub enum SynthesisMode { /// Defines the parameter to optimize for a `ConstraintSystem`. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum OptimizationGoal { + /// Make no attempt to optimize. + None, /// Minimize the number of constraints. Constraints, /// Minimize the total weight of the constraints (the number of nonzero @@ -146,7 +148,7 @@ impl ConstraintSystem { construct_matrices: true, }, - optimization_goal: OptimizationGoal::Constraints, + optimization_goal: OptimizationGoal::None, } } @@ -165,14 +167,14 @@ impl ConstraintSystem { self.mode == SynthesisMode::Setup } - /// Check whether this constraint system aims to optimize weight or - /// number of constraints. - pub fn get_optimization_goal(&self) -> OptimizationGoal { + /// Check whether this constraint system aims to optimize weight, + /// number of constraints, or neither. + pub fn optimization_goal(&self) -> OptimizationGoal { self.optimization_goal } - /// Specify whether this constraint system should aim to optimize weight - /// or number of constraints. + /// Specify whether this constraint system should aim to optimize weight, + /// number of constraints, or neither. pub fn set_optimization_goal(&mut self, goal: OptimizationGoal) { self.optimization_goal = goal; } @@ -289,17 +291,15 @@ impl ConstraintSystem { /// Transform the map of linear combinations. /// Specifically, allow the creation of additional witness assignments. /// - /// This method is used as a subroutine of `inline_all_lcs` and - /// `outline_lcs`. + /// This method is used as a subroutine of `inline_all_lcs` and `outline_lcs`. /// - /// The transformer function is given a references of this constraint system - /// (&self), number of times used, and a mutable reference of the linear - /// combination to be transformed. (&ConstraintSystem, usize, - /// &mut LinearCombination) + /// The transformer function is given a references of this constraint system (&self), + /// number of times used, and a mutable reference of the linear combination to be transformed. + /// (&ConstraintSystem, usize, &mut LinearCombination) /// - /// The transformer function returns the number of new witness variables - /// needed and a vector of new witness assignments (if not in the setup - /// mode). (usize, Option>) + /// The transformer function returns the number of new witness variables needed + /// and a vector of new witness assignments (if not in the setup mode). + /// (usize, Option>) pub fn transform_lc_map( &mut self, transformer: &mut dyn FnMut( @@ -517,9 +517,10 @@ impl ConstraintSystem { } /// Finalize the constraint system (either by outlining or inlining, - /// depending on the set optimization mode). + /// if an optimization goal is set). pub fn finalize(&mut self) { match self.optimization_goal { + OptimizationGoal::None => (), OptimizationGoal::Constraints => self.inline_all_lcs(), OptimizationGoal::Weight => self.outline_lcs(), }; @@ -644,7 +645,7 @@ impl ConstraintSystem { self.lc_assignment_cache.borrow_mut().insert(idx, value); Some(value) } - }, + } } } } @@ -822,17 +823,17 @@ impl ConstraintSystemRef { .map_or(0, |cs| cs.borrow().num_witness_variables) } - /// Check whether this constraint system aims to optimize weight or - /// number of constraints. + /// Check whether this constraint system aims to optimize weight, + /// number of constraints, or neither. #[inline] - pub fn get_optimization_goal(&self) -> OptimizationGoal { + pub fn optimization_goal(&self) -> OptimizationGoal { self.inner().map_or(OptimizationGoal::Constraints, |cs| { - cs.borrow().get_optimization_goal() + cs.borrow().optimization_goal() }) } - /// Specify whether this constraint system should aim to optimize weight - /// or number of constraints. + /// Specify whether this constraint system should aim to optimize weight, + /// number of constraints, or neither. #[inline] pub fn set_optimization_goal(&self, goal: OptimizationGoal) { self.inner() @@ -933,7 +934,7 @@ impl ConstraintSystemRef { } /// Finalize the constraint system (either by outlining or inlining, - /// depending on the set optimization mode). + /// if an optimization goal is set). pub fn finalize(&self) { if let Some(cs) = self.inner() { cs.borrow_mut().finalize() diff --git a/relations/src/r1cs/error.rs b/relations/src/r1cs/error.rs index 3a4136966..162b2b735 100644 --- a/relations/src/r1cs/error.rs +++ b/relations/src/r1cs/error.rs @@ -31,17 +31,17 @@ impl fmt::Display for SynthesisError { SynthesisError::MissingCS => write!(f, "the constraint system was `None`"), SynthesisError::AssignmentMissing => { write!(f, "an assignment for a variable could not be computed") - }, + } SynthesisError::DivisionByZero => write!(f, "division by zero"), SynthesisError::Unsatisfiable => write!(f, "unsatisfiable constraint system"), SynthesisError::PolynomialDegreeTooLarge => write!(f, "polynomial degree is too large"), SynthesisError::UnexpectedIdentity => { write!(f, "encountered an identity element in the CRS") - }, + } SynthesisError::MalformedVerifyingKey => write!(f, "malformed verifying key"), SynthesisError::UnconstrainedVariable => { write!(f, "auxiliary variable was unconstrained") - }, + } } } } diff --git a/relations/src/r1cs/impl_lc.rs b/relations/src/r1cs/impl_lc.rs index c56abce5e..1af389643 100644 --- a/relations/src/r1cs/impl_lc.rs +++ b/relations/src/r1cs/impl_lc.rs @@ -228,16 +228,16 @@ where Ordering::Greater => { new_vec.push((push_fn(other[j].0), other[j].1)); j += 1; - }, + } Ordering::Less => { new_vec.push(*self_cur); i += 1; - }, + } Ordering::Equal => { new_vec.push((combine_fn(self_cur.0, other_cur.0), self_cur.1)); i += 1; j += 1; - }, + } }; } new_vec.extend_from_slice(&cur[i..]); diff --git a/relations/src/r1cs/trace.rs b/relations/src/r1cs/trace.rs index 341d168d6..fe9570589 100644 --- a/relations/src/r1cs/trace.rs +++ b/relations/src/r1cs/trace.rs @@ -68,7 +68,7 @@ where id if id == TypeId::of::() => Some(self as *const _ as *const ()), id if id == TypeId::of::() => { Some(&self.get_context as *const _ as *const ()) - }, + } _ => None, } } From 974ef4fdd5ecc317bae13addd991e0551aea6bc3 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 31 Dec 2020 11:20:10 -0800 Subject: [PATCH 05/10] constraints as default optimization goal --- relations/src/r1cs/constraint_system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index 5ae957808..1e59335c9 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -148,7 +148,7 @@ impl ConstraintSystem { construct_matrices: true, }, - optimization_goal: OptimizationGoal::None, + optimization_goal: OptimizationGoal::Constraints, } } From 32e5206034d4cc381d0931512dfe42d411951163 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Sat, 2 Jan 2021 20:41:57 -0800 Subject: [PATCH 06/10] remove reduce_constraint_weight --- relations/src/r1cs/constraint_system.rs | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index 1e59335c9..b186a813c 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -504,18 +504,6 @@ impl ConstraintSystem { } } - /// Reduce the constraint weight. - /// - /// At this moment, it is a wrapper to `outline_lcs`. - /// More weight reductions may be added later. - /// - /// Useful for SNARKs like [\[Marlin\]](https://eprint.iacr.org/2019/1047) or - /// [\[Fractal\]](https://eprint.iacr.org/2019/1076), where addition gates - /// are not cheap. - fn reduce_constraint_weight(&mut self) { - self.outline_lcs(); - } - /// Finalize the constraint system (either by outlining or inlining, /// if an optimization goal is set). pub fn finalize(&mut self) { @@ -922,17 +910,6 @@ impl ConstraintSystemRef { } } - /// Reduce the constraint weight. - /// - /// Useful for SNARKs like [\[Marlin\]](https://eprint.iacr.org/2019/1047) or - /// [\[Fractal\]](https://eprint.iacr.org/2019/1076), where addition gates - /// are not cheap. - pub fn reduce_constraint_weight(&self) { - if let Some(cs) = self.inner() { - cs.borrow_mut().reduce_constraint_weight() - } - } - /// Finalize the constraint system (either by outlining or inlining, /// if an optimization goal is set). pub fn finalize(&self) { From a31f000bcea2fb2e5ca05c28717c8fa2c106c0a2 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Sun, 3 Jan 2021 12:58:45 -0800 Subject: [PATCH 07/10] None still inlines --- relations/src/r1cs/constraint_system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index b186a813c..6d7d3a0c4 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -508,7 +508,7 @@ impl ConstraintSystem { /// if an optimization goal is set). pub fn finalize(&mut self) { match self.optimization_goal { - OptimizationGoal::None => (), + OptimizationGoal::None => self.inline_all_lcs(), OptimizationGoal::Constraints => self.inline_all_lcs(), OptimizationGoal::Weight => self.outline_lcs(), }; From 7f9ef99900a5f3fdcef3be65dc4ac84ce2aa82d2 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sun, 3 Jan 2021 21:36:22 -0800 Subject: [PATCH 08/10] export OptimizationGoal; add assertion checks --- relations/src/r1cs/constraint_system.rs | 6 ++++++ relations/src/r1cs/mod.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/relations/src/r1cs/constraint_system.rs b/relations/src/r1cs/constraint_system.rs index 6d7d3a0c4..93b37bfd3 100644 --- a/relations/src/r1cs/constraint_system.rs +++ b/relations/src/r1cs/constraint_system.rs @@ -176,6 +176,12 @@ impl ConstraintSystem { /// Specify whether this constraint system should aim to optimize weight, /// number of constraints, or neither. pub fn set_optimization_goal(&mut self, goal: OptimizationGoal) { + // `set_optimization_goal` should only be executed before any constraint or value is created. + assert_eq!(self.num_instance_variables, 1); + assert_eq!(self.num_witness_variables, 0); + assert_eq!(self.num_constraints, 0); + assert_eq!(self.num_linear_combinations, 0); + self.optimization_goal = goal; } diff --git a/relations/src/r1cs/mod.rs b/relations/src/r1cs/mod.rs index 3e1393fd5..69adfa3f5 100644 --- a/relations/src/r1cs/mod.rs +++ b/relations/src/r1cs/mod.rs @@ -20,7 +20,7 @@ pub use tracing::info_span; pub use ark_ff::{Field, ToConstraintField}; pub use constraint_system::{ ConstraintMatrices, ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, Namespace, - SynthesisMode, + OptimizationGoal, SynthesisMode, }; pub use error::SynthesisError; From b58393a9dda412f1be3da882dcacdddbee0b2f73 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sun, 3 Jan 2021 22:07:40 -0800 Subject: [PATCH 09/10] retouch the comments --- snark/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/snark/src/lib.rs b/snark/src/lib.rs index 065f22111..e973339e1 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -51,8 +51,8 @@ pub trait SNARK { ) -> Result; /// Checks that `proof` is a valid proof of the satisfaction of circuit - /// encoded in `circuit_vk`, with respect to the public input - /// `public_input`. as R1CS constraints). + /// encoded in `circuit_vk`, with respect to the public input `public_input`, + /// specified as R1CS constraints. fn verify( circuit_vk: &Self::VerifyingKey, public_input: &[F], @@ -68,8 +68,8 @@ pub trait SNARK { ) -> Result; /// Checks that `proof` is a valid proof of the satisfaction of circuit - /// encoded in `circuit_pvk`, with respect to the public input - /// `public_input`. as R1CS constraints). + /// encoded in `circuit_pvk`, with respect to the public input `public_input`, + /// specified as R1CS constraints. fn verify_with_processed_vk( circuit_pvk: &Self::ProcessedVerifyingKey, public_input: &[F], From 9de6b0c7d68a2413dc382be5d4e636a7ba8842ff Mon Sep 17 00:00:00 2001 From: weikeng Date: Sun, 3 Jan 2021 22:12:18 -0800 Subject: [PATCH 10/10] update the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0878bf09a..bce0b6613 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Pending ### Breaking changes +- #334 Outlining linear combinations is now specified via the optimization goal interface. ### Features