mirror of https://github.com/zcash/halo2.git
Add `Region::constrain_constant` API
This is the non-assigning subset of `Region::assign_advice_from_constant`.
This commit is contained in:
parent
4c5a830e5c
commit
629c13eae8
|
@ -225,6 +225,16 @@ impl<'r, F: Field> Region<'r, F> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Constrains a cell to have a constant value.
|
||||
///
|
||||
/// Returns an error if the cell is in a column where equality has not been enabled.
|
||||
pub fn constrain_constant<VR>(&mut self, cell: Cell, constant: VR) -> Result<(), Error>
|
||||
where
|
||||
VR: Into<Assigned<F>>,
|
||||
{
|
||||
self.region.constrain_constant(cell, constant.into())
|
||||
}
|
||||
|
||||
/// Constrains two cells to have the same value.
|
||||
///
|
||||
/// Returns an error if either of the cells are in columns where equality
|
||||
|
|
|
@ -215,28 +215,8 @@ impl<'r, 'a, F: Field, CS: Assignment<F> + 'a> RegionLayouter<F>
|
|||
offset: usize,
|
||||
constant: Assigned<F>,
|
||||
) -> Result<Cell, Error> {
|
||||
if self.layouter.constants.is_empty() {
|
||||
return Err(Error::NotEnoughColumnsForConstants);
|
||||
}
|
||||
|
||||
let advice = self.assign_advice(annotation, column, offset, &mut || Ok(constant))?;
|
||||
|
||||
// For the simple layouter, just assign the fixed constants inside the region
|
||||
// using the first constants column. self.next_constant_row is updated by this
|
||||
// function call.
|
||||
let fixed = self.assign_fixed(
|
||||
annotation,
|
||||
self.layouter.constants[0],
|
||||
// Convert the absolute row into a relative offset within this region, but
|
||||
// always at an offset that is not before this region (taking advantage of the
|
||||
// fact that for this single-pass layouter, regions are always layed out in
|
||||
// increasing row order).
|
||||
self.next_constant_row
|
||||
.saturating_sub(*self.layouter.regions[*self.region_index]),
|
||||
&mut || Ok(constant),
|
||||
)?;
|
||||
|
||||
self.constrain_equal(advice, fixed)?;
|
||||
self.constrain_constant(advice, constant)?;
|
||||
|
||||
Ok(advice)
|
||||
}
|
||||
|
@ -291,6 +271,29 @@ impl<'r, 'a, F: Field, CS: Assignment<F> + 'a> RegionLayouter<F>
|
|||
})
|
||||
}
|
||||
|
||||
fn constrain_constant(&mut self, cell: Cell, constant: Assigned<F>) -> Result<(), Error> {
|
||||
if self.layouter.constants.is_empty() {
|
||||
return Err(Error::NotEnoughColumnsForConstants);
|
||||
}
|
||||
|
||||
// For the simple layouter, just assign the fixed constants inside the region
|
||||
// using the first constants column. self.next_constant_row is updated by this
|
||||
// function call.
|
||||
let fixed = self.assign_fixed(
|
||||
&|| "constant".into(),
|
||||
self.layouter.constants[0],
|
||||
// Convert the absolute row into a relative offset within this region, but
|
||||
// always at an offset that is not before this region (taking advantage of the
|
||||
// fact that for this single-pass layouter, regions are always layed out in
|
||||
// increasing row order).
|
||||
self.next_constant_row
|
||||
.saturating_sub(*self.layouter.regions[*self.region_index]),
|
||||
&mut || Ok(constant),
|
||||
)?;
|
||||
|
||||
self.constrain_equal(cell, fixed)
|
||||
}
|
||||
|
||||
fn constrain_equal(&mut self, left: Cell, right: Cell) -> Result<(), Error> {
|
||||
self.layouter.cs.copy(
|
||||
left.column,
|
||||
|
|
|
@ -348,7 +348,7 @@ impl<'r, 'a, F: Field, CS: Assignment<F> + 'a> RegionLayouter<F> for V1Region<'r
|
|||
constant: Assigned<F>,
|
||||
) -> Result<Cell, Error> {
|
||||
let advice = self.assign_advice(annotation, column, offset, &mut || Ok(constant))?;
|
||||
self.plan.constants.push((constant, advice));
|
||||
self.constrain_constant(advice, constant)?;
|
||||
|
||||
Ok(advice)
|
||||
}
|
||||
|
@ -398,6 +398,11 @@ impl<'r, 'a, F: Field, CS: Assignment<F> + 'a> RegionLayouter<F> for V1Region<'r
|
|||
})
|
||||
}
|
||||
|
||||
fn constrain_constant(&mut self, cell: Cell, constant: Assigned<F>) -> Result<(), Error> {
|
||||
self.plan.constants.push((constant, cell));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn constrain_equal(&mut self, left: Cell, right: Cell) -> Result<(), Error> {
|
||||
self.plan.cs.copy(
|
||||
left.column,
|
||||
|
|
|
@ -94,6 +94,11 @@ pub trait RegionLayouter<F: Field>: fmt::Debug {
|
|||
to: &'v mut (dyn FnMut() -> Result<Assigned<F>, Error> + 'v),
|
||||
) -> Result<Cell, Error>;
|
||||
|
||||
/// Constrains a cell to have a constant value.
|
||||
///
|
||||
/// Returns an error if the cell is in a column where equality has not been enabled.
|
||||
fn constrain_constant(&mut self, cell: Cell, constant: Assigned<F>) -> Result<(), Error>;
|
||||
|
||||
/// Constraint two cells to have the same value.
|
||||
///
|
||||
/// Returns an error if either of the cells is not within the given permutation.
|
||||
|
@ -215,6 +220,11 @@ impl<F: Field> RegionLayouter<F> for RegionShape {
|
|||
})
|
||||
}
|
||||
|
||||
fn constrain_constant(&mut self, _cell: Cell, _constant: Assigned<F>) -> Result<(), Error> {
|
||||
// Global constants don't affect the region shape.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn constrain_equal(&mut self, _left: Cell, _right: Cell) -> Result<(), Error> {
|
||||
// Equality constraints don't affect the region shape.
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in New Issue