diff --git a/CHANGELOG.md b/CHANGELOG.md index d562acf0..ebd97dee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ and this project adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- `halo2::plonk::Error` has been overhauled: + - `Error` now implements `std::fmt::Display` and `std::error::Error`. + - `Error` no longer implements `PartialEq`. Tests can check for specific error + cases with `assert!(matches!(..))`. + - `Error::IncompatibleParams` is now `Error::InvalidInstances`. + - `Error::OpeningError` is now `Error::Opening`. + - `Error::SynthesisError` is now `Error::Synthesis`. + - `Error::TranscriptError` is now `Error::Transcript`, and stores the + underlying `io::Error`. + ### Removed - `halo2::arithmetic::BatchInvert` (use `ff::BatchInvert` instead). diff --git a/benches/plonk.rs b/benches/plonk.rs index 3106b72c..15528d48 100644 --- a/benches/plonk.rs +++ b/benches/plonk.rs @@ -90,20 +90,20 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::zero()))?; @@ -132,20 +132,20 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::one()))?; @@ -226,17 +226,17 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { let (a0, _, c0) = cs.raw_multiply(&mut layouter, || { a_squared = self.a.map(|a| a.square()); Ok(( - self.a.ok_or(Error::SynthesisError)?, - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, )) })?; let (a1, b1, _) = cs.raw_add(&mut layouter, || { let fin = a_squared.and_then(|a2| self.a.map(|a| a + a2)); Ok(( - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, - fin.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, + fin.ok_or(Error::Synthesis)?, )) })?; cs.copy(&mut layouter, a0, a1)?; diff --git a/book/src/user/dev-tools.md b/book/src/user/dev-tools.md index 63eb6f06..dcb5a7ac 100644 --- a/book/src/user/dev-tools.md +++ b/book/src/user/dev-tools.md @@ -16,6 +16,11 @@ granular error messages that indicate which specific constraint (if any) is not The `dev-graph` feature flag exposes several helper methods for creating graphical representations of circuits. +On Debian systems, you will need the following additional packages: +```plaintext +sudo apt install cmake libexpat1-dev libfreetype6-dev +``` + ### Circuit layout `halo2::dev::CircuitLayout` renders the circuit layout as a grid: diff --git a/examples/circuit-layout.rs b/examples/circuit-layout.rs index 49035595..eed2816a 100644 --- a/examples/circuit-layout.rs +++ b/examples/circuit-layout.rs @@ -72,32 +72,32 @@ impl StandardCs for StandardPlonk { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; region.assign_advice( || "lhs^4", self.config.d, 0, - || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.0.square().square()), )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; region.assign_advice( || "rhs^4", self.config.e, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.1.square().square()), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::zero()))?; @@ -117,32 +117,32 @@ impl StandardCs for StandardPlonk { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; region.assign_advice( || "lhs^4", self.config.d, 0, - || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.0.square().square()), )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; region.assign_advice( || "rhs^4", self.config.e, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.1.square().square()), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::one()))?; @@ -259,17 +259,17 @@ impl Circuit for MyCircuit { let (a0, _, c0) = cs.raw_multiply(&mut region, || { a_squared = self.a.map(|a| a.square()); Ok(( - self.a.ok_or(Error::SynthesisError)?, - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, )) })?; let (a1, b1, _) = cs.raw_add(&mut region, || { let fin = a_squared.and_then(|a2| self.a.map(|a| a + a2)); Ok(( - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, - fin.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, + fin.ok_or(Error::Synthesis)?, )) })?; cs.copy(&mut region, a0, a1)?; diff --git a/examples/simple-example.rs b/examples/simple-example.rs index f3236b5f..56a6fd7e 100644 --- a/examples/simple-example.rs +++ b/examples/simple-example.rs @@ -172,7 +172,7 @@ impl NumericInstructions for FieldChip { || "private input", config.advice[0], 0, - || value.ok_or(Error::SynthesisError), + || value.ok_or(Error::Synthesis), )?; num = Some(Number { cell, value }); Ok(()) @@ -233,13 +233,13 @@ impl NumericInstructions for FieldChip { || "lhs", config.advice[0], 0, - || a.value.ok_or(Error::SynthesisError), + || a.value.ok_or(Error::Synthesis), )?; let rhs = region.assign_advice( || "rhs", config.advice[1], 0, - || b.value.ok_or(Error::SynthesisError), + || b.value.ok_or(Error::Synthesis), )?; region.constrain_equal(a.cell, lhs)?; region.constrain_equal(b.cell, rhs)?; @@ -250,7 +250,7 @@ impl NumericInstructions for FieldChip { || "lhs * rhs", config.advice[0], 1, - || value.ok_or(Error::SynthesisError), + || value.ok_or(Error::Synthesis), )?; // Finally, we return a variable representing the output, diff --git a/examples/two-chip.rs b/examples/two-chip.rs index a2adcea9..2f22cc0a 100644 --- a/examples/two-chip.rs +++ b/examples/two-chip.rs @@ -222,13 +222,13 @@ impl AddInstructions for AddChip { || "lhs", config.advice[0], 0, - || a.value.ok_or(Error::SynthesisError), + || a.value.ok_or(Error::Synthesis), )?; let rhs = region.assign_advice( || "rhs", config.advice[1], 0, - || b.value.ok_or(Error::SynthesisError), + || b.value.ok_or(Error::Synthesis), )?; region.constrain_equal(a.cell, lhs)?; region.constrain_equal(b.cell, rhs)?; @@ -239,7 +239,7 @@ impl AddInstructions for AddChip { || "lhs * rhs", config.advice[0], 1, - || value.ok_or(Error::SynthesisError), + || value.ok_or(Error::Synthesis), )?; // Finally, we return a variable representing the output, @@ -362,13 +362,13 @@ impl MulInstructions for MulChip { || "lhs", config.advice[0], 0, - || a.value.ok_or(Error::SynthesisError), + || a.value.ok_or(Error::Synthesis), )?; let rhs = region.assign_advice( || "rhs", config.advice[1], 0, - || b.value.ok_or(Error::SynthesisError), + || b.value.ok_or(Error::Synthesis), )?; region.constrain_equal(a.cell, lhs)?; region.constrain_equal(b.cell, rhs)?; @@ -379,7 +379,7 @@ impl MulInstructions for MulChip { || "lhs * rhs", config.advice[0], 1, - || value.ok_or(Error::SynthesisError), + || value.ok_or(Error::Synthesis), )?; // Finally, we return a variable representing the output, @@ -457,7 +457,7 @@ impl FieldInstructions for FieldChip { || "private input", config.advice[0], 0, - || value.ok_or(Error::SynthesisError), + || value.ok_or(Error::Synthesis), )?; num = Some(Number { cell, value }); Ok(()) diff --git a/src/circuit/floor_planner/single_pass.rs b/src/circuit/floor_planner/single_pass.rs index 8e6b102a..68e35c00 100644 --- a/src/circuit/floor_planner/single_pass.rs +++ b/src/circuit/floor_planner/single_pass.rs @@ -180,7 +180,7 @@ impl<'a, F: Field, CS: Assignment + 'a> Layouter for SingleChipLayouter<'a _ => None, }) { Some(Some(len)) => len, - _ => return Err(Error::SynthesisError), // TODO better error + _ => return Err(Error::Synthesis), // TODO better error } }; @@ -320,7 +320,7 @@ impl<'r, 'a, F: Field, CS: Assignment + 'a> RegionLayouter let value = self.layouter.cs.query_instance(instance, row)?; let cell = self.assign_advice(annotation, advice, offset, &mut || { - value.ok_or(Error::SynthesisError).map(|v| v.into()) + value.ok_or(Error::Synthesis).map(|v| v.into()) })?; self.layouter.cs.copy( @@ -417,7 +417,7 @@ impl<'r, 'a, F: Field, CS: Assignment + 'a> TableLayouter to: &'v mut (dyn FnMut() -> Result, Error> + 'v), ) -> Result<(), Error> { if self.used_columns.contains(&column) { - return Err(Error::SynthesisError); // TODO better error + return Err(Error::Synthesis); // TODO better error } let entry = self.default_and_assigned.entry(column).or_default(); @@ -439,7 +439,7 @@ impl<'r, 'a, F: Field, CS: Assignment + 'a> TableLayouter (true, 0) => entry.0 = Some(value), // Since there is already an existing default value for this table column, // the caller should not be attempting to assign another value at offset 0. - (false, 0) => return Err(Error::SynthesisError), // TODO better error + (false, 0) => return Err(Error::Synthesis), // TODO better error _ => (), } if entry.1.len() <= offset { @@ -499,9 +499,9 @@ mod tests { } let circuit = MyCircuit {}; - assert_eq!( + assert!(matches!( MockProver::run(3, &circuit, vec![]).unwrap_err(), Error::NotEnoughColumnsForConstants, - ); + )); } } diff --git a/src/circuit/floor_planner/v1.rs b/src/circuit/floor_planner/v1.rs index 8d505c33..2b7f8ae7 100644 --- a/src/circuit/floor_planner/v1.rs +++ b/src/circuit/floor_planner/v1.rs @@ -321,7 +321,7 @@ impl<'p, 'a, F: Field, CS: Assignment + 'a> AssignmentPass<'p, 'a, F, CS> { _ => None, }) { Some(Some(len)) => len, - _ => return Err(Error::SynthesisError), // TODO better error + _ => return Err(Error::Synthesis), // TODO better error } }; @@ -436,7 +436,7 @@ impl<'r, 'a, F: Field, CS: Assignment + 'a> RegionLayouter for V1Region<'r let value = self.plan.cs.query_instance(instance, row)?; let cell = self.assign_advice(annotation, advice, offset, &mut || { - value.ok_or(Error::SynthesisError).map(|v| v.into()) + value.ok_or(Error::Synthesis).map(|v| v.into()) })?; self.plan.cs.copy( @@ -534,9 +534,9 @@ mod tests { } let circuit = MyCircuit {}; - assert_eq!( + assert!(matches!( MockProver::run(3, &circuit, vec![]).unwrap_err(), Error::NotEnoughColumnsForConstants, - ); + )); } } diff --git a/src/dev.rs b/src/dev.rs index 29f9837e..7fda24c1 100644 --- a/src/dev.rs +++ b/src/dev.rs @@ -292,15 +292,15 @@ impl Mul for Value { /// layouter.assign_region(|| "Example region", |mut region| { /// config.s.enable(&mut region, 0)?; /// region.assign_advice(|| "a", config.a, 0, || { -/// self.a.map(|v| F::from(v)).ok_or(Error::SynthesisError) +/// self.a.map(|v| F::from(v)).ok_or(Error::Synthesis) /// })?; /// region.assign_advice(|| "b", config.b, 0, || { -/// self.b.map(|v| F::from(v)).ok_or(Error::SynthesisError) +/// self.b.map(|v| F::from(v)).ok_or(Error::Synthesis) /// })?; /// region.assign_advice(|| "c", config.c, 0, || { /// self.a /// .and_then(|a| self.b.map(|b| F::from(a * b))) -/// .ok_or(Error::SynthesisError) +/// .ok_or(Error::Synthesis) /// })?; /// Ok(()) /// }) @@ -528,7 +528,7 @@ impl MockProver { } if instance.len() != cs.num_instance_columns { - return Err(Error::IncompatibleParams); + return Err(Error::InvalidInstances); } let instance = instance diff --git a/src/plonk.rs b/src/plonk.rs index 0bb80090..a31e6c6d 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -16,6 +16,7 @@ use crate::poly::{ use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript}; mod circuit; +mod error; mod keygen; mod lookup; pub(crate) mod permutation; @@ -25,6 +26,7 @@ mod prover; mod verifier; pub use circuit::*; +pub use error::*; pub use keygen::*; pub use prover::*; pub use verifier::*; @@ -133,33 +135,6 @@ pub struct ProvingKey { permutation: permutation::ProvingKey, } -/// This is an error that could occur during proving or circuit synthesis. -// TODO: these errors need to be cleaned up -#[derive(Debug, PartialEq)] -pub enum Error { - /// This is an error that can occur during synthesis of the circuit, for - /// example, when the witness is not present. - SynthesisError, - /// The structured reference string or the parameters are not compatible - /// with the circuit being synthesized. - IncompatibleParams, - /// The constraint system is not satisfied. - ConstraintSystemFailure, - /// Out of bounds index passed to a backend - BoundsFailure, - /// Opening error - OpeningError, - /// Transcript error - TranscriptError, - /// Instance provided has more rows than supported by circuit - NotEnoughRowsAvailable, - /// Instance provided exceeds number of available rows - InstanceTooLarge, - /// Circuit synthesis requires global constants, but circuit configuration did not - /// call [`ConstraintSystem::enable_constant`] on fixed columns with sufficient space. - NotEnoughColumnsForConstants, -} - impl ProvingKey { /// Get the underlying [`VerifyingKey`]. pub fn get_vk(&self) -> &VerifyingKey { diff --git a/src/plonk/error.rs b/src/plonk/error.rs new file mode 100644 index 00000000..308bbba3 --- /dev/null +++ b/src/plonk/error.rs @@ -0,0 +1,68 @@ +use std::error; +use std::fmt; +use std::io; + +/// This is an error that could occur during proving or circuit synthesis. +// TODO: these errors need to be cleaned up +#[derive(Debug)] +pub enum Error { + /// This is an error that can occur during synthesis of the circuit, for + /// example, when the witness is not present. + Synthesis, + /// The provided instances do not match the circuit parameters. + InvalidInstances, + /// The constraint system is not satisfied. + ConstraintSystemFailure, + /// Out of bounds index passed to a backend + BoundsFailure, + /// Opening error + Opening, + /// Transcript error + Transcript(io::Error), + /// Instance provided has more rows than supported by circuit + NotEnoughRowsAvailable, + /// Instance provided exceeds number of available rows + InstanceTooLarge, + /// Circuit synthesis requires global constants, but circuit configuration did not + /// call [`ConstraintSystem::enable_constant`] on fixed columns with sufficient space. + /// + /// [`ConstraintSystem::enable_constant`]: crate::plonk::ConstraintSystem::enable_constant + NotEnoughColumnsForConstants, +} + +impl From for Error { + fn from(error: io::Error) -> Self { + // The only place we can get io::Error from is the transcript. + Error::Transcript(error) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::Synthesis => write!(f, "General synthesis error"), + Error::InvalidInstances => write!(f, "Provided instances do not match the circuit"), + Error::ConstraintSystemFailure => write!(f, "The constraint system is not satisfied"), + Error::BoundsFailure => write!(f, "An out-of-bounds index was passed to the backend"), + Error::Opening => write!(f, "Multi-opening proof was invalid"), + Error::Transcript(e) => write!(f, "Transcript error: {}", e), + Error::NotEnoughRowsAvailable => write!(f, "`k` is too small for the given circuit"), + Error::InstanceTooLarge => write!(f, "Instance vectors are larger than the circuit"), + Error::NotEnoughColumnsForConstants => { + write!( + f, + "Too few fixed columns are enabled for global constants usage" + ) + } + } + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Error::Transcript(e) => Some(e), + _ => None, + } + } +} diff --git a/src/plonk/keygen.rs b/src/plonk/keygen.rs index e52f2a03..fd280690 100644 --- a/src/plonk/keygen.rs +++ b/src/plonk/keygen.rs @@ -160,7 +160,7 @@ impl Assignment for Assembly { .ok_or(Error::BoundsFailure)?; for row in self.usable_rows.clone().skip(from_row) { - col[row] = to.ok_or(Error::SynthesisError)?; + col[row] = to.ok_or(Error::Synthesis)?; } Ok(()) diff --git a/src/plonk/lookup/prover.rs b/src/plonk/lookup/prover.rs index f90f36dd..33aa36d7 100644 --- a/src/plonk/lookup/prover.rs +++ b/src/plonk/lookup/prover.rs @@ -210,14 +210,10 @@ impl Argument { commit_values(&permuted_table_expression); // Hash permuted input commitment - transcript - .write_point(permuted_input_commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(permuted_input_commitment)?; // Hash permuted table commitment - transcript - .write_point(permuted_table_commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(permuted_table_commitment)?; let permuted_input_coset = pk.vk.domain.coeff_to_extended(permuted_input_poly.clone()); let permuted_table_coset = pk.vk.domain.coeff_to_extended(permuted_table_poly.clone()); @@ -391,9 +387,7 @@ impl Permuted { let product_coset = pk.vk.domain.coeff_to_extended(z.clone()); // Hash product commitment - transcript - .write_point(product_commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(product_commitment)?; Ok(Committed:: { permuted: self, @@ -541,9 +535,7 @@ impl Constructed { .chain(Some(permuted_input_inv_eval)) .chain(Some(permuted_table_eval)) { - transcript - .write_scalar(eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(eval)?; } Ok(Evaluated { constructed: self }) diff --git a/src/plonk/lookup/verifier.rs b/src/plonk/lookup/verifier.rs index 127142c2..1a04ec2f 100644 --- a/src/plonk/lookup/verifier.rs +++ b/src/plonk/lookup/verifier.rs @@ -40,12 +40,8 @@ impl Argument { &self, transcript: &mut T, ) -> Result, Error> { - let permuted_input_commitment = transcript - .read_point() - .map_err(|_| Error::TranscriptError)?; - let permuted_table_commitment = transcript - .read_point() - .map_err(|_| Error::TranscriptError)?; + let permuted_input_commitment = transcript.read_point()?; + let permuted_table_commitment = transcript.read_point()?; Ok(PermutationCommitments { permuted_input_commitment, @@ -62,9 +58,7 @@ impl PermutationCommitments { self, transcript: &mut T, ) -> Result, Error> { - let product_commitment = transcript - .read_point() - .map_err(|_| Error::TranscriptError)?; + let product_commitment = transcript.read_point()?; Ok(Committed { permuted: self, @@ -78,21 +72,11 @@ impl Committed { self, transcript: &mut T, ) -> Result, Error> { - let product_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; - let product_next_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; - let permuted_input_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; - let permuted_input_inv_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; - let permuted_table_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; + let product_eval = transcript.read_scalar()?; + let product_next_eval = transcript.read_scalar()?; + let permuted_input_eval = transcript.read_scalar()?; + let permuted_input_inv_eval = transcript.read_scalar()?; + let permuted_table_eval = transcript.read_scalar()?; Ok(Evaluated { committed: self, diff --git a/src/plonk/permutation/keygen.rs b/src/plonk/permutation/keygen.rs index 1aa9c908..b0f9cba5 100644 --- a/src/plonk/permutation/keygen.rs +++ b/src/plonk/permutation/keygen.rs @@ -51,12 +51,12 @@ impl Assembly { .columns .iter() .position(|c| c == &left_column) - .ok_or(Error::SynthesisError)?; + .ok_or(Error::Synthesis)?; let right_column = self .columns .iter() .position(|c| c == &right_column) - .ok_or(Error::SynthesisError)?; + .ok_or(Error::Synthesis)?; // Check bounds if left_row >= self.mapping[left_column].len() diff --git a/src/plonk/permutation/prover.rs b/src/plonk/permutation/prover.rs index 8412f879..58c8c69c 100644 --- a/src/plonk/permutation/prover.rs +++ b/src/plonk/permutation/prover.rs @@ -173,9 +173,7 @@ impl Argument { permutation_product_commitment_projective.to_affine(); // Hash the permutation product commitment - transcript - .write_point(permutation_product_commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(permutation_product_commitment)?; sets.push(CommittedSet { permutation_product_poly, @@ -330,9 +328,7 @@ impl super::ProvingKey { ) -> Result<(), Error> { // Hash permutation evals for eval in self.polys.iter().map(|poly| eval_polynomial(poly, *x)) { - transcript - .write_scalar(eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(eval)?; } Ok(()) @@ -365,9 +361,7 @@ impl Constructed { .chain(Some(&permutation_product_eval)) .chain(Some(&permutation_product_next_eval)) { - transcript - .write_scalar(*eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(*eval)?; } // If we have any remaining sets to process, evaluate this set at omega^u @@ -379,9 +373,7 @@ impl Constructed { domain.rotate_omega(*x, Rotation(-((blinding_factors + 1) as i32))), ); - transcript - .write_scalar(permutation_product_last_eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(permutation_product_last_eval)?; } } } diff --git a/src/plonk/permutation/verifier.rs b/src/plonk/permutation/verifier.rs index 1acb8a75..1a3b6507 100644 --- a/src/plonk/permutation/verifier.rs +++ b/src/plonk/permutation/verifier.rs @@ -44,7 +44,7 @@ impl Argument { let permutation_product_commitments = self .columns .chunks(chunk_len) - .map(|_| transcript.read_point().map_err(|_| Error::TranscriptError)) + .map(|_| transcript.read_point()) .collect::, _>>()?; Ok(Committed { @@ -61,7 +61,7 @@ impl VerifyingKey { let permutation_evals = self .commitments .iter() - .map(|_| transcript.read_scalar().map_err(|_| Error::TranscriptError)) + .map(|_| transcript.read_scalar()) .collect::, _>>()?; Ok(CommonEvaluated { permutation_evals }) @@ -78,18 +78,10 @@ impl Committed { let mut iter = self.permutation_product_commitments.into_iter(); while let Some(permutation_product_commitment) = iter.next() { - let permutation_product_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; - let permutation_product_next_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; + let permutation_product_eval = transcript.read_scalar()?; + let permutation_product_next_eval = transcript.read_scalar()?; let permutation_product_last_eval = if iter.len() > 0 { - Some( - transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?, - ) + Some(transcript.read_scalar()?) } else { None }; diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 79db66c1..06200c75 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -43,14 +43,12 @@ pub fn create_proof< ) -> Result<(), Error> { for instance in instances.iter() { if instance.len() != pk.vk.cs.num_instance_columns { - return Err(Error::IncompatibleParams); + return Err(Error::InvalidInstances); } } // Hash verification key into transcript - pk.vk - .hash_into(transcript) - .map_err(|_| Error::TranscriptError)?; + pk.vk.hash_into(transcript)?; let domain = &pk.vk.domain; let mut meta = ConstraintSystem::default(); @@ -94,9 +92,7 @@ pub fn create_proof< drop(instance_commitments_projective); for commitment in &instance_commitments { - transcript - .common_point(*commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.common_point(*commitment)?; } let instance_polys: Vec<_> = instance_values @@ -303,9 +299,7 @@ pub fn create_proof< drop(advice_commitments_projective); for commitment in &advice_commitments { - transcript - .write_point(*commitment) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(*commitment)?; } let advice_polys: Vec<_> = advice @@ -498,9 +492,7 @@ pub fn create_proof< // Hash each instance column evaluation for eval in instance_evals.iter() { - transcript - .write_scalar(*eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(*eval)?; } } @@ -520,9 +512,7 @@ pub fn create_proof< // Hash each advice column evaluation for eval in advice_evals.iter() { - transcript - .write_scalar(*eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(*eval)?; } } @@ -537,9 +527,7 @@ pub fn create_proof< // Hash each fixed column evaluation for eval in fixed_evals.iter() { - transcript - .write_scalar(*eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(*eval)?; } let vanishing = vanishing.evaluate(x, xn, domain, transcript)?; @@ -611,5 +599,5 @@ pub fn create_proof< // We query the h(X) polynomial at x .chain(vanishing.open(x)); - multiopen::create_proof(params, transcript, instances).map_err(|_| Error::OpeningError) + multiopen::create_proof(params, transcript, instances).map_err(|_| Error::Opening) } diff --git a/src/plonk/vanishing/prover.rs b/src/plonk/vanishing/prover.rs index a0cd0a14..02dff0a6 100644 --- a/src/plonk/vanishing/prover.rs +++ b/src/plonk/vanishing/prover.rs @@ -48,9 +48,7 @@ impl Argument { // Commit let c = params.commit(&random_poly, random_blind).to_affine(); - transcript - .write_point(c) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(c)?; Ok(Committed { random_poly, @@ -97,9 +95,7 @@ impl Committed { // Hash each h(X) piece for c in h_commitments.iter() { - transcript - .write_point(*c) - .map_err(|_| Error::TranscriptError)?; + transcript.write_point(*c)?; } Ok(Constructed { @@ -133,9 +129,7 @@ impl Constructed { }); let random_eval = eval_polynomial(&self.committed.random_poly, *x); - transcript - .write_scalar(random_eval) - .map_err(|_| Error::TranscriptError)?; + transcript.write_scalar(random_eval)?; Ok(Evaluated { h_poly, diff --git a/src/plonk/vanishing/verifier.rs b/src/plonk/vanishing/verifier.rs index 996da071..c2e3700d 100644 --- a/src/plonk/vanishing/verifier.rs +++ b/src/plonk/vanishing/verifier.rs @@ -44,9 +44,7 @@ impl Argument { >( transcript: &mut T, ) -> Result, Error> { - let random_poly_commitment = transcript - .read_point() - .map_err(|_| Error::TranscriptError)?; + let random_poly_commitment = transcript.read_point()?; Ok(Committed { random_poly_commitment, @@ -64,8 +62,7 @@ impl Committed { transcript: &mut T, ) -> Result, Error> { // Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1 - let h_commitments = read_n_points(transcript, vk.domain.get_quotient_poly_degree()) - .map_err(|_| Error::TranscriptError)?; + let h_commitments = read_n_points(transcript, vk.domain.get_quotient_poly_degree())?; Ok(Constructed { h_commitments, @@ -79,9 +76,7 @@ impl Constructed { self, transcript: &mut T, ) -> Result, Error> { - let random_eval = transcript - .read_scalar() - .map_err(|_| Error::TranscriptError)?; + let random_eval = transcript.read_scalar()?; Ok(PartiallyEvaluated { h_commitments: self.h_commitments, diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index c77e165b..639f7027 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -24,7 +24,7 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge, T: Transcri // Check that instances matches the expected number of instance columns for instances in instances.iter() { if instances.len() != vk.cs.num_instance_columns { - return Err(Error::IncompatibleParams); + return Err(Error::InvalidInstances); } } @@ -50,22 +50,19 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge, T: Transcri let num_proofs = instance_commitments.len(); // Hash verification key into transcript - vk.hash_into(transcript) - .map_err(|_| Error::TranscriptError)?; + vk.hash_into(transcript)?; for instance_commitments in instance_commitments.iter() { // Hash the instance (external) commitments into the transcript for commitment in instance_commitments { - transcript - .common_point(*commitment) - .map_err(|_| Error::TranscriptError)? + transcript.common_point(*commitment)? } } let advice_commitments = (0..num_proofs) .map(|_| -> Result, _> { // Hash the prover's advice commitments into the transcript - read_n_points(transcript, vk.cs.num_advice_columns).map_err(|_| Error::TranscriptError) + read_n_points(transcript, vk.cs.num_advice_columns) }) .collect::, _>>()?; @@ -118,21 +115,14 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge, T: Transcri // satisfied with high probability. let x: ChallengeX<_> = transcript.squeeze_challenge_scalar(); let instance_evals = (0..num_proofs) - .map(|_| -> Result, _> { - read_n_scalars(transcript, vk.cs.instance_queries.len()) - .map_err(|_| Error::TranscriptError) - }) + .map(|_| -> Result, _> { read_n_scalars(transcript, vk.cs.instance_queries.len()) }) .collect::, _>>()?; let advice_evals = (0..num_proofs) - .map(|_| -> Result, _> { - read_n_scalars(transcript, vk.cs.advice_queries.len()) - .map_err(|_| Error::TranscriptError) - }) + .map(|_| -> Result, _> { read_n_scalars(transcript, vk.cs.advice_queries.len()) }) .collect::, _>>()?; - let fixed_evals = read_n_scalars(transcript, vk.cs.fixed_queries.len()) - .map_err(|_| Error::TranscriptError)?; + let fixed_evals = read_n_scalars(transcript, vk.cs.fixed_queries.len())?; let vanishing = vanishing.evaluate_after_x(transcript)?; @@ -295,5 +285,5 @@ pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge, T: Transcri // We are now convinced the circuit is satisfied so long as the // polynomial commitments open to the correct values. - multiopen::verify_proof(params, transcript, queries, msm).map_err(|_| Error::OpeningError) + multiopen::verify_proof(params, transcript, queries, msm).map_err(|_| Error::Opening) } diff --git a/tests/plonk_api.rs b/tests/plonk_api.rs index 5c0ddd1a..457da4fb 100644 --- a/tests/plonk_api.rs +++ b/tests/plonk_api.rs @@ -105,32 +105,32 @@ fn plonk_api() { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; region.assign_advice( || "lhs^4", self.config.d, 0, - || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.0.square().square()), )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; region.assign_advice( || "rhs^4", self.config.e, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.1.square().square()), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::zero()))?; @@ -159,32 +159,32 @@ fn plonk_api() { 0, || { value = Some(f()?); - Ok(value.ok_or(Error::SynthesisError)?.0) + Ok(value.ok_or(Error::Synthesis)?.0) }, )?; region.assign_advice( || "lhs^4", self.config.d, 0, - || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.0.square().square()), )?; let rhs = region.assign_advice( || "rhs", self.config.b, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1), + || Ok(value.ok_or(Error::Synthesis)?.1), )?; region.assign_advice( || "rhs^4", self.config.e, 0, - || Ok(value.ok_or(Error::SynthesisError)?.1.square().square()), + || Ok(value.ok_or(Error::Synthesis)?.1.square().square()), )?; let out = region.assign_advice( || "out", self.config.c, 0, - || Ok(value.ok_or(Error::SynthesisError)?.2), + || Ok(value.ok_or(Error::Synthesis)?.2), )?; region.assign_fixed(|| "a", self.config.sa, 0, || Ok(FF::one()))?; @@ -356,17 +356,17 @@ fn plonk_api() { let (a0, _, c0) = cs.raw_multiply(&mut layouter, || { a_squared = self.a.map(|a| a.square()); Ok(( - self.a.ok_or(Error::SynthesisError)?, - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, )) })?; let (a1, b1, _) = cs.raw_add(&mut layouter, || { let fin = a_squared.and_then(|a2| self.a.map(|a| a + a2)); Ok(( - self.a.ok_or(Error::SynthesisError)?, - a_squared.ok_or(Error::SynthesisError)?, - fin.ok_or(Error::SynthesisError)?, + self.a.ok_or(Error::Synthesis)?, + a_squared.ok_or(Error::Synthesis)?, + fin.ok_or(Error::Synthesis)?, )) })?; cs.copy(&mut layouter, a0, a1)?;