Merge pull request #209 from zcash/ecc-gadget-fixedpoints

Store `Loaded` chip state in chip
This commit is contained in:
str4d 2021-02-26 04:24:28 +13:00 committed by GitHub
commit 9467a03ae2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 12 deletions

View file

@ -138,6 +138,7 @@ impl<F: FieldExt> FieldChip<F> {
// ANCHOR: chip-impl
impl<F: FieldExt> Chip for FieldChip<F> {
type Config = FieldConfig;
type Loaded = ();
type Field = F;
fn load(_layouter: &mut impl Layouter<Self>) -> Result<(), halo2::plonk::Error> {
@ -286,7 +287,7 @@ impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
}
fn synthesize(&self, cs: &mut impl Assignment<F>, config: Self::Config) -> Result<(), Error> {
let mut layouter = SingleChip::new(cs, config);
let mut layouter = SingleChip::new(cs, config)?;
// Load our private values into the circuit.
let a = FieldChip::load_private(&mut layouter, self.a)?;

View file

@ -16,16 +16,26 @@ pub mod layouter;
/// [`Layouter::config`].
pub trait Chip: Sized {
/// A type that holds the configuration for this chip, and any other state it may need
/// during circuit synthesis.
/// during circuit synthesis, that can be derived during [`Circuit::configure`].
///
/// [`Circuit::configure`]: crate::plonk::Circuit::configure
type Config: fmt::Debug;
/// A type that holds any general chip state that needs to be loaded at the start of
/// [`Circuit::synthesize`]. This might simply be `()` for some chips.
///
/// [`Circuit::synthesize`]: crate::plonk::Circuit::synthesize
type Loaded: fmt::Debug;
/// The field that the chip is defined over.
///
/// This provides a type that the chip's configuration can reference if necessary.
type Field: FieldExt;
/// Load any fixed configuration for this chip into the circuit.
fn load(layouter: &mut impl Layouter<Self>) -> Result<(), Error>;
///
/// `layouter.loaded()` will panic if called inside this function.
fn load(layouter: &mut impl Layouter<Self>) -> Result<Self::Loaded, Error>;
}
/// Index of a region in a layouter
@ -161,6 +171,12 @@ pub trait Layouter<C: Chip> {
/// Provides access to the chip configuration.
fn config(&self) -> &C::Config;
/// Provides access to general chip state loaded at the beginning of circuit
/// synthesis.
///
/// Panics if called inside `C::load`.
fn loaded(&self) -> &C::Loaded;
/// Assign a region of gates to an absolute row number.
///
/// Inside the closure, the chip may freely use relative offsets; the `Layouter` will
@ -220,6 +236,10 @@ impl<'a, C: Chip, L: Layouter<C> + 'a> Layouter<C> for NamespacedLayouter<'a, C,
self.0.config()
}
fn loaded(&self) -> &C::Loaded {
self.0.loaded()
}
fn assign_region<A, AR, N, NR>(&mut self, name: N, assignment: A) -> Result<AR, Error>
where
A: FnMut(Region<'_, C>) -> Result<AR, Error>,

View file

@ -70,6 +70,7 @@ pub trait RegionLayouter<C: Chip>: fmt::Debug {
pub struct SingleChip<'a, C: Chip, CS: Assignment<C::Field> + 'a> {
cs: &'a mut CS,
config: C::Config,
loaded: Option<C::Loaded>,
/// Stores the starting row for each region.
regions: Vec<RegionStart>,
/// Stores the first empty row for each column.
@ -89,14 +90,18 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> fmt::Debug for SingleChip<'a, C
impl<'a, C: Chip, CS: Assignment<C::Field>> SingleChip<'a, C, CS> {
/// Creates a new single-chip layouter.
pub fn new(cs: &'a mut CS, config: C::Config) -> Self {
SingleChip {
pub fn new(cs: &'a mut CS, config: C::Config) -> Result<Self, Error> {
let mut ret = SingleChip {
cs,
config,
loaded: None,
regions: vec![],
columns: HashMap::default(),
_marker: PhantomData,
}
};
let loaded = C::load(&mut ret)?;
ret.loaded = Some(loaded);
Ok(ret)
}
}
@ -107,6 +112,10 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
&self.config
}
fn loaded(&self) -> &C::Loaded {
self.loaded.as_ref().expect("We called C::load")
}
fn assign_region<A, AR, N, NR>(&mut self, name: N, mut assignment: A) -> Result<AR, Error>
where
A: FnMut(Region<'_, C>) -> Result<AR, Error>,

View file

@ -8,12 +8,17 @@ use crate::{
plonk::Error,
};
/// Trait allowing circuit's fixed points to be enumerated.
pub trait FixedPoints<C: CurveAffine>: Clone + fmt::Debug {}
/// The set of circuit instructions required to use the ECC gadgets.
pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
/// Variable representing an element of the elliptic curve's scalar field.
type Scalar: Clone + fmt::Debug;
/// Variable representing an elliptic curve point.
type Point: Clone + fmt::Debug;
/// Variable representing the set of fixed bases in the circuit.
type FixedPoints: FixedPoints<C>;
/// Variable representing a fixed elliptic curve point (constant in the circuit).
type FixedPoint: Clone + fmt::Debug;
@ -29,10 +34,10 @@ pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
value: Option<C>,
) -> Result<Self::Point, Error>;
/// Loads a fixed point into the circuit.
fn load_fixed(
/// Gets a fixed point into the circuit.
fn get_fixed(
layouter: &mut impl Layouter<Self>,
value: Option<C>,
fixed_points: Self::FixedPoints,
) -> Result<Self::FixedPoint, Error>;
/// Performs point addition, returning `a + b`.
@ -116,9 +121,12 @@ pub struct FixedPoint<C: CurveAffine, EccChip: EccInstructions<C>> {
}
impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPoint<C, EccChip> {
/// Loads a fixed point with the given value into the circuit.
pub fn load(mut layouter: impl Layouter<EccChip>, value: Option<C>) -> Result<Self, Error> {
EccChip::load_fixed(&mut layouter, value).map(|inner| FixedPoint { inner })
/// Gets a reference to the specified fixed point in the circuit.
pub fn get(
mut layouter: impl Layouter<EccChip>,
point: EccChip::FixedPoints,
) -> Result<Self, Error> {
EccChip::get_fixed(&mut layouter, point).map(|inner| FixedPoint { inner })
}
/// Returns `[by] self`.