Add annotations to Region::{assign_advice, assign_fixed}

This enables circuits to annotate individual cells with variable names
or similar protocol-specific metadata.
This commit is contained in:
Jack Grigg 2021-01-22 16:57:38 +00:00
parent fb82730d85
commit 4c3adf59d5
9 changed files with 292 additions and 141 deletions

View file

@ -76,25 +76,36 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.b, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::zero()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::zero()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::one()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::one()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),
@ -108,25 +119,36 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.b, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::one()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::one()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::zero()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::zero()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),

View file

@ -76,25 +76,36 @@ impl<'a, FF: FieldExt, CS: Assignment<FF>> StandardCS<FF> for StandardPLONK<'a,
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.b, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::zero()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::zero()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::one()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::one()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),
@ -108,25 +119,36 @@ impl<'a, FF: FieldExt, CS: Assignment<FF>> StandardCS<FF> for StandardPLONK<'a,
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.b, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::one()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::one()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::zero()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::zero()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),
@ -156,9 +178,10 @@ impl<'a, FF: FieldExt, CS: Assignment<FF>> StandardCS<FF> for StandardPLONK<'a,
{ {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
self.cs.assign_advice(self.config.a, index, || f())?;
self.cs self.cs
.assign_fixed(self.config.sp, index, || Ok(FF::one()))?; .assign_advice(|| "value", self.config.a, index, || f())?;
self.cs
.assign_fixed(|| "public", self.config.sp, index, || Ok(FF::one()))?;
Ok(Variable(self.config.a, index)) Ok(Variable(self.config.a, index))
} }

View file

@ -81,25 +81,39 @@ impl<'r, C: Chip> Region<'r, C> {
/// Assign an advice column value (witness). /// Assign an advice column value (witness).
/// ///
/// Even though `to` has `FnMut` bounds, it is guaranteed to be called at most once. /// Even though `to` has `FnMut` bounds, it is guaranteed to be called at most once.
pub fn assign_advice<'v>( pub fn assign_advice<'v, V, A, AR>(
&'v mut self, &'v mut self,
annotation: A,
column: Column<Advice>, column: Column<Advice>,
offset: usize, offset: usize,
mut to: impl FnMut() -> Result<C::Field, Error> + 'v, mut to: V,
) -> Result<Cell, Error> { ) -> Result<Cell, Error>
self.region.assign_advice(column, offset, &mut to) where
V: FnMut() -> Result<C::Field, Error> + 'v,
A: Fn() -> AR,
AR: Into<String>,
{
self.region
.assign_advice(&|| annotation().into(), column, offset, &mut to)
} }
/// Assign a fixed value. /// Assign a fixed value.
/// ///
/// Even though `to` has `FnMut` bounds, it is guaranteed to be called at most once. /// Even though `to` has `FnMut` bounds, it is guaranteed to be called at most once.
pub fn assign_fixed<'v>( pub fn assign_fixed<'v, V, A, AR>(
&'v mut self, &'v mut self,
annotation: A,
column: Column<Fixed>, column: Column<Fixed>,
offset: usize, offset: usize,
mut to: impl FnMut() -> Result<C::Field, Error> + 'v, mut to: V,
) -> Result<Cell, Error> { ) -> Result<Cell, Error>
self.region.assign_fixed(column, offset, &mut to) where
V: FnMut() -> Result<C::Field, Error> + 'v,
A: Fn() -> AR,
AR: Into<String>,
{
self.region
.assign_fixed(&|| annotation().into(), column, offset, &mut to)
} }
/// Constraint two cells to have the same value. /// Constraint two cells to have the same value.

View file

@ -40,6 +40,7 @@ pub trait RegionLayouter<C: Chip>: fmt::Debug {
/// Assign an advice column value (witness) /// Assign an advice column value (witness)
fn assign_advice<'v>( fn assign_advice<'v>(
&'v mut self, &'v mut self,
annotation: &'v (dyn Fn() -> String + 'v),
column: Column<Advice>, column: Column<Advice>,
offset: usize, offset: usize,
to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
@ -48,6 +49,7 @@ pub trait RegionLayouter<C: Chip>: fmt::Debug {
/// Assign a fixed value /// Assign a fixed value
fn assign_fixed<'v>( fn assign_fixed<'v>(
&'v mut self, &'v mut self,
annotation: &'v (dyn Fn() -> String + 'v),
column: Column<Fixed>, column: Column<Fixed>,
offset: usize, offset: usize,
to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
@ -176,6 +178,7 @@ impl RegionShape {
impl<C: Chip> RegionLayouter<C> for RegionShape { impl<C: Chip> RegionLayouter<C> for RegionShape {
fn assign_advice<'v>( fn assign_advice<'v>(
&'v mut self, &'v mut self,
_: &'v (dyn Fn() -> String + 'v),
column: Column<Advice>, column: Column<Advice>,
offset: usize, offset: usize,
_to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), _to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
@ -192,6 +195,7 @@ impl<C: Chip> RegionLayouter<C> for RegionShape {
fn assign_fixed<'v>( fn assign_fixed<'v>(
&'v mut self, &'v mut self,
_: &'v (dyn Fn() -> String + 'v),
column: Column<Fixed>, column: Column<Fixed>,
offset: usize, offset: usize,
_to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), _to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
@ -247,11 +251,13 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> RegionLayouter<C>
{ {
fn assign_advice<'v>( fn assign_advice<'v>(
&'v mut self, &'v mut self,
annotation: &'v (dyn Fn() -> String + 'v),
column: Column<Advice>, column: Column<Advice>,
offset: usize, offset: usize,
to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
) -> Result<Cell, Error> { ) -> Result<Cell, Error> {
self.layouter.cs.assign_advice( self.layouter.cs.assign_advice(
annotation,
column, column,
self.layouter.regions[self.region_index] + offset, self.layouter.regions[self.region_index] + offset,
to, to,
@ -266,11 +272,13 @@ impl<'r, 'a, C: Chip, CS: Assignment<C::Field> + 'a> RegionLayouter<C>
fn assign_fixed<'v>( fn assign_fixed<'v>(
&'v mut self, &'v mut self,
annotation: &'v (dyn Fn() -> String + 'v),
column: Column<Fixed>, column: Column<Fixed>,
offset: usize, offset: usize,
to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v), to: &'v mut (dyn FnMut() -> Result<C::Field, Error> + 'v),
) -> Result<Cell, Error> { ) -> Result<Cell, Error> {
self.layouter.cs.assign_fixed( self.layouter.cs.assign_fixed(
annotation,
column, column,
self.layouter.regions[self.region_index] + offset, self.layouter.regions[self.region_index] + offset,
to, to,

View file

@ -4,7 +4,10 @@ use ff::Field;
use crate::{ use crate::{
arithmetic::{FieldExt, Group}, arithmetic::{FieldExt, Group},
plonk::{permutation, Any, Assignment, Circuit, Column, ColumnType, ConstraintSystem, Error}, plonk::{
permutation, Advice, Any, Assignment, Circuit, Column, ColumnType, ConstraintSystem, Error,
Fixed,
},
poly::Rotation, poly::Rotation,
}; };
@ -96,13 +99,13 @@ pub enum VerifyFailure {
/// } /// }
/// ///
/// fn synthesize(&self, cs: &mut impl Assignment<F>, config: MyConfig) -> Result<(), Error> { /// fn synthesize(&self, cs: &mut impl Assignment<F>, config: MyConfig) -> Result<(), Error> {
/// cs.assign_advice(config.a, 0, || { /// cs.assign_advice(|| "a", config.a, 0, || {
/// self.a.map(|v| F::from_u64(v)).ok_or(Error::SynthesisError) /// self.a.map(|v| F::from_u64(v)).ok_or(Error::SynthesisError)
/// })?; /// })?;
/// cs.assign_advice(config.b, 0, || { /// cs.assign_advice(|| "b", config.b, 0, || {
/// self.b.map(|v| F::from_u64(v)).ok_or(Error::SynthesisError) /// self.b.map(|v| F::from_u64(v)).ok_or(Error::SynthesisError)
/// })?; /// })?;
/// cs.assign_advice(config.c, 0, || { /// cs.assign_advice(|| "c", config.c, 0, || {
/// self.a /// self.a
/// .and_then(|a| self.b.map(|b| F::from_u64(a * b))) /// .and_then(|a| self.b.map(|b| F::from_u64(a * b)))
/// .ok_or(Error::SynthesisError) /// .ok_or(Error::SynthesisError)
@ -144,12 +147,18 @@ pub struct MockProver<F: Group> {
} }
impl<F: Field + Group> Assignment<F> for MockProver<F> { impl<F: Field + Group> Assignment<F> for MockProver<F> {
fn assign_advice( fn assign_advice<V, A, AR>(
&mut self, &mut self,
column: crate::plonk::Column<crate::plonk::Advice>, _: A,
column: Column<Advice>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, crate::plonk::Error>, to: V,
) -> Result<(), crate::plonk::Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
*self *self
.advice .advice
.get_mut(column.index()) .get_mut(column.index())
@ -159,12 +168,18 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
Ok(()) Ok(())
} }
fn assign_fixed( fn assign_fixed<V, A, AR>(
&mut self, &mut self,
column: crate::plonk::Column<crate::plonk::Fixed>, _: A,
column: Column<Fixed>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, crate::plonk::Error>, to: V,
) -> Result<(), crate::plonk::Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
*self *self
.fixed .fixed
.get_mut(column.index()) .get_mut(column.index())

View file

@ -230,31 +230,48 @@ fn test_proving() {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.d, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.0.square().square()) self.cs.assign_advice(
})?; || "lhs^4",
self.cs.assign_advice(self.config.b, index, || { self.config.d,
Ok(value.ok_or(Error::SynthesisError)?.1) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()),
self.cs.assign_advice(self.config.e, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1.square().square()) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "rhs^4",
self.config.e,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.1.square().square()),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::zero()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::zero()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::zero()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::one()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::one()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),
@ -268,31 +285,48 @@ fn test_proving() {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
let mut value = None; let mut value = None;
self.cs.assign_advice(self.config.a, index, || { self.cs.assign_advice(
|| "lhs",
self.config.a,
index,
|| {
value = Some(f()?); value = Some(f()?);
Ok(value.ok_or(Error::SynthesisError)?.0) Ok(value.ok_or(Error::SynthesisError)?.0)
})?; },
self.cs.assign_advice(self.config.d, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.0.square().square()) self.cs.assign_advice(
})?; || "lhs^4",
self.cs.assign_advice(self.config.b, index, || { self.config.d,
Ok(value.ok_or(Error::SynthesisError)?.1) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.0.square().square()),
self.cs.assign_advice(self.config.e, index, || { )?;
Ok(value.ok_or(Error::SynthesisError)?.1.square().square()) self.cs.assign_advice(
})?; || "rhs",
self.cs.assign_advice(self.config.c, index, || { self.config.b,
Ok(value.ok_or(Error::SynthesisError)?.2) index,
})?; || Ok(value.ok_or(Error::SynthesisError)?.1),
)?;
self.cs.assign_advice(
|| "rhs^4",
self.config.e,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.1.square().square()),
)?;
self.cs.assign_advice(
|| "out",
self.config.c,
index,
|| Ok(value.ok_or(Error::SynthesisError)?.2),
)?;
self.cs self.cs
.assign_fixed(self.config.sa, index, || Ok(FF::one()))?; .assign_fixed(|| "a", self.config.sa, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sb, index, || Ok(FF::one()))?; .assign_fixed(|| "b", self.config.sb, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?; .assign_fixed(|| "c", self.config.sc, index, || Ok(FF::one()))?;
self.cs self.cs
.assign_fixed(self.config.sm, index, || Ok(FF::zero()))?; .assign_fixed(|| "a * b", self.config.sm, index, || Ok(FF::zero()))?;
Ok(( Ok((
Variable(self.config.a, index), Variable(self.config.a, index),
Variable(self.config.b, index), Variable(self.config.b, index),
@ -329,9 +363,10 @@ fn test_proving() {
{ {
let index = self.current_gate; let index = self.current_gate;
self.current_gate += 1; self.current_gate += 1;
self.cs.assign_advice(self.config.a, index, || f())?;
self.cs self.cs
.assign_fixed(self.config.sp, index, || Ok(FF::one()))?; .assign_advice(|| "value", self.config.a, index, || f())?;
self.cs
.assign_fixed(|| "public", self.config.sp, index, || Ok(FF::one()))?;
Ok(Variable(self.config.a, index)) Ok(Variable(self.config.a, index))
} }
@ -341,9 +376,9 @@ fn test_proving() {
self.current_gate += 1; self.current_gate += 1;
self.cs self.cs
.assign_fixed(self.config.sl, index, || Ok(value_0))?; .assign_fixed(|| "table col 1", self.config.sl, index, || Ok(value_0))?;
self.cs self.cs
.assign_fixed(self.config.sl2, index, || Ok(value_1))?; .assign_fixed(|| "table col 2", self.config.sl2, index, || Ok(value_1))?;
} }
Ok(()) Ok(())
} }

View file

@ -127,20 +127,30 @@ impl TryFrom<Column<Any>> for Column<Aux> {
/// for a constraint system. /// for a constraint system.
pub trait Assignment<F: Field> { pub trait Assignment<F: Field> {
/// Assign an advice column value (witness) /// Assign an advice column value (witness)
fn assign_advice( fn assign_advice<V, A, AR>(
&mut self, &mut self,
annotation: A,
column: Column<Advice>, column: Column<Advice>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, Error>, to: V,
) -> Result<(), Error>; ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>;
/// Assign a fixed value /// Assign a fixed value
fn assign_fixed( fn assign_fixed<V, A, AR>(
&mut self, &mut self,
annotation: A,
column: Column<Fixed>, column: Column<Fixed>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, Error>, to: V,
) -> Result<(), Error>; ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>;
/// Assign two advice columns to have the same value /// Assign two advice columns to have the same value
fn copy( fn copy(

View file

@ -57,29 +57,41 @@ where
/// Assembly to be used in circuit synthesis. /// Assembly to be used in circuit synthesis.
#[derive(Debug)] #[derive(Debug)]
pub struct Assembly<F: Field> { struct Assembly<F: Field> {
fixed: Vec<Polynomial<F, LagrangeCoeff>>, fixed: Vec<Polynomial<F, LagrangeCoeff>>,
permutations: Vec<permutation::keygen::Assembly>, permutations: Vec<permutation::keygen::Assembly>,
_marker: std::marker::PhantomData<F>, _marker: std::marker::PhantomData<F>,
} }
impl<F: Field> Assignment<F> for Assembly<F> { impl<F: Field> Assignment<F> for Assembly<F> {
fn assign_advice( fn assign_advice<V, A, AR>(
&mut self, &mut self,
_: A,
_: Column<Advice>, _: Column<Advice>,
_: usize, _: usize,
_: impl FnOnce() -> Result<F, Error>, _: V,
) -> Result<(), Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
// We only care about fixed columns here // We only care about fixed columns here
Ok(()) Ok(())
} }
fn assign_fixed( fn assign_fixed<V, A, AR>(
&mut self, &mut self,
_: A,
column: Column<Fixed>, column: Column<Fixed>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, Error>, to: V,
) -> Result<(), Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
*self *self
.fixed .fixed
.get_mut(column.index()) .get_mut(column.index())

View file

@ -100,12 +100,18 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
} }
impl<F: Field> Assignment<F> for WitnessCollection<F> { impl<F: Field> Assignment<F> for WitnessCollection<F> {
fn assign_advice( fn assign_advice<V, A, AR>(
&mut self, &mut self,
_: A,
column: Column<Advice>, column: Column<Advice>,
row: usize, row: usize,
to: impl FnOnce() -> Result<F, Error>, to: V,
) -> Result<(), Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
*self *self
.advice .advice
.get_mut(column.index()) .get_mut(column.index())
@ -115,12 +121,18 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
Ok(()) Ok(())
} }
fn assign_fixed( fn assign_fixed<V, A, AR>(
&mut self, &mut self,
_: A,
_: Column<Fixed>, _: Column<Fixed>,
_: usize, _: usize,
_: impl FnOnce() -> Result<F, Error>, _: V,
) -> Result<(), Error> { ) -> Result<(), Error>
where
V: FnOnce() -> Result<F, Error>,
A: FnOnce() -> AR,
AR: Into<String>,
{
// We only care about advice columns here // We only care about advice columns here
Ok(()) Ok(())