mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Merge pull request #209 from zcash/ecc-gadget-fixedpoints
Store `Loaded` chip state in chip
This commit is contained in:
commit
9467a03ae2
4 changed files with 50 additions and 12 deletions
|
|
@ -138,6 +138,7 @@ impl<F: FieldExt> FieldChip<F> {
|
||||||
// ANCHOR: chip-impl
|
// ANCHOR: chip-impl
|
||||||
impl<F: FieldExt> Chip for FieldChip<F> {
|
impl<F: FieldExt> Chip for FieldChip<F> {
|
||||||
type Config = FieldConfig;
|
type Config = FieldConfig;
|
||||||
|
type Loaded = ();
|
||||||
type Field = F;
|
type Field = F;
|
||||||
|
|
||||||
fn load(_layouter: &mut impl Layouter<Self>) -> Result<(), halo2::plonk::Error> {
|
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> {
|
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.
|
// Load our private values into the circuit.
|
||||||
let a = FieldChip::load_private(&mut layouter, self.a)?;
|
let a = FieldChip::load_private(&mut layouter, self.a)?;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,26 @@ pub mod layouter;
|
||||||
/// [`Layouter::config`].
|
/// [`Layouter::config`].
|
||||||
pub trait Chip: Sized {
|
pub trait Chip: Sized {
|
||||||
/// A type that holds the configuration for this chip, and any other state it may need
|
/// 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;
|
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.
|
/// The field that the chip is defined over.
|
||||||
///
|
///
|
||||||
/// This provides a type that the chip's configuration can reference if necessary.
|
/// This provides a type that the chip's configuration can reference if necessary.
|
||||||
type Field: FieldExt;
|
type Field: FieldExt;
|
||||||
|
|
||||||
/// Load any fixed configuration for this chip into the circuit.
|
/// 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
|
/// Index of a region in a layouter
|
||||||
|
|
@ -161,6 +171,12 @@ pub trait Layouter<C: Chip> {
|
||||||
/// Provides access to the chip configuration.
|
/// Provides access to the chip configuration.
|
||||||
fn config(&self) -> &C::Config;
|
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.
|
/// Assign a region of gates to an absolute row number.
|
||||||
///
|
///
|
||||||
/// Inside the closure, the chip may freely use relative offsets; the `Layouter` will
|
/// 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()
|
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>
|
fn assign_region<A, AR, N, NR>(&mut self, name: N, assignment: A) -> Result<AR, Error>
|
||||||
where
|
where
|
||||||
A: FnMut(Region<'_, C>) -> Result<AR, Error>,
|
A: FnMut(Region<'_, C>) -> Result<AR, Error>,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ pub trait RegionLayouter<C: Chip>: fmt::Debug {
|
||||||
pub struct SingleChip<'a, C: Chip, CS: Assignment<C::Field> + 'a> {
|
pub struct SingleChip<'a, C: Chip, CS: Assignment<C::Field> + 'a> {
|
||||||
cs: &'a mut CS,
|
cs: &'a mut CS,
|
||||||
config: C::Config,
|
config: C::Config,
|
||||||
|
loaded: Option<C::Loaded>,
|
||||||
/// Stores the starting row for each region.
|
/// Stores the starting row for each region.
|
||||||
regions: Vec<RegionStart>,
|
regions: Vec<RegionStart>,
|
||||||
/// Stores the first empty row for each column.
|
/// 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> {
|
impl<'a, C: Chip, CS: Assignment<C::Field>> SingleChip<'a, C, CS> {
|
||||||
/// Creates a new single-chip layouter.
|
/// Creates a new single-chip layouter.
|
||||||
pub fn new(cs: &'a mut CS, config: C::Config) -> Self {
|
pub fn new(cs: &'a mut CS, config: C::Config) -> Result<Self, Error> {
|
||||||
SingleChip {
|
let mut ret = SingleChip {
|
||||||
cs,
|
cs,
|
||||||
config,
|
config,
|
||||||
|
loaded: None,
|
||||||
regions: vec![],
|
regions: vec![],
|
||||||
columns: HashMap::default(),
|
columns: HashMap::default(),
|
||||||
_marker: PhantomData,
|
_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
|
&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>
|
fn assign_region<A, AR, N, NR>(&mut self, name: N, mut assignment: A) -> Result<AR, Error>
|
||||||
where
|
where
|
||||||
A: FnMut(Region<'_, C>) -> Result<AR, Error>,
|
A: FnMut(Region<'_, C>) -> Result<AR, Error>,
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,17 @@ use crate::{
|
||||||
plonk::Error,
|
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.
|
/// The set of circuit instructions required to use the ECC gadgets.
|
||||||
pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
|
pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
|
||||||
/// Variable representing an element of the elliptic curve's scalar field.
|
/// Variable representing an element of the elliptic curve's scalar field.
|
||||||
type Scalar: Clone + fmt::Debug;
|
type Scalar: Clone + fmt::Debug;
|
||||||
/// Variable representing an elliptic curve point.
|
/// Variable representing an elliptic curve point.
|
||||||
type Point: Clone + fmt::Debug;
|
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).
|
/// Variable representing a fixed elliptic curve point (constant in the circuit).
|
||||||
type FixedPoint: Clone + fmt::Debug;
|
type FixedPoint: Clone + fmt::Debug;
|
||||||
|
|
||||||
|
|
@ -29,10 +34,10 @@ pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
|
||||||
value: Option<C>,
|
value: Option<C>,
|
||||||
) -> Result<Self::Point, Error>;
|
) -> Result<Self::Point, Error>;
|
||||||
|
|
||||||
/// Loads a fixed point into the circuit.
|
/// Gets a fixed point into the circuit.
|
||||||
fn load_fixed(
|
fn get_fixed(
|
||||||
layouter: &mut impl Layouter<Self>,
|
layouter: &mut impl Layouter<Self>,
|
||||||
value: Option<C>,
|
fixed_points: Self::FixedPoints,
|
||||||
) -> Result<Self::FixedPoint, Error>;
|
) -> Result<Self::FixedPoint, Error>;
|
||||||
|
|
||||||
/// Performs point addition, returning `a + b`.
|
/// 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> {
|
impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPoint<C, EccChip> {
|
||||||
/// Loads a fixed point with the given value into the circuit.
|
/// Gets a reference to the specified fixed point in the circuit.
|
||||||
pub fn load(mut layouter: impl Layouter<EccChip>, value: Option<C>) -> Result<Self, Error> {
|
pub fn get(
|
||||||
EccChip::load_fixed(&mut layouter, value).map(|inner| FixedPoint { inner })
|
mut layouter: impl Layouter<EccChip>,
|
||||||
|
point: EccChip::FixedPoints,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
EccChip::get_fixed(&mut layouter, point).map(|inner| FixedPoint { inner })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `[by] self`.
|
/// Returns `[by] self`.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue