From c20f3fdf1aaa87c0c366d57f60fa3d4a68817464 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 23 Aug 2020 13:26:04 -0600 Subject: [PATCH] Give fixed and advice wires separate types --- src/plonk.rs | 52 ++++++++++++++++++------------------------- src/plonk/circuit.rs | 53 ++++++++++++++++++++++++++++++-------------- src/plonk/prover.rs | 35 +++++++++++++++++------------ src/plonk/srs.rs | 37 ++++++++++++++++++------------- 4 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/plonk.rs b/src/plonk.rs index 9385609..ef6e997 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -112,14 +112,14 @@ fn test_proving() { let params: Params = Params::new::>(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 { a: Option, @@ -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; } diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 3f4f872..6f3d165 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -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 { - /// Assign a wire value - fn assign(&mut self, var: Variable, to: impl FnOnce() -> Result) - -> Result<(), Error>; + /// Assign an advice wire value (witness) + fn assign_advice( + &mut self, + wire: AdviceWire, + row: usize, + to: impl FnOnce() -> Result, + ) -> Result<(), Error>; + + /// Assign a fixed value + fn assign_fixed( + &mut self, + wire: FixedWire, + row: usize, + to: impl FnOnce() -> Result, + ) -> Result<(), Error>; /// Creates a gate. fn create_gate( @@ -93,8 +109,10 @@ pub trait Circuit { /// Low-degree polynomial representing an identity that must hold over the committed wires. #[derive(Clone, Debug)] pub enum Polynomial { - /// 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>, Box>), /// This is the product of two polynomials @@ -106,10 +124,11 @@ pub enum Polynomial { impl Polynomial { 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 } diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index b99e015..4f3c854 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -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 Proof { } impl ConstraintSystem for WitnessCollection { - fn assign( + fn assign_advice( &mut self, - var: Variable, + wire: AdviceWire, + row: usize, to: impl FnOnce() -> Result, ) -> 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, + ) -> Result<(), Error> { + // We only care about advice wires here + Ok(()) } diff --git a/src/plonk/srs.rs b/src/plonk/srs.rs index 1c2e3b6..5a94d97 100644 --- a/src/plonk/srs.rs +++ b/src/plonk/srs.rs @@ -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 SRS { } impl ConstraintSystem for Assembly { - fn assign( + fn assign_advice( &mut self, - var: Variable, - to: impl FnOnce() -> Result, + _: AdviceWire, + _: usize, + _: impl FnOnce() -> Result, ) -> 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, + ) -> 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,