mirror of https://github.com/zcash/halo2.git
Replace `Error::BoundsFailure` uses with `Error::NotEnoughRowsAvailable`
The remaining uses of `Error::BoundsFailure` that are exposed to the user, are for invalid column indices.
This commit is contained in:
parent
d055acda31
commit
eb88a2ebef
28
src/dev.rs
28
src/dev.rs
|
@ -324,9 +324,19 @@ impl<F: Group + Field> Mul<F> for Value<F> {
|
|||
/// row: 0
|
||||
/// }])
|
||||
/// );
|
||||
///
|
||||
/// // If we provide a too-small K, we get an error.
|
||||
/// assert!(matches!(
|
||||
/// MockProver::<Fp>::run(2, &circuit, vec![]).unwrap_err(),
|
||||
/// Error::NotEnoughRowsAvailable {
|
||||
/// current_k,
|
||||
/// minimum_k,
|
||||
/// } if current_k == 2 && minimum_k == 3,
|
||||
/// ));
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct MockProver<F: Group + Field> {
|
||||
k: u32,
|
||||
n: u32,
|
||||
cs: ConstraintSystem<F>,
|
||||
|
||||
|
@ -376,7 +386,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
// Track that this selector was enabled. We require that all selectors are enabled
|
||||
|
@ -396,7 +406,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
|
||||
fn query_instance(&self, column: Column<Instance>, row: usize) -> Result<Option<F>, Error> {
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
self.instance
|
||||
|
@ -420,7 +430,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
if let Some(region) = self.current_region.as_mut() {
|
||||
|
@ -451,7 +461,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
if let Some(region) = self.current_region.as_mut() {
|
||||
|
@ -475,8 +485,11 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
right_column: Column<Any>,
|
||||
right_row: usize,
|
||||
) -> Result<(), crate::plonk::Error> {
|
||||
if !self.usable_rows.contains(&left_row) || !self.usable_rows.contains(&right_row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
if !self.usable_rows.contains(&left_row) {
|
||||
return Err(Error::not_enough_rows_available(self.k, left_row + 1));
|
||||
}
|
||||
if !self.usable_rows.contains(&right_row) {
|
||||
return Err(Error::not_enough_rows_available(self.k, right_row + 1));
|
||||
}
|
||||
|
||||
self.permutation
|
||||
|
@ -490,7 +503,7 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
_: Option<Assigned<F>>,
|
||||
) -> Result<(), Error> {
|
||||
if !self.usable_rows.contains(&from_row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, from_row + 1));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -564,6 +577,7 @@ impl<F: FieldExt> MockProver<F> {
|
|||
let constants = cs.constants.clone();
|
||||
|
||||
let mut prover = MockProver {
|
||||
k,
|
||||
n: n as u32,
|
||||
cs,
|
||||
regions: vec![],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::cmp;
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
@ -45,9 +46,16 @@ impl From<io::Error> for Error {
|
|||
impl Error {
|
||||
/// Constructs an `Error::NotEnoughRowsAvailable`, computing the required `k` value.
|
||||
pub(crate) fn not_enough_rows_available(current_k: u32, required_rows: usize) -> Self {
|
||||
// To avoid needing to pass around the required number of blinding factors, we
|
||||
// assume here that k always needs to increment by at least 1.
|
||||
let minimum_k = cmp::max(
|
||||
current_k + 1,
|
||||
(required_rows.next_power_of_two() as f64).log2() as u32,
|
||||
);
|
||||
|
||||
Error::NotEnoughRowsAvailable {
|
||||
current_k,
|
||||
minimum_k: (required_rows.next_power_of_two() as f64).log2() as u32,
|
||||
minimum_k,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ where
|
|||
/// Assembly to be used in circuit synthesis.
|
||||
#[derive(Debug)]
|
||||
struct Assembly<F: Field> {
|
||||
k: u32,
|
||||
fixed: Vec<Polynomial<Assigned<F>, LagrangeCoeff>>,
|
||||
permutation: permutation::keygen::Assembly,
|
||||
selectors: Vec<Vec<bool>>,
|
||||
|
@ -69,7 +70,7 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
self.selectors[selector.0][row] = true;
|
||||
|
@ -79,7 +80,7 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
|
||||
fn query_instance(&self, _: Column<Instance>, row: usize) -> Result<Option<F>, Error> {
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
// There is no instance in this context.
|
||||
|
@ -117,7 +118,7 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
*self
|
||||
|
@ -136,8 +137,11 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
right_column: Column<Any>,
|
||||
right_row: usize,
|
||||
) -> Result<(), Error> {
|
||||
if !self.usable_rows.contains(&left_row) || !self.usable_rows.contains(&right_row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
if !self.usable_rows.contains(&left_row) {
|
||||
return Err(Error::not_enough_rows_available(self.k, left_row + 1));
|
||||
}
|
||||
if !self.usable_rows.contains(&right_row) {
|
||||
return Err(Error::not_enough_rows_available(self.k, right_row + 1));
|
||||
}
|
||||
|
||||
self.permutation
|
||||
|
@ -151,7 +155,7 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
to: Option<Assigned<F>>,
|
||||
) -> Result<(), Error> {
|
||||
if !self.usable_rows.contains(&from_row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, from_row + 1));
|
||||
}
|
||||
|
||||
let col = self
|
||||
|
@ -198,6 +202,7 @@ where
|
|||
}
|
||||
|
||||
let mut assembly: Assembly<C::Scalar> = Assembly {
|
||||
k: params.k,
|
||||
fixed: vec![domain.empty_lagrange_assigned(); cs.num_fixed_columns],
|
||||
permutation: permutation::keygen::Assembly::new(params.n as usize, &cs.permutation),
|
||||
selectors: vec![vec![false; params.n as usize]; cs.num_selectors],
|
||||
|
@ -261,6 +266,7 @@ where
|
|||
}
|
||||
|
||||
let mut assembly: Assembly<C::Scalar> = Assembly {
|
||||
k: params.k,
|
||||
fixed: vec![vk.domain.empty_lagrange_assigned(); cs.num_fixed_columns],
|
||||
permutation: permutation::keygen::Assembly::new(params.n as usize, &cs.permutation),
|
||||
selectors: vec![vec![false; params.n as usize]; cs.num_selectors],
|
||||
|
|
|
@ -128,6 +128,7 @@ pub fn create_proof<
|
|||
.zip(instances.iter())
|
||||
.map(|(circuit, instances)| -> Result<AdviceSingle<C>, Error> {
|
||||
struct WitnessCollection<'a, F: Field> {
|
||||
k: u32,
|
||||
pub advice: Vec<Polynomial<Assigned<F>, LagrangeCoeff>>,
|
||||
instances: &'a [&'a [F]],
|
||||
usable_rows: RangeTo<usize>,
|
||||
|
@ -168,7 +169,7 @@ pub fn create_proof<
|
|||
row: usize,
|
||||
) -> Result<Option<F>, Error> {
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
self.instances
|
||||
|
@ -192,7 +193,7 @@ pub fn create_proof<
|
|||
AR: Into<String>,
|
||||
{
|
||||
if !self.usable_rows.contains(&row) {
|
||||
return Err(Error::BoundsFailure);
|
||||
return Err(Error::not_enough_rows_available(self.k, row + 1));
|
||||
}
|
||||
|
||||
*self
|
||||
|
@ -259,6 +260,7 @@ pub fn create_proof<
|
|||
let unusable_rows_start = params.n as usize - (meta.blinding_factors() + 1);
|
||||
|
||||
let mut witness = WitnessCollection {
|
||||
k: params.k,
|
||||
advice: vec![domain.empty_lagrange_assigned(); meta.num_advice_columns],
|
||||
instances,
|
||||
// The prover will not be allowed to assign values to advice
|
||||
|
|
|
@ -405,6 +405,17 @@ fn plonk_api() {
|
|||
}) if current_k == 1 && minimum_k == 3
|
||||
);
|
||||
|
||||
// Check that we get an error if we try to initialize the proving key with a value of
|
||||
// k that is too small for the number of rows the circuit uses.
|
||||
let slightly_too_small_params: Params<EqAffine> = Params::new(K - 1);
|
||||
assert_matches!(
|
||||
keygen_vk(&slightly_too_small_params, &empty_circuit),
|
||||
Err(Error::NotEnoughRowsAvailable {
|
||||
current_k,
|
||||
minimum_k,
|
||||
}) if current_k == K - 1 && minimum_k == K
|
||||
);
|
||||
|
||||
// Initialize the proving key
|
||||
let vk = keygen_vk(¶ms, &empty_circuit).expect("keygen_vk should not fail");
|
||||
let pk = keygen_pk(¶ms, vk, &empty_circuit).expect("keygen_pk should not fail");
|
||||
|
|
Loading…
Reference in New Issue