Give fixed and advice wires separate types

This commit is contained in:
Sean Bowe 2020-08-23 13:26:04 -06:00
parent 7edffe0197
commit c20f3fdf1a
No known key found for this signature in database
GPG key ID: 95684257D8F8B031
4 changed files with 100 additions and 77 deletions

View file

@ -112,14 +112,14 @@ fn test_proving() {
let params: Params<EqAffine> = Params::new::<DummyHash<Fq>>(K);
struct MyConfig {
a: Wire,
b: Wire,
c: Wire,
a: AdviceWire,
b: AdviceWire,
c: AdviceWire,
sa: Wire,
sb: Wire,
sc: Wire,
sm: Wire,
sa: FixedWire,
sb: FixedWire,
sc: FixedWire,
sm: FixedWire,
}
struct MyCircuit<F: Field> {
a: Option<F>,
@ -174,36 +174,26 @@ fn test_proving() {
// Similar to the above...
let mut row = 0;
for _ in 0..10 {
cs.assign(Variable(config.a, row), || {
self.a.ok_or(Error::SynthesisError)
})?;
cs.assign(Variable(config.b, row), || {
self.a.ok_or(Error::SynthesisError)
})?;
cs.assign_advice(config.a, row, || self.a.ok_or(Error::SynthesisError))?;
cs.assign_advice(config.b, row, || self.a.ok_or(Error::SynthesisError))?;
let a_squared = self.a.map(|a| a.square());
cs.assign(Variable(config.c, row), || {
self.a.ok_or(Error::SynthesisError)
})?;
cs.assign_advice(config.c, row, || self.a.ok_or(Error::SynthesisError))?;
// Multiplication gate
cs.assign(Variable(config.sa, row), || Ok(Field::zero()))?;
cs.assign(Variable(config.sb, row), || Ok(Field::zero()))?;
cs.assign(Variable(config.sc, row), || Ok(Field::one()))?;
cs.assign(Variable(config.sm, row), || Ok(Field::one()))?;
cs.assign_fixed(config.sa, row, || Ok(Field::zero()))?;
cs.assign_fixed(config.sb, row, || Ok(Field::zero()))?;
cs.assign_fixed(config.sc, row, || Ok(Field::one()))?;
cs.assign_fixed(config.sm, row, || Ok(Field::one()))?;
row += 1;
cs.assign(Variable(config.a, row), || {
self.a.ok_or(Error::SynthesisError)
})?;
cs.assign(Variable(config.b, row), || {
a_squared.ok_or(Error::SynthesisError)
})?;
cs.assign_advice(config.a, row, || self.a.ok_or(Error::SynthesisError))?;
cs.assign_advice(config.b, row, || a_squared.ok_or(Error::SynthesisError))?;
let fin = a_squared.and_then(|a_squared| self.a.map(|a| a + a_squared));
cs.assign(Variable(config.c, row), || fin.ok_or(Error::SynthesisError))?;
cs.assign_advice(config.c, row, || fin.ok_or(Error::SynthesisError))?;
// Addition gate
cs.assign(Variable(config.sa, row), || Ok(Field::one()))?;
cs.assign(Variable(config.sb, row), || Ok(Field::one()))?;
cs.assign(Variable(config.sc, row), || Ok(Field::one()))?;
cs.assign(Variable(config.sm, row), || Ok(Field::zero()))?;
cs.assign_fixed(config.sa, row, || Ok(Field::one()))?;
cs.assign_fixed(config.sb, row, || Ok(Field::one()))?;
cs.assign_fixed(config.sc, row, || Ok(Field::one()))?;
cs.assign_fixed(config.sm, row, || Ok(Field::zero()))?;
row += 1;
}

View file

@ -16,12 +16,16 @@ pub enum Wire {
C,
/// D wires
D,
/// Fixed wires
Fixed(usize),
/// Advice wires
Advice(usize),
}
/// This represents a wire which has a fixed (permanent) value
#[derive(Copy, Clone, Debug)]
pub struct FixedWire(pub usize);
/// This represents a wire which has a witness-specific value
#[derive(Copy, Clone, Debug)]
pub struct AdviceWire(pub usize);
/// Represents a pointer to a value in the constraint system.
#[derive(Clone, Debug)]
pub struct Variable(pub Wire, pub usize);
@ -29,9 +33,21 @@ pub struct Variable(pub Wire, pub usize);
/// This trait allows a [`Circuit`] to direct some backend to assign a witness
/// for a constraint system.
pub trait ConstraintSystem<F: Field> {
/// Assign a wire value
fn assign(&mut self, var: Variable, to: impl FnOnce() -> Result<F, Error>)
-> Result<(), Error>;
/// Assign an advice wire value (witness)
fn assign_advice(
&mut self,
wire: AdviceWire,
row: usize,
to: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error>;
/// Assign a fixed value
fn assign_fixed(
&mut self,
wire: FixedWire,
row: usize,
to: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error>;
/// Creates a gate.
fn create_gate(
@ -93,8 +109,10 @@ pub trait Circuit<F: Field> {
/// Low-degree polynomial representing an identity that must hold over the committed wires.
#[derive(Clone, Debug)]
pub enum Polynomial<F> {
/// This is a wire queried at a certain relative location
Wire(Wire, isize),
/// This is a fixed wire queried at a certain relative location
Fixed(FixedWire, isize),
/// This is an advice (witness) wire queried at a certain relative location
Advice(AdviceWire, isize),
/// This is the sum of two polynomials
Sum(Box<Polynomial<F>>, Box<Polynomial<F>>),
/// This is the product of two polynomials
@ -106,10 +124,11 @@ pub enum Polynomial<F> {
impl<F: Field> Polynomial<F> {
fn degree(&self) -> usize {
match self {
Polynomial::Wire(_, _) => 1,
Polynomial::Sum(ref a, ref b) => max(a.degree(), b.degree()),
Polynomial::Product(ref a, ref b) => a.degree() + b.degree(),
Polynomial::Scaled(ref poly, _) => poly.degree(),
Polynomial::Fixed(_, _) => 1,
Polynomial::Advice(_, _) => 1,
Polynomial::Sum(a, b) => max(a.degree(), b.degree()),
Polynomial::Product(a, b) => a.degree() + b.degree(),
Polynomial::Scaled(poly, _) => poly.degree(),
}
}
}
@ -158,14 +177,14 @@ impl Default for MetaCircuit {
impl MetaCircuit {
/// Allocate a new fixed wire
pub fn fixed_wire(&mut self) -> Wire {
let tmp = Wire::Fixed(self.num_fixed_wires);
pub fn fixed_wire(&mut self) -> FixedWire {
let tmp = FixedWire(self.num_fixed_wires);
self.num_fixed_wires += 1;
tmp
}
/// Allocate a new advice wire
pub fn advice_wire(&mut self) -> Wire {
let tmp = Wire::Advice(self.num_advice_wires);
pub fn advice_wire(&mut self) -> AdviceWire {
let tmp = AdviceWire(self.num_advice_wires);
self.num_advice_wires += 1;
tmp
}

View file

@ -1,5 +1,5 @@
use super::{
circuit::{Circuit, ConstraintSystem, MetaCircuit, Variable, Wire},
circuit::{AdviceWire, Circuit, ConstraintSystem, FixedWire, MetaCircuit, Variable, Wire},
hash_point, Error, Proof, SRS,
};
use crate::arithmetic::{
@ -35,22 +35,29 @@ impl<C: CurveAffine> Proof<C> {
}
impl<F: Field> ConstraintSystem<F> for WitnessCollection<F> {
fn assign(
fn assign_advice(
&mut self,
var: Variable,
wire: AdviceWire,
row: usize,
to: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
// We only care about advice wires here.
match var.0 {
Wire::Advice(index) => {
*self
.advice
.get_mut(index)
.and_then(|v| v.get_mut(var.1))
.ok_or(Error::BoundsFailure)? = to()?;
}
_ => {}
}
*self
.advice
.get_mut(wire.0)
.and_then(|v| v.get_mut(row))
.ok_or(Error::BoundsFailure)? = to()?;
Ok(())
}
fn assign_fixed(
&mut self,
_: FixedWire,
_: usize,
_: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
// We only care about advice wires here
Ok(())
}

View file

@ -1,5 +1,5 @@
use super::{
circuit::{Circuit, ConstraintSystem, MetaCircuit, Variable, Wire},
circuit::{AdviceWire, Circuit, ConstraintSystem, FixedWire, MetaCircuit, Variable, Wire},
domain::EvaluationDomain,
Error, GATE_DEGREE, SRS,
};
@ -23,24 +23,31 @@ impl<C: CurveAffine> SRS<C> {
}
impl<F: Field> ConstraintSystem<F> for Assembly<F> {
fn assign(
fn assign_advice(
&mut self,
var: Variable,
to: impl FnOnce() -> Result<F, Error>,
_: AdviceWire,
_: usize,
_: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
// We only care about fixed wires here.
match var.0 {
Wire::Fixed(index) => {
*self
.fixed
.get_mut(index)
.and_then(|v| v.get_mut(var.1))
.ok_or(Error::BoundsFailure)? = to()?;
}
_ => {}
}
// We only care about fixed wires here
Ok(())
}
fn assign_fixed(
&mut self,
wire: FixedWire,
row: usize,
to: impl FnOnce() -> Result<F, Error>,
) -> Result<(), Error> {
*self
.fixed
.get_mut(wire.0)
.and_then(|v| v.get_mut(row))
.ok_or(Error::BoundsFailure)? = to()?;
Ok(())
}
fn create_gate(
&mut self,
sa: F,