From 2034179d8263087d8d3c696a04a3a771a78c31ee Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Fri, 6 Nov 2020 11:13:54 +0800 Subject: [PATCH 1/8] Rename wire -> column --- src/plonk.rs | 63 +++++++------- src/plonk/circuit.rs | 191 +++++++++++++++++++++++++----------------- src/plonk/keygen.rs | 50 +++++------ src/plonk/prover.rs | 88 +++++++++---------- src/plonk/verifier.rs | 38 ++++----- 5 files changed, 237 insertions(+), 193 deletions(-) diff --git a/src/plonk.rs b/src/plonk.rs index 4dfd7773..6200dcc9 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -117,25 +117,25 @@ fn test_proving() { use std::marker::PhantomData; const K: u32 = 5; - /// This represents an advice wire at a certain row in the ConstraintSystem + /// This represents an advice column at a certain row in the ConstraintSystem #[derive(Copy, Clone, Debug)] - pub struct Variable(AdviceWire, usize); + pub struct Variable(AdviceColumn, usize); // Initialize the polynomial commitment parameters let params: Params = Params::new::>(K); struct PLONKConfig { - a: AdviceWire, - b: AdviceWire, - c: AdviceWire, - d: AdviceWire, - e: AdviceWire, + a: AdviceColumn, + b: AdviceColumn, + c: AdviceColumn, + d: AdviceColumn, + e: AdviceColumn, - sa: FixedWire, - sb: FixedWire, - sc: FixedWire, - sm: FixedWire, - sp: FixedWire, + sa: FixedColumn, + sb: FixedColumn, + sc: FixedColumn, + sm: FixedColumn, + sp: FixedColumn, perm: usize, perm2: usize, @@ -254,13 +254,13 @@ fn test_proving() { )) } fn copy(&mut self, left: Variable, right: Variable) -> Result<(), Error> { - let left_wire = match left.0 { + let left_column = match left.0 { x if x == self.config.a => 0, x if x == self.config.b => 1, x if x == self.config.c => 2, _ => unreachable!(), }; - let right_wire = match right.0 { + let right_column = match right.0 { x if x == self.config.a => 0, x if x == self.config.b => 1, x if x == self.config.c => 2, @@ -268,9 +268,14 @@ fn test_proving() { }; self.cs - .copy(self.config.perm, left_wire, left.1, right_wire, right.1)?; - self.cs - .copy(self.config.perm2, left_wire, left.1, right_wire, right.1) + .copy(self.config.perm, left_column, left.1, right_column, right.1)?; + self.cs.copy( + self.config.perm2, + left_column, + left.1, + right_column, + right.1, + ) } fn public_input(&mut self, f: F) -> Result where @@ -290,22 +295,22 @@ fn test_proving() { type Config = PLONKConfig; fn configure(meta: &mut ConstraintSystem) -> PLONKConfig { - let e = meta.advice_wire(); - let a = meta.advice_wire(); - let b = meta.advice_wire(); - let sf = meta.fixed_wire(); - let c = meta.advice_wire(); - let d = meta.advice_wire(); - let p = meta.aux_wire(); + let e = meta.advice_column(); + let a = meta.advice_column(); + let b = meta.advice_column(); + let sf = meta.fixed_column(); + let c = meta.advice_column(); + let d = meta.advice_column(); + let p = meta.aux_column(); let perm = meta.permutation(&[a, b, c]); let perm2 = meta.permutation(&[a, b, c]); - let sm = meta.fixed_wire(); - let sa = meta.fixed_wire(); - let sb = meta.fixed_wire(); - let sc = meta.fixed_wire(); - let sp = meta.fixed_wire(); + let sm = meta.fixed_column(); + let sa = meta.fixed_column(); + let sb = meta.fixed_column(); + let sc = meta.fixed_column(); + let sp = meta.fixed_column(); meta.create_gate(|meta| { let d = meta.query_advice(d, 1); diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index c12e386a..c17d4bb4 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -6,25 +6,25 @@ use super::Error; use crate::arithmetic::Field; use crate::poly::Rotation; -/// This represents a wire which has a fixed (permanent) value +/// This represents a column which has a fixed (permanent) value #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct FixedWire(pub usize); +pub struct FixedColumn(pub usize); -/// This represents a wire which has a witness-specific value +/// This represents a column which has a witness-specific value #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct AdviceWire(pub usize); +pub struct AdviceColumn(pub usize); -/// This represents a wire which has an externally assigned value +/// This represents a column which has an externally assigned value #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct AuxWire(pub usize); +pub struct AuxColumn(pub usize); /// This trait allows a [`Circuit`] to direct some backend to assign a witness /// for a constraint system. pub trait Assignment { - /// Assign an advice wire value (witness) + /// Assign an advice column value (witness) fn assign_advice( &mut self, - wire: AdviceWire, + column: AdviceColumn, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error>; @@ -32,18 +32,18 @@ pub trait Assignment { /// Assign a fixed value fn assign_fixed( &mut self, - wire: FixedWire, + column: FixedColumn, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error>; - /// Assign two advice wires to have the same value + /// Assign two advice columns to have the same value fn copy( &mut self, permutation: usize, - left_wire: usize, + left_column: usize, left_row: usize, - right_wire: usize, + right_column: usize, right_row: usize, ) -> Result<(), Error>; } @@ -52,11 +52,11 @@ pub trait Assignment { /// backend prover can ask the circuit to synthesize using some given /// [`ConstraintSystem`] implementation. pub trait Circuit { - /// This is a configuration object that stores things like wires. + /// This is a configuration object that stores things like columns. type Config; /// The circuit is given an opportunity to describe the exact gate - /// arrangement, wire arrangement, etc. + /// arrangement, column arrangement, etc. fn configure(meta: &mut ConstraintSystem) -> Self::Config; /// Given the provided `cs`, synthesize the circuit. The concrete type of @@ -65,14 +65,14 @@ pub trait Circuit { fn synthesize(&self, cs: &mut impl Assignment, config: Self::Config) -> Result<(), Error>; } -/// Low-degree expression representing an identity that must hold over the committed wires. +/// Low-degree expression representing an identity that must hold over the committed columns. #[derive(Clone, Debug)] pub enum Expression { - /// This is a fixed wire queried at a certain relative location + /// This is a fixed column queried at a certain relative location Fixed(usize), - /// This is an advice (witness) wire queried at a certain relative location + /// This is an advice (witness) column queried at a certain relative location Advice(usize), - /// This is an auxiliary (external) wire queried at a certain relative location + /// This is an auxiliary (external) column queried at a certain relative location Aux(usize), /// This is the sum of two polynomials Sum(Box>, Box>), @@ -87,29 +87,64 @@ impl Expression { /// operations. pub fn evaluate( &self, - fixed_wire: &impl Fn(usize) -> T, - advice_wire: &impl Fn(usize) -> T, - aux_wire: &impl Fn(usize) -> T, + fixed_column: &impl Fn(usize) -> T, + advice_column: &impl Fn(usize) -> T, + aux_column: &impl Fn(usize) -> T, sum: &impl Fn(T, T) -> T, product: &impl Fn(T, T) -> T, scaled: &impl Fn(T, F) -> T, ) -> T { match self { - Expression::Fixed(index) => fixed_wire(*index), - Expression::Advice(index) => advice_wire(*index), - Expression::Aux(index) => aux_wire(*index), + Expression::Fixed(index) => fixed_column(*index), + Expression::Advice(index) => advice_column(*index), + Expression::Aux(index) => aux_column(*index), Expression::Sum(a, b) => { - let a = a.evaluate(fixed_wire, advice_wire, aux_wire, sum, product, scaled); - let b = b.evaluate(fixed_wire, advice_wire, aux_wire, sum, product, scaled); + let a = a.evaluate( + fixed_column, + advice_column, + aux_column, + sum, + product, + scaled, + ); + let b = b.evaluate( + fixed_column, + advice_column, + aux_column, + sum, + product, + scaled, + ); sum(a, b) } Expression::Product(a, b) => { - let a = a.evaluate(fixed_wire, advice_wire, aux_wire, sum, product, scaled); - let b = b.evaluate(fixed_wire, advice_wire, aux_wire, sum, product, scaled); + let a = a.evaluate( + fixed_column, + advice_column, + aux_column, + sum, + product, + scaled, + ); + let b = b.evaluate( + fixed_column, + advice_column, + aux_column, + sum, + product, + scaled, + ); product(a, b) } Expression::Scaled(a, f) => { - let a = a.evaluate(fixed_wire, advice_wire, aux_wire, sum, product, scaled); + let a = a.evaluate( + fixed_column, + advice_column, + aux_column, + sum, + product, + scaled, + ); scaled(a, *f) } } @@ -154,24 +189,24 @@ impl Mul for Expression { #[derive(Copy, Clone, Debug)] pub(crate) struct PointIndex(pub usize); -/// This is a description of the circuit environment, such as the gate, wire and +/// This is a description of the circuit environment, such as the gate, column and /// permutation arrangements. #[derive(Debug, Clone)] pub struct ConstraintSystem { - pub(crate) num_fixed_wires: usize, - pub(crate) num_advice_wires: usize, - pub(crate) num_aux_wires: usize, + pub(crate) num_fixed_columns: usize, + pub(crate) num_advice_columns: usize, + pub(crate) num_aux_columns: usize, pub(crate) gates: Vec>, - pub(crate) advice_queries: Vec<(AdviceWire, Rotation)>, - pub(crate) aux_queries: Vec<(AuxWire, Rotation)>, - pub(crate) fixed_queries: Vec<(FixedWire, Rotation)>, + pub(crate) advice_queries: Vec<(AdviceColumn, Rotation)>, + pub(crate) aux_queries: Vec<(AuxColumn, Rotation)>, + pub(crate) fixed_queries: Vec<(FixedColumn, Rotation)>, // Mapping from a witness vector rotation to the index in the point vector. pub(crate) rotations: BTreeMap, - // Vector of permutation arguments, where each corresponds to a set of wires + // Vector of permutation arguments, where each corresponds to a set of columns // that are involved in a permutation argument. - pub(crate) permutations: Vec>, + pub(crate) permutations: Vec>, } impl Default for ConstraintSystem { @@ -180,9 +215,9 @@ impl Default for ConstraintSystem { rotations.insert(Rotation::default(), PointIndex(0)); ConstraintSystem { - num_fixed_wires: 0, - num_advice_wires: 0, - num_aux_wires: 0, + num_fixed_columns: 0, + num_advice_columns: 0, + num_aux_columns: 0, gates: vec![], fixed_queries: Vec::new(), advice_queries: Vec::new(), @@ -194,8 +229,8 @@ impl Default for ConstraintSystem { } impl ConstraintSystem { - /// Add a permutation argument for some advice wires - pub fn permutation(&mut self, wires: &[AdviceWire]) -> usize { + /// Add a permutation argument for some advice columns + pub fn permutation(&mut self, columns: &[AdviceColumn]) -> usize { let index = self.permutations.len(); if self.permutations.is_empty() { let at = Rotation(-1); @@ -203,15 +238,15 @@ impl ConstraintSystem { self.rotations.entry(at).or_insert(PointIndex(len)); } - for wire in wires { - self.query_advice_index(*wire, 0); + for column in columns { + self.query_advice_index(*column, 0); } - self.permutations.push(wires.to_vec()); + self.permutations.push(columns.to_vec()); index } - fn query_fixed_index(&mut self, wire: FixedWire, at: i32) -> usize { + fn query_fixed_index(&mut self, column: FixedColumn, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -220,27 +255,27 @@ impl ConstraintSystem { // Return existing query, if it exists for (index, fixed_query) in self.fixed_queries.iter().enumerate() { - if fixed_query == &(wire, at) { + if fixed_query == &(column, at) { return index; } } // Make a new query let index = self.fixed_queries.len(); - self.fixed_queries.push((wire, at)); + self.fixed_queries.push((column, at)); index } - /// Query a fixed wire at a relative position - pub fn query_fixed(&mut self, wire: FixedWire, at: i32) -> Expression { - Expression::Fixed(self.query_fixed_index(wire, at)) + /// Query a fixed column at a relative position + pub fn query_fixed(&mut self, column: FixedColumn, at: i32) -> Expression { + Expression::Fixed(self.query_fixed_index(column, at)) } - pub(crate) fn get_advice_query_index(&self, wire: AdviceWire, at: i32) -> usize { + pub(crate) fn get_advice_query_index(&self, column: AdviceColumn, at: i32) -> usize { let at = Rotation(at); for (index, advice_query) in self.advice_queries.iter().enumerate() { - if advice_query == &(wire, at) { + if advice_query == &(column, at) { return index; } } @@ -248,7 +283,7 @@ impl ConstraintSystem { panic!("get_advice_query_index called for non-existant query"); } - pub(crate) fn query_advice_index(&mut self, wire: AdviceWire, at: i32) -> usize { + pub(crate) fn query_advice_index(&mut self, column: AdviceColumn, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -257,24 +292,24 @@ impl ConstraintSystem { // Return existing query, if it exists for (index, advice_query) in self.advice_queries.iter().enumerate() { - if advice_query == &(wire, at) { + if advice_query == &(column, at) { return index; } } // Make a new query let index = self.advice_queries.len(); - self.advice_queries.push((wire, at)); + self.advice_queries.push((column, at)); index } - /// Query an advice wire at a relative position - pub fn query_advice(&mut self, wire: AdviceWire, at: i32) -> Expression { - Expression::Advice(self.query_advice_index(wire, at)) + /// Query an advice column at a relative position + pub fn query_advice(&mut self, column: AdviceColumn, at: i32) -> Expression { + Expression::Advice(self.query_advice_index(column, at)) } - fn query_aux_index(&mut self, wire: AuxWire, at: i32) -> usize { + fn query_aux_index(&mut self, column: AuxColumn, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -283,21 +318,21 @@ impl ConstraintSystem { // Return existing query, if it exists for (index, aux_query) in self.aux_queries.iter().enumerate() { - if aux_query == &(wire, at) { + if aux_query == &(column, at) { return index; } } // Make a new query let index = self.aux_queries.len(); - self.aux_queries.push((wire, at)); + self.aux_queries.push((column, at)); index } - /// Query an auxiliary wire at a relative position - pub fn query_aux(&mut self, wire: AuxWire, at: i32) -> Expression { - Expression::Aux(self.query_aux_index(wire, at)) + /// Query an auxiliary column at a relative position + pub fn query_aux(&mut self, column: AuxColumn, at: i32) -> Expression { + Expression::Aux(self.query_aux_index(column, at)) } /// Create a new gate @@ -306,24 +341,24 @@ impl ConstraintSystem { self.gates.push(poly); } - /// Allocate a new fixed wire - pub fn fixed_wire(&mut self) -> FixedWire { - let tmp = FixedWire(self.num_fixed_wires); - self.num_fixed_wires += 1; + /// Allocate a new fixed column + pub fn fixed_column(&mut self) -> FixedColumn { + let tmp = FixedColumn(self.num_fixed_columns); + self.num_fixed_columns += 1; tmp } - /// Allocate a new advice wire - pub fn advice_wire(&mut self) -> AdviceWire { - let tmp = AdviceWire(self.num_advice_wires); - self.num_advice_wires += 1; + /// Allocate a new advice column + pub fn advice_column(&mut self) -> AdviceColumn { + let tmp = AdviceColumn(self.num_advice_columns); + self.num_advice_columns += 1; tmp } - /// Allocate a new auxiliary wire - pub fn aux_wire(&mut self) -> AuxWire { - let tmp = AuxWire(self.num_aux_wires); - self.num_aux_wires += 1; + /// Allocate a new auxiliary column + pub fn aux_column(&mut self) -> AuxColumn { + let tmp = AuxColumn(self.num_aux_columns); + self.num_aux_columns += 1; tmp } } diff --git a/src/plonk/keygen.rs b/src/plonk/keygen.rs index d776920e..9a0f0298 100644 --- a/src/plonk/keygen.rs +++ b/src/plonk/keygen.rs @@ -1,5 +1,5 @@ use super::{ - circuit::{AdviceWire, Assignment, Circuit, ConstraintSystem, FixedWire}, + circuit::{AdviceColumn, Assignment, Circuit, ConstraintSystem, FixedColumn}, Error, ProvingKey, VerifyingKey, }; use crate::arithmetic::{Curve, CurveAffine, Field}; @@ -28,23 +28,23 @@ where impl Assignment for Assembly { fn assign_advice( &mut self, - _: AdviceWire, + _: AdviceColumn, _: usize, _: impl FnOnce() -> Result, ) -> Result<(), Error> { - // We only care about fixed wires here + // We only care about fixed columns here Ok(()) } fn assign_fixed( &mut self, - wire: FixedWire, + column: FixedColumn, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error> { *self .fixed - .get_mut(wire.0) + .get_mut(column.0) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -54,23 +54,23 @@ where fn copy( &mut self, permutation: usize, - left_wire: usize, + left_column: usize, left_row: usize, - right_wire: usize, + right_column: usize, right_row: usize, ) -> Result<(), Error> { // Check bounds first if permutation >= self.mapping.len() - || left_wire >= self.mapping[permutation].len() - || left_row >= self.mapping[permutation][left_wire].len() - || right_wire >= self.mapping[permutation].len() - || right_row >= self.mapping[permutation][right_wire].len() + || left_column >= self.mapping[permutation].len() + || left_row >= self.mapping[permutation][left_column].len() + || right_column >= self.mapping[permutation].len() + || right_row >= self.mapping[permutation][right_column].len() { return Err(Error::BoundsFailure); } - let mut left_cycle = self.aux[permutation][left_wire][left_row]; - let mut right_cycle = self.aux[permutation][right_wire][right_row]; + let mut left_cycle = self.aux[permutation][left_column][left_row]; + let mut right_cycle = self.aux[permutation][right_column][right_row]; if left_cycle == right_cycle { return Ok(()); @@ -93,10 +93,10 @@ where } } - let tmp = self.mapping[permutation][left_wire][left_row]; - self.mapping[permutation][left_wire][left_row] = - self.mapping[permutation][right_wire][right_row]; - self.mapping[permutation][right_wire][right_row] = tmp; + let tmp = self.mapping[permutation][left_column][left_row]; + self.mapping[permutation][left_column][left_row] = + self.mapping[permutation][right_column][right_row]; + self.mapping[permutation][right_column][right_row] = tmp; Ok(()) } @@ -106,7 +106,7 @@ where let config = ConcreteCircuit::configure(&mut cs); // Get the largest permutation argument length in terms of the number of - // advice wires involved. + // advice columns involved. let mut largest_permutation_length = 0; for permutation in &cs.permutations { largest_permutation_length = std::cmp::max(permutation.len(), largest_permutation_length); @@ -151,7 +151,7 @@ where } let mut assembly: Assembly = Assembly { - fixed: vec![domain.empty_lagrange(); cs.num_fixed_wires], + fixed: vec![domain.empty_lagrange(); cs.num_fixed_columns], mapping: vec![], aux: vec![], sizes: vec![], @@ -161,13 +161,13 @@ where // Initialize the copy vector to keep track of copy constraints in all // the permutation arguments. for permutation in &cs.permutations { - let mut wires = vec![]; + let mut columns = vec![]; for i in 0..permutation.len() { // Computes [(i, 0), (i, 1), ..., (i, n - 1)] - wires.push((0..params.n).map(|j| (i, j as usize)).collect()); + columns.push((0..params.n).map(|j| (i, j as usize)).collect()); } - assembly.mapping.push(wires.clone()); - assembly.aux.push(wires); + assembly.mapping.push(columns.clone()); + assembly.aux.push(columns); assembly .sizes .push(vec![vec![1usize; params.n as usize]; permutation.len()]); @@ -229,8 +229,8 @@ where let fixed_cosets = cs .fixed_queries .iter() - .map(|&(wire, at)| { - let poly = fixed_polys[wire.0].clone(); + .map(|&(column, at)| { + let poly = fixed_polys[column.0].clone(); domain.coeff_to_extended(poly, at) }) .collect(); diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 10c3fe4e..3aa5af91 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -1,5 +1,5 @@ use super::{ - circuit::{AdviceWire, Assignment, Circuit, ConstraintSystem, FixedWire}, + circuit::{AdviceColumn, Assignment, Circuit, ConstraintSystem, FixedColumn}, hash_point, Error, Proof, ProvingKey, }; use crate::arithmetic::{ @@ -27,7 +27,7 @@ impl Proof { circuit: &ConcreteCircuit, aux: &[Polynomial], ) -> Result { - if aux.len() != pk.vk.cs.num_aux_wires { + if aux.len() != pk.vk.cs.num_aux_columns { return Err(Error::IncompatibleParams); } @@ -39,13 +39,13 @@ impl Proof { impl Assignment for WitnessCollection { fn assign_advice( &mut self, - wire: AdviceWire, + column: AdviceColumn, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error> { *self .advice - .get_mut(wire.0) + .get_mut(column.0) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -54,11 +54,11 @@ impl Proof { fn assign_fixed( &mut self, - _: FixedWire, + _: FixedColumn, _: usize, _: impl FnOnce() -> Result, ) -> Result<(), Error> { - // We only care about advice wires here + // We only care about advice columns here Ok(()) } @@ -71,7 +71,7 @@ impl Proof { _: usize, _: usize, ) -> Result<(), Error> { - // We only care about advice wires here + // We only care about advice columns here Ok(()) } @@ -82,7 +82,7 @@ impl Proof { let config = ConcreteCircuit::configure(&mut meta); let mut witness = WitnessCollection { - advice: vec![domain.empty_lagrange(); meta.num_advice_wires], + advice: vec![domain.empty_lagrange(); meta.num_advice_columns], _marker: std::marker::PhantomData, }; @@ -94,7 +94,7 @@ impl Proof { // Create a transcript for obtaining Fiat-Shamir challenges. let mut transcript = HBase::init(C::Base::one()); - // Compute commitments to aux wire polynomials + // Compute commitments to aux column polynomials let aux_commitments_projective: Vec<_> = aux .iter() .map(|poly| params.commit_lagrange(poly, Blind::default())) @@ -119,13 +119,13 @@ impl Proof { let aux_cosets: Vec<_> = meta .aux_queries .iter() - .map(|&(wire, at)| { - let poly = aux_polys[wire.0].clone(); + .map(|&(column, at)| { + let poly = aux_polys[column.0].clone(); domain.coeff_to_extended(poly, at) }) .collect(); - // Compute commitments to advice wire polynomials + // Compute commitments to advice column polynomials let advice_blinds: Vec<_> = witness .advice .iter() @@ -156,8 +156,8 @@ impl Proof { let advice_cosets: Vec<_> = meta .advice_queries .iter() - .map(|&(wire, at)| { - let poly = advice_polys[wire.0].clone(); + .map(|&(column, at)| { + let poly = advice_polys[column.0].clone(); domain.coeff_to_extended(poly, at) }) .collect(); @@ -177,23 +177,23 @@ impl Proof { // Iterate over each permutation let mut permutation_modified_advice = vec![]; - for (wires, permuted_values) in pk.vk.cs.permutations.iter().zip(pk.permutations.iter()) { + for (columns, permuted_values) in pk.vk.cs.permutations.iter().zip(pk.permutations.iter()) { // Goal is to compute the products of fractions // // (p_j(\omega^i) + \delta^j \omega^i \beta + \gamma) / // (p_j(\omega^i) + \beta s_j(\omega^i) + \gamma) // - // where p_j(X) is the jth advice wire in this permutation, - // and i is the ith row of the wire. + // where p_j(X) is the jth advice column in this permutation, + // and i is the ith row of the column. let mut modified_advice = vec![C::Scalar::one(); params.n as usize]; - // Iterate over each wire of the permutation - for (&wire, permuted_wire_values) in wires.iter().zip(permuted_values.iter()) { + // Iterate over each column of the permutation + for (&column, permuted_column_values) in columns.iter().zip(permuted_values.iter()) { parallelize(&mut modified_advice, |modified_advice, start| { for ((modified_advice, advice_value), permuted_advice_value) in modified_advice .iter_mut() - .zip(witness.advice[wire.0][start..].iter()) - .zip(permuted_wire_values[start..].iter()) + .zip(witness.advice[column.0][start..].iter()) + .zip(permuted_column_values[start..].iter()) { *modified_advice *= &(x_0 * permuted_advice_value + &x_1 + advice_value); } @@ -210,23 +210,23 @@ impl Proof { .flat_map(|v| v.iter_mut()) .batch_invert(); - for (wires, mut modified_advice) in pk + for (columns, mut modified_advice) in pk .vk .cs .permutations .iter() .zip(permutation_modified_advice.into_iter()) { - // Iterate over each wire again, this time finishing the computation + // Iterate over each column again, this time finishing the computation // of the entire fraction by computing the numerators let mut deltaomega = C::Scalar::one(); - for &wire in wires.iter() { + for &column in columns.iter() { let omega = domain.get_omega(); parallelize(&mut modified_advice, |modified_advice, start| { let mut deltaomega = deltaomega * &omega.pow_vartime(&[start as u64, 0, 0, 0]); for (modified_advice, advice_value) in modified_advice .iter_mut() - .zip(witness.advice[wire.0][start..].iter()) + .zip(witness.advice[column.0][start..].iter()) { // Multiply by p_j(\omega^i) + \delta^j \omega^i \beta *modified_advice *= &(deltaomega * &x_0 + &x_1 + advice_value); @@ -242,7 +242,7 @@ impl Proof { // (p_j(\omega^i) + \delta^j \omega^i \beta + \gamma) / // (p_j(\omega^i) + \beta s_j(\omega^i) + \gamma) // - // where i is the index into modified_advice, for the jth wire in + // where i is the index into modified_advice, for the jth column in // the permutation // Compute the evaluations of the permutation product polynomial @@ -315,13 +315,13 @@ impl Proof { } // z(X) \prod (p(X) + \beta s_i(X) + \gamma) - z(omega^{-1} X) \prod (p(X) + \delta^i \beta X + \gamma) - for (permutation_index, wires) in pk.vk.cs.permutations.iter().enumerate() { + for (permutation_index, columns) in pk.vk.cs.permutations.iter().enumerate() { h_poly = h_poly * x_2; let mut left = permutation_product_cosets[permutation_index].clone(); - for (advice, permutation) in wires + for (advice, permutation) in columns .iter() - .map(|&wire| &advice_cosets[pk.vk.cs.get_advice_query_index(wire, 0)]) + .map(|&column| &advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]) .zip(pk.permutation_cosets[permutation_index].iter()) { parallelize(&mut left, |left, start| { @@ -338,9 +338,9 @@ impl Proof { let mut right = permutation_product_cosets_inv[permutation_index].clone(); let mut current_delta = x_0 * &C::Scalar::ZETA; let step = domain.get_extended_omega(); - for advice in wires + for advice in columns .iter() - .map(|&wire| &advice_cosets[pk.vk.cs.get_advice_query_index(wire, 0)]) + .map(|&column| &advice_cosets[pk.vk.cs.get_advice_query_index(column, 0)]) { parallelize(&mut right, move |right, start| { let mut beta_term = current_delta * &step.pow_vartime(&[start as u64, 0, 0, 0]); @@ -394,20 +394,24 @@ impl Proof { let advice_evals: Vec<_> = meta .advice_queries .iter() - .map(|&(wire, at)| eval_polynomial(&advice_polys[wire.0], domain.rotate_omega(x_3, at))) + .map(|&(column, at)| { + eval_polynomial(&advice_polys[column.0], domain.rotate_omega(x_3, at)) + }) .collect(); let aux_evals: Vec<_> = meta .aux_queries .iter() - .map(|&(wire, at)| eval_polynomial(&aux_polys[wire.0], domain.rotate_omega(x_3, at))) + .map(|&(column, at)| { + eval_polynomial(&aux_polys[column.0], domain.rotate_omega(x_3, at)) + }) .collect(); let fixed_evals: Vec<_> = meta .fixed_queries .iter() - .map(|&(wire, at)| { - eval_polynomial(&pk.fixed_polys[wire.0], domain.rotate_omega(x_3, at)) + .map(|&(column, at)| { + eval_polynomial(&pk.fixed_polys[column.0], domain.rotate_omega(x_3, at)) }) .collect(); @@ -460,34 +464,34 @@ impl Proof { let mut instances: Vec> = Vec::new(); - for (query_index, &(wire, at)) in pk.vk.cs.advice_queries.iter().enumerate() { + for (query_index, &(column, at)) in pk.vk.cs.advice_queries.iter().enumerate() { let point = domain.rotate_omega(x_3, at); instances.push(ProverQuery { point, - poly: &advice_polys[wire.0], - blind: advice_blinds[wire.0], + poly: &advice_polys[column.0], + blind: advice_blinds[column.0], eval: advice_evals[query_index], }); } - for (query_index, &(wire, at)) in pk.vk.cs.aux_queries.iter().enumerate() { + for (query_index, &(column, at)) in pk.vk.cs.aux_queries.iter().enumerate() { let point = domain.rotate_omega(x_3, at); instances.push(ProverQuery { point, - poly: &aux_polys[wire.0], + poly: &aux_polys[column.0], blind: Blind::default(), eval: aux_evals[query_index], }); } - for (query_index, &(wire, at)) in pk.vk.cs.fixed_queries.iter().enumerate() { + for (query_index, &(column, at)) in pk.vk.cs.fixed_queries.iter().enumerate() { let point = domain.rotate_omega(x_3, at); instances.push(ProverQuery { point, - poly: &pk.fixed_polys[wire.0], + poly: &pk.fixed_polys[column.0], blind: Blind::default(), eval: fixed_evals[query_index], }); diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 2046140f..855c6da1 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -18,10 +18,10 @@ impl<'a, C: CurveAffine> Proof { ) -> Result, Error> { self.check_lengths(vk, aux_commitments)?; - // Check that aux_commitments matches the expected number of aux_wires + // Check that aux_commitments matches the expected number of aux_columns // and self.aux_evals - if aux_commitments.len() != vk.cs.num_aux_wires - || self.aux_evals.len() != vk.cs.num_aux_wires + if aux_commitments.len() != vk.cs.num_aux_columns + || self.aux_evals.len() != vk.cs.num_aux_columns { return Err(Error::IncompatibleParams); } @@ -89,29 +89,29 @@ impl<'a, C: CurveAffine> Proof { let mut queries: Vec> = Vec::new(); - for (query_index, &(wire, at)) in vk.cs.advice_queries.iter().enumerate() { + for (query_index, &(column, at)) in vk.cs.advice_queries.iter().enumerate() { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &self.advice_commitments[wire.0], + commitment: &self.advice_commitments[column.0], eval: self.advice_evals[query_index], }); } - for (query_index, &(wire, at)) in vk.cs.aux_queries.iter().enumerate() { + for (query_index, &(column, at)) in vk.cs.aux_queries.iter().enumerate() { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &aux_commitments[wire.0], + commitment: &aux_commitments[column.0], eval: self.aux_evals[query_index], }); } - for (query_index, &(wire, at)) in vk.cs.fixed_queries.iter().enumerate() { + for (query_index, &(column, at)) in vk.cs.fixed_queries.iter().enumerate() { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &vk.fixed_commitments[wire.0], + commitment: &vk.fixed_commitments[column.0], eval: self.fixed_evals[query_index], }); } @@ -193,10 +193,10 @@ impl<'a, C: CurveAffine> Proof { /// Checks that the lengths of vectors are consistent with the constraint /// system fn check_lengths(&self, vk: &VerifyingKey, aux_commitments: &[C]) -> Result<(), Error> { - // Check that aux_commitments matches the expected number of aux_wires + // Check that aux_commitments matches the expected number of aux_columns // and self.aux_evals - if aux_commitments.len() != vk.cs.num_aux_wires - || self.aux_evals.len() != vk.cs.num_aux_wires + if aux_commitments.len() != vk.cs.num_aux_columns + || self.aux_evals.len() != vk.cs.num_aux_columns { return Err(Error::IncompatibleParams); } @@ -237,7 +237,7 @@ impl<'a, C: CurveAffine> Proof { // TODO: check h_commitments - if self.advice_commitments.len() != vk.cs.num_advice_wires { + if self.advice_commitments.len() != vk.cs.num_advice_columns { return Err(Error::IncompatibleParams); } @@ -293,12 +293,12 @@ impl<'a, C: CurveAffine> Proof { .zip(self.permutation_product_evals.iter()) .zip(self.permutation_product_inv_evals.iter()) .map( - |(((wires, permutation_evals), product_eval), product_inv_eval)| { + |(((columns, permutation_evals), product_eval), product_inv_eval)| { let mut left = *product_eval; - for (advice_eval, permutation_eval) in wires + for (advice_eval, permutation_eval) in columns .iter() - .map(|&wire| { - self.advice_evals[vk.cs.get_advice_query_index(wire, 0)] + .map(|&column| { + self.advice_evals[vk.cs.get_advice_query_index(column, 0)] }) .zip(permutation_evals.iter()) { @@ -307,8 +307,8 @@ impl<'a, C: CurveAffine> Proof { let mut right = *product_inv_eval; let mut current_delta = x_0 * &x_3; - for advice_eval in wires.iter().map(|&wire| { - self.advice_evals[vk.cs.get_advice_query_index(wire, 0)] + for advice_eval in columns.iter().map(|&column| { + self.advice_evals[vk.cs.get_advice_query_index(column, 0)] }) { right *= &(advice_eval + ¤t_delta + &x_1); current_delta *= &C::Scalar::DELTA; From 075988ae4e80c9113eec1248aae992969d7b5ce7 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Fri, 6 Nov 2020 11:25:50 +0800 Subject: [PATCH 2/8] Introduce Column struct and ColumnType trait --- src/plonk.rs | 23 +++--- src/plonk/circuit.rs | 180 ++++++++++++++++++++++++++++++++---------- src/plonk/keygen.rs | 10 +-- src/plonk/prover.rs | 30 +++---- src/plonk/verifier.rs | 6 +- 5 files changed, 175 insertions(+), 74 deletions(-) diff --git a/src/plonk.rs b/src/plonk.rs index 6200dcc9..6a457d4f 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -114,28 +114,29 @@ fn test_proving() { use crate::arithmetic::{Curve, EqAffine, Field, Fp, Fq}; use crate::poly::commitment::{Blind, Params}; use crate::transcript::DummyHash; + use circuit::{Advice, Column, Fixed}; use std::marker::PhantomData; const K: u32 = 5; /// This represents an advice column at a certain row in the ConstraintSystem #[derive(Copy, Clone, Debug)] - pub struct Variable(AdviceColumn, usize); + pub struct Variable(Column, usize); // Initialize the polynomial commitment parameters let params: Params = Params::new::>(K); struct PLONKConfig { - a: AdviceColumn, - b: AdviceColumn, - c: AdviceColumn, - d: AdviceColumn, - e: AdviceColumn, + a: Column, + b: Column, + c: Column, + d: Column, + e: Column, - sa: FixedColumn, - sb: FixedColumn, - sc: FixedColumn, - sm: FixedColumn, - sp: FixedColumn, + sa: Column, + sb: Column, + sc: Column, + sm: Column, + sp: Column, perm: usize, perm2: usize, diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index c17d4bb4..793e6d7f 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -4,19 +4,99 @@ use std::collections::BTreeMap; use super::Error; use crate::arithmetic::Field; - use crate::poly::Rotation; -/// This represents a column which has a fixed (permanent) value -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct FixedColumn(pub usize); -/// This represents a column which has a witness-specific value -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct AdviceColumn(pub usize); +/// A column type +pub trait ColumnType: 'static + Sized {} -/// This represents a column which has an externally assigned value -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct AuxColumn(pub usize); +/// A column with an index and type +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Column { + pub(crate) index: usize, + pub(crate) column_type: C, +} + +/// An advice column +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Advice; + +/// A fixed column +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Fixed; + +/// An auxiliary column +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Aux; + +/// An enum over the Advice, Fixed, Aux structs +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Any { + /// An Advice variant + Advice, + /// A Fixed variant + Fixed, + /// An Auxiliary variant + Aux, +} + +impl ColumnType for Advice {} +impl ColumnType for Fixed {} +impl ColumnType for Aux {} +impl ColumnType for Any {} + +impl From> for Column { + fn from(advice: Column) -> Column { + Column { + index: advice.index, + column_type: Any::Advice, + } + } +} + +impl From> for Column { + fn from(advice: Column) -> Column { + Column { + index: advice.index, + column_type: Any::Fixed, + } + } +} + +impl From> for Column { + fn from(advice: Column) -> Column { + Column { + index: advice.index, + column_type: Any::Aux, + } + } +} + +impl From> for Column { + fn from(any: Column) -> Column { + Column { + index: any.index, + column_type: Advice, + } + } +} + +impl From> for Column { + fn from(any: Column) -> Column { + Column { + index: any.index, + column_type: Fixed, + } + } +} + +impl From> for Column { + fn from(any: Column) -> Column { + Column { + index: any.index, + column_type: Aux, + } + } +} /// This trait allows a [`Circuit`] to direct some backend to assign a witness /// for a constraint system. @@ -24,7 +104,7 @@ pub trait Assignment { /// Assign an advice column value (witness) fn assign_advice( &mut self, - column: AdviceColumn, + column: Column, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error>; @@ -32,7 +112,7 @@ pub trait Assignment { /// Assign a fixed value fn assign_fixed( &mut self, - column: FixedColumn, + column: Column, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error>; @@ -197,16 +277,16 @@ pub struct ConstraintSystem { pub(crate) num_advice_columns: usize, pub(crate) num_aux_columns: usize, pub(crate) gates: Vec>, - pub(crate) advice_queries: Vec<(AdviceColumn, Rotation)>, - pub(crate) aux_queries: Vec<(AuxColumn, Rotation)>, - pub(crate) fixed_queries: Vec<(FixedColumn, Rotation)>, + pub(crate) advice_queries: Vec<(Column, Rotation)>, + pub(crate) aux_queries: Vec<(Column, Rotation)>, + pub(crate) fixed_queries: Vec<(Column, Rotation)>, // Mapping from a witness vector rotation to the index in the point vector. pub(crate) rotations: BTreeMap, // Vector of permutation arguments, where each corresponds to a set of columns // that are involved in a permutation argument. - pub(crate) permutations: Vec>, + pub(crate) permutations: Vec>>, } impl Default for ConstraintSystem { @@ -230,7 +310,7 @@ impl Default for ConstraintSystem { impl ConstraintSystem { /// Add a permutation argument for some advice columns - pub fn permutation(&mut self, columns: &[AdviceColumn]) -> usize { + pub fn permutation(&mut self, columns: &[Column]) -> usize { let index = self.permutations.len(); if self.permutations.is_empty() { let at = Rotation(-1); @@ -246,7 +326,7 @@ impl ConstraintSystem { index } - fn query_fixed_index(&mut self, column: FixedColumn, at: i32) -> usize { + fn query_fixed_index(&mut self, column: Column, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -268,22 +348,11 @@ impl ConstraintSystem { } /// Query a fixed column at a relative position - pub fn query_fixed(&mut self, column: FixedColumn, at: i32) -> Expression { + pub fn query_fixed(&mut self, column: Column, at: i32) -> Expression { Expression::Fixed(self.query_fixed_index(column, at)) } - pub(crate) fn get_advice_query_index(&self, column: AdviceColumn, at: i32) -> usize { - let at = Rotation(at); - for (index, advice_query) in self.advice_queries.iter().enumerate() { - if advice_query == &(column, at) { - return index; - } - } - - panic!("get_advice_query_index called for non-existant query"); - } - - pub(crate) fn query_advice_index(&mut self, column: AdviceColumn, at: i32) -> usize { + pub(crate) fn query_advice_index(&mut self, column: Column, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -305,11 +374,11 @@ impl ConstraintSystem { } /// Query an advice column at a relative position - pub fn query_advice(&mut self, column: AdviceColumn, at: i32) -> Expression { + pub fn query_advice(&mut self, column: Column, at: i32) -> Expression { Expression::Advice(self.query_advice_index(column, at)) } - fn query_aux_index(&mut self, column: AuxColumn, at: i32) -> usize { + fn query_aux_index(&mut self, column: Column, at: i32) -> usize { let at = Rotation(at); { let len = self.rotations.len(); @@ -331,10 +400,32 @@ impl ConstraintSystem { } /// Query an auxiliary column at a relative position - pub fn query_aux(&mut self, column: AuxColumn, at: i32) -> Expression { + pub fn query_aux(&mut self, column: Column, at: i32) -> Expression { Expression::Aux(self.query_aux_index(column, at)) } + pub(crate) fn get_advice_query_index(&self, column: Column, at: i32) -> usize { + let at = Rotation(at); + for (index, advice_query) in self.advice_queries.iter().enumerate() { + if advice_query == &(column, at) { + return index; + } + } + + panic!("get_advice_query_index called for non-existant query"); + } + + pub(crate) fn get_fixed_query_index(&self, column: Column, at: i32) -> usize { + let at = Rotation(at); + for (index, fixed_query) in self.fixed_queries.iter().enumerate() { + if fixed_query == &(column, at) { + return index; + } + } + + panic!("get_fixed_query_index called for non-existent query"); + } + /// Create a new gate pub fn create_gate(&mut self, f: impl FnOnce(&mut Self) -> Expression) { let poly = f(self); @@ -342,22 +433,31 @@ impl ConstraintSystem { } /// Allocate a new fixed column - pub fn fixed_column(&mut self) -> FixedColumn { - let tmp = FixedColumn(self.num_fixed_columns); + pub fn fixed_column(&mut self) -> Column { + let tmp = Column { + index: self.num_fixed_columns, + column_type: Fixed, + }; self.num_fixed_columns += 1; tmp } /// Allocate a new advice column - pub fn advice_column(&mut self) -> AdviceColumn { - let tmp = AdviceColumn(self.num_advice_columns); + pub fn advice_column(&mut self) -> Column { + let tmp = Column { + index: self.num_advice_columns, + column_type: Advice, + }; self.num_advice_columns += 1; tmp } /// Allocate a new auxiliary column - pub fn aux_column(&mut self) -> AuxColumn { - let tmp = AuxColumn(self.num_aux_columns); + pub fn aux_column(&mut self) -> Column { + let tmp = Column { + index: self.num_aux_columns, + column_type: Aux, + }; self.num_aux_columns += 1; tmp } diff --git a/src/plonk/keygen.rs b/src/plonk/keygen.rs index 9a0f0298..13f29154 100644 --- a/src/plonk/keygen.rs +++ b/src/plonk/keygen.rs @@ -1,5 +1,5 @@ use super::{ - circuit::{AdviceColumn, Assignment, Circuit, ConstraintSystem, FixedColumn}, + circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed}, Error, ProvingKey, VerifyingKey, }; use crate::arithmetic::{Curve, CurveAffine, Field}; @@ -28,7 +28,7 @@ where impl Assignment for Assembly { fn assign_advice( &mut self, - _: AdviceColumn, + _: Column, _: usize, _: impl FnOnce() -> Result, ) -> Result<(), Error> { @@ -38,13 +38,13 @@ where fn assign_fixed( &mut self, - column: FixedColumn, + column: Column, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error> { *self .fixed - .get_mut(column.0) + .get_mut(column.index) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -230,7 +230,7 @@ where .fixed_queries .iter() .map(|&(column, at)| { - let poly = fixed_polys[column.0].clone(); + let poly = fixed_polys[column.index].clone(); domain.coeff_to_extended(poly, at) }) .collect(); diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 3aa5af91..507235a2 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -1,5 +1,5 @@ use super::{ - circuit::{AdviceColumn, Assignment, Circuit, ConstraintSystem, FixedColumn}, + circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed}, hash_point, Error, Proof, ProvingKey, }; use crate::arithmetic::{ @@ -39,13 +39,13 @@ impl Proof { impl Assignment for WitnessCollection { fn assign_advice( &mut self, - column: AdviceColumn, + column: Column, row: usize, to: impl FnOnce() -> Result, ) -> Result<(), Error> { *self .advice - .get_mut(column.0) + .get_mut(column.index) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -54,7 +54,7 @@ impl Proof { fn assign_fixed( &mut self, - _: FixedColumn, + _: Column, _: usize, _: impl FnOnce() -> Result, ) -> Result<(), Error> { @@ -120,7 +120,7 @@ impl Proof { .aux_queries .iter() .map(|&(column, at)| { - let poly = aux_polys[column.0].clone(); + let poly = aux_polys[column.index].clone(); domain.coeff_to_extended(poly, at) }) .collect(); @@ -157,7 +157,7 @@ impl Proof { .advice_queries .iter() .map(|&(column, at)| { - let poly = advice_polys[column.0].clone(); + let poly = advice_polys[column.index].clone(); domain.coeff_to_extended(poly, at) }) .collect(); @@ -192,7 +192,7 @@ impl Proof { parallelize(&mut modified_advice, |modified_advice, start| { for ((modified_advice, advice_value), permuted_advice_value) in modified_advice .iter_mut() - .zip(witness.advice[column.0][start..].iter()) + .zip(witness.advice[column.index][start..].iter()) .zip(permuted_column_values[start..].iter()) { *modified_advice *= &(x_0 * permuted_advice_value + &x_1 + advice_value); @@ -226,7 +226,7 @@ impl Proof { let mut deltaomega = deltaomega * &omega.pow_vartime(&[start as u64, 0, 0, 0]); for (modified_advice, advice_value) in modified_advice .iter_mut() - .zip(witness.advice[column.0][start..].iter()) + .zip(witness.advice[column.index][start..].iter()) { // Multiply by p_j(\omega^i) + \delta^j \omega^i \beta *modified_advice *= &(deltaomega * &x_0 + &x_1 + advice_value); @@ -395,7 +395,7 @@ impl Proof { .advice_queries .iter() .map(|&(column, at)| { - eval_polynomial(&advice_polys[column.0], domain.rotate_omega(x_3, at)) + eval_polynomial(&advice_polys[column.index], domain.rotate_omega(x_3, at)) }) .collect(); @@ -403,7 +403,7 @@ impl Proof { .aux_queries .iter() .map(|&(column, at)| { - eval_polynomial(&aux_polys[column.0], domain.rotate_omega(x_3, at)) + eval_polynomial(&aux_polys[column.index], domain.rotate_omega(x_3, at)) }) .collect(); @@ -411,7 +411,7 @@ impl Proof { .fixed_queries .iter() .map(|&(column, at)| { - eval_polynomial(&pk.fixed_polys[column.0], domain.rotate_omega(x_3, at)) + eval_polynomial(&pk.fixed_polys[column.index], domain.rotate_omega(x_3, at)) }) .collect(); @@ -469,8 +469,8 @@ impl Proof { instances.push(ProverQuery { point, - poly: &advice_polys[column.0], - blind: advice_blinds[column.0], + poly: &advice_polys[column.index], + blind: advice_blinds[column.index], eval: advice_evals[query_index], }); } @@ -480,7 +480,7 @@ impl Proof { instances.push(ProverQuery { point, - poly: &aux_polys[column.0], + poly: &aux_polys[column.index], blind: Blind::default(), eval: aux_evals[query_index], }); @@ -491,7 +491,7 @@ impl Proof { instances.push(ProverQuery { point, - poly: &pk.fixed_polys[column.0], + poly: &pk.fixed_polys[column.index], blind: Blind::default(), eval: fixed_evals[query_index], }); diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 855c6da1..5ff87455 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -93,7 +93,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &self.advice_commitments[column.0], + commitment: &self.advice_commitments[column.index], eval: self.advice_evals[query_index], }); } @@ -102,7 +102,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &aux_commitments[column.0], + commitment: &aux_commitments[column.index], eval: self.aux_evals[query_index], }); } @@ -111,7 +111,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &vk.fixed_commitments[column.0], + commitment: &vk.fixed_commitments[column.index], eval: self.fixed_evals[query_index], }); } From 34c6cba5375d08bd88d19ca1a268c9596e8510b2 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Fri, 6 Nov 2020 11:36:54 +0800 Subject: [PATCH 3/8] Add generic query_any_index() and get_any_query_index methods --- src/plonk/circuit.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 793e6d7f..17ecd6a9 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -399,6 +399,17 @@ impl ConstraintSystem { index } + /// Query an Any column at a relative position + fn query_any_index(&mut self, column: Column, at: i32) -> usize { + let index = match column.column_type { + Any::Advice => self.query_advice_index(Column::::from(column), at), + Any::Fixed => self.query_fixed_index(Column::::from(column), at), + Any::Aux => self.query_aux_index(Column::::from(column), at), + }; + + index + } + /// Query an auxiliary column at a relative position pub fn query_aux(&mut self, column: Column, at: i32) -> Expression { Expression::Aux(self.query_aux_index(column, at)) @@ -412,7 +423,7 @@ impl ConstraintSystem { } } - panic!("get_advice_query_index called for non-existant query"); + panic!("get_advice_query_index called for non-existent query"); } pub(crate) fn get_fixed_query_index(&self, column: Column, at: i32) -> usize { @@ -426,6 +437,27 @@ impl ConstraintSystem { panic!("get_fixed_query_index called for non-existent query"); } + pub(crate) fn get_aux_query_index(&self, column: Column, at: i32) -> usize { + let at = Rotation(at); + for (index, aux_query) in self.aux_queries.iter().enumerate() { + if aux_query == &(column, at) { + return index; + } + } + + panic!("get_aux_query_index called for non-existent query"); + } + + pub(crate) fn get_any_query_index(&self, column: Column, at: i32) -> usize { + let index = match column.column_type { + Any::Advice => self.get_advice_query_index(Column::::from(column), at), + Any::Fixed => self.get_fixed_query_index(Column::::from(column), at), + Any::Aux => self.get_aux_query_index(Column::::from(column), at), + }; + + index + } + /// Create a new gate pub fn create_gate(&mut self, f: impl FnOnce(&mut Self) -> Expression) { let poly = f(self); From 22b6d5bd704611beff941267c28906d457b9c2a9 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 7 Nov 2020 13:22:33 +0800 Subject: [PATCH 4/8] Cleanups in circuit.rs --- src/plonk/circuit.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 17ecd6a9..327c8e94 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -284,7 +284,7 @@ pub struct ConstraintSystem { // Mapping from a witness vector rotation to the index in the point vector. pub(crate) rotations: BTreeMap, - // Vector of permutation arguments, where each corresponds to a set of columns + // Vector of permutation arguments, where each corresponds to a sequence of columns // that are involved in a permutation argument. pub(crate) permutations: Vec>>, } @@ -399,7 +399,11 @@ impl ConstraintSystem { index } - /// Query an Any column at a relative position + /// Query an auxiliary column at a relative position + pub fn query_aux(&mut self, column: Column, at: i32) -> Expression { + Expression::Aux(self.query_aux_index(column, at)) + } + fn query_any_index(&mut self, column: Column, at: i32) -> usize { let index = match column.column_type { Any::Advice => self.query_advice_index(Column::::from(column), at), @@ -410,9 +414,17 @@ impl ConstraintSystem { index } - /// Query an auxiliary column at a relative position - pub fn query_aux(&mut self, column: Column, at: i32) -> Expression { - Expression::Aux(self.query_aux_index(column, at)) + /// Query an Any column at a relative position + pub fn query_any(&mut self, column: Column, at: i32) -> Expression { + match column.column_type { + Any::Advice => { + Expression::Advice(self.query_advice_index(Column::::from(column), at)) + } + Any::Fixed => { + Expression::Fixed(self.query_fixed_index(Column::::from(column), at)) + } + Any::Aux => Expression::Aux(self.query_aux_index(Column::::from(column), at)), + } } pub(crate) fn get_advice_query_index(&self, column: Column, at: i32) -> usize { From ad781356c2a8a1171374148fb6db71c969d0fb51 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 7 Nov 2020 13:22:52 +0800 Subject: [PATCH 5/8] Update authors in Cargo.toml --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 98a8483c..62f3d274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.1" authors = [ "Sean Bowe ", "Ying Tong Lai ", + "Daira Hopwood ", ] edition = "2018" description = """ From 0519a522aaecc7683f5d8e7a380a8fc71ca53b18 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Tue, 10 Nov 2020 00:39:08 +0800 Subject: [PATCH 6/8] Use TryFrom to convert Column to other column types --- src/plonk/circuit.rs | 82 +++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 327c8e94..2cbd59d9 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -1,6 +1,7 @@ use core::cmp::max; use core::ops::{Add, Mul}; use std::collections::BTreeMap; +use std::convert::TryFrom; use super::Error; use crate::arithmetic::Field; @@ -71,29 +72,50 @@ impl From> for Column { } } -impl From> for Column { - fn from(any: Column) -> Column { - Column { - index: any.index, - column_type: Advice, +impl TryFrom> for Column { + type Error = &'static str; + + fn try_from(any: Column) -> Result { + match any.column_type { + Any::Advice => { + return Ok(Column { + index: any.index, + column_type: Advice, + }) + } + _ => Err("Cannot convert into Column"), } } } -impl From> for Column { - fn from(any: Column) -> Column { - Column { - index: any.index, - column_type: Fixed, +impl TryFrom> for Column { + type Error = &'static str; + + fn try_from(any: Column) -> Result { + match any.column_type { + Any::Fixed => { + return Ok(Column { + index: any.index, + column_type: Fixed, + }) + } + _ => Err("Cannot convert into Column"), } } } -impl From> for Column { - fn from(any: Column) -> Column { - Column { - index: any.index, - column_type: Aux, +impl TryFrom> for Column { + type Error = &'static str; + + fn try_from(any: Column) -> Result { + match any.column_type { + Any::Aux => { + return Ok(Column { + index: any.index, + column_type: Aux, + }) + } + _ => Err("Cannot convert into Column"), } } } @@ -406,9 +428,9 @@ impl ConstraintSystem { fn query_any_index(&mut self, column: Column, at: i32) -> usize { let index = match column.column_type { - Any::Advice => self.query_advice_index(Column::::from(column), at), - Any::Fixed => self.query_fixed_index(Column::::from(column), at), - Any::Aux => self.query_aux_index(Column::::from(column), at), + Any::Advice => self.query_advice_index(Column::::try_from(column).unwrap(), at), + Any::Fixed => self.query_fixed_index(Column::::try_from(column).unwrap(), at), + Any::Aux => self.query_aux_index(Column::::try_from(column).unwrap(), at), }; index @@ -417,13 +439,15 @@ impl ConstraintSystem { /// Query an Any column at a relative position pub fn query_any(&mut self, column: Column, at: i32) -> Expression { match column.column_type { - Any::Advice => { - Expression::Advice(self.query_advice_index(Column::::from(column), at)) + Any::Advice => Expression::Advice( + self.query_advice_index(Column::::try_from(column).unwrap(), at), + ), + Any::Fixed => Expression::Fixed( + self.query_fixed_index(Column::::try_from(column).unwrap(), at), + ), + Any::Aux => { + Expression::Aux(self.query_aux_index(Column::::try_from(column).unwrap(), at)) } - Any::Fixed => { - Expression::Fixed(self.query_fixed_index(Column::::from(column), at)) - } - Any::Aux => Expression::Aux(self.query_aux_index(Column::::from(column), at)), } } @@ -462,9 +486,13 @@ impl ConstraintSystem { pub(crate) fn get_any_query_index(&self, column: Column, at: i32) -> usize { let index = match column.column_type { - Any::Advice => self.get_advice_query_index(Column::::from(column), at), - Any::Fixed => self.get_fixed_query_index(Column::::from(column), at), - Any::Aux => self.get_aux_query_index(Column::::from(column), at), + Any::Advice => { + self.get_advice_query_index(Column::::try_from(column).unwrap(), at) + } + Any::Fixed => { + self.get_fixed_query_index(Column::::try_from(column).unwrap(), at) + } + Any::Aux => self.get_aux_query_index(Column::::try_from(column).unwrap(), at), }; index From 766caf92146bdd88c46976d4465929fad1051b72 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Tue, 10 Nov 2020 00:45:52 +0800 Subject: [PATCH 7/8] Make getters for column index() and column_type() --- src/plonk/circuit.rs | 38 ++++++++++++++++++++++++-------------- src/plonk/keygen.rs | 4 ++-- src/plonk/prover.rs | 27 +++++++++++++++------------ src/plonk/verifier.rs | 6 +++--- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 2cbd59d9..895cd8a4 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -13,8 +13,18 @@ pub trait ColumnType: 'static + Sized {} /// A column with an index and type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Column { - pub(crate) index: usize, - pub(crate) column_type: C, + index: usize, + column_type: C, +} + +impl Column { + pub(crate) fn index(&self) -> usize { + self.index + } + + pub(crate) fn column_type(&self) -> &C { + &self.column_type + } } /// An advice column @@ -48,7 +58,7 @@ impl ColumnType for Any {} impl From> for Column { fn from(advice: Column) -> Column { Column { - index: advice.index, + index: advice.index(), column_type: Any::Advice, } } @@ -57,7 +67,7 @@ impl From> for Column { impl From> for Column { fn from(advice: Column) -> Column { Column { - index: advice.index, + index: advice.index(), column_type: Any::Fixed, } } @@ -66,7 +76,7 @@ impl From> for Column { impl From> for Column { fn from(advice: Column) -> Column { Column { - index: advice.index, + index: advice.index(), column_type: Any::Aux, } } @@ -76,10 +86,10 @@ impl TryFrom> for Column { type Error = &'static str; fn try_from(any: Column) -> Result { - match any.column_type { + match any.column_type() { Any::Advice => { return Ok(Column { - index: any.index, + index: any.index(), column_type: Advice, }) } @@ -92,10 +102,10 @@ impl TryFrom> for Column { type Error = &'static str; fn try_from(any: Column) -> Result { - match any.column_type { + match any.column_type() { Any::Fixed => { return Ok(Column { - index: any.index, + index: any.index(), column_type: Fixed, }) } @@ -108,10 +118,10 @@ impl TryFrom> for Column { type Error = &'static str; fn try_from(any: Column) -> Result { - match any.column_type { + match any.column_type() { Any::Aux => { return Ok(Column { - index: any.index, + index: any.index(), column_type: Aux, }) } @@ -427,7 +437,7 @@ impl ConstraintSystem { } fn query_any_index(&mut self, column: Column, at: i32) -> usize { - let index = match column.column_type { + let index = match column.column_type() { Any::Advice => self.query_advice_index(Column::::try_from(column).unwrap(), at), Any::Fixed => self.query_fixed_index(Column::::try_from(column).unwrap(), at), Any::Aux => self.query_aux_index(Column::::try_from(column).unwrap(), at), @@ -438,7 +448,7 @@ impl ConstraintSystem { /// Query an Any column at a relative position pub fn query_any(&mut self, column: Column, at: i32) -> Expression { - match column.column_type { + match column.column_type() { Any::Advice => Expression::Advice( self.query_advice_index(Column::::try_from(column).unwrap(), at), ), @@ -485,7 +495,7 @@ impl ConstraintSystem { } pub(crate) fn get_any_query_index(&self, column: Column, at: i32) -> usize { - let index = match column.column_type { + let index = match column.column_type() { Any::Advice => { self.get_advice_query_index(Column::::try_from(column).unwrap(), at) } diff --git a/src/plonk/keygen.rs b/src/plonk/keygen.rs index 13f29154..76240737 100644 --- a/src/plonk/keygen.rs +++ b/src/plonk/keygen.rs @@ -44,7 +44,7 @@ where ) -> Result<(), Error> { *self .fixed - .get_mut(column.index) + .get_mut(column.index()) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -230,7 +230,7 @@ where .fixed_queries .iter() .map(|&(column, at)| { - let poly = fixed_polys[column.index].clone(); + let poly = fixed_polys[column.index()].clone(); domain.coeff_to_extended(poly, at) }) .collect(); diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 507235a2..d13dd7a5 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -45,7 +45,7 @@ impl Proof { ) -> Result<(), Error> { *self .advice - .get_mut(column.index) + .get_mut(column.index()) .and_then(|v| v.get_mut(row)) .ok_or(Error::BoundsFailure)? = to()?; @@ -120,7 +120,7 @@ impl Proof { .aux_queries .iter() .map(|&(column, at)| { - let poly = aux_polys[column.index].clone(); + let poly = aux_polys[column.index()].clone(); domain.coeff_to_extended(poly, at) }) .collect(); @@ -157,7 +157,7 @@ impl Proof { .advice_queries .iter() .map(|&(column, at)| { - let poly = advice_polys[column.index].clone(); + let poly = advice_polys[column.index()].clone(); domain.coeff_to_extended(poly, at) }) .collect(); @@ -192,7 +192,7 @@ impl Proof { parallelize(&mut modified_advice, |modified_advice, start| { for ((modified_advice, advice_value), permuted_advice_value) in modified_advice .iter_mut() - .zip(witness.advice[column.index][start..].iter()) + .zip(witness.advice[column.index()][start..].iter()) .zip(permuted_column_values[start..].iter()) { *modified_advice *= &(x_0 * permuted_advice_value + &x_1 + advice_value); @@ -226,7 +226,7 @@ impl Proof { let mut deltaomega = deltaomega * &omega.pow_vartime(&[start as u64, 0, 0, 0]); for (modified_advice, advice_value) in modified_advice .iter_mut() - .zip(witness.advice[column.index][start..].iter()) + .zip(witness.advice[column.index()][start..].iter()) { // Multiply by p_j(\omega^i) + \delta^j \omega^i \beta *modified_advice *= &(deltaomega * &x_0 + &x_1 + advice_value); @@ -395,7 +395,7 @@ impl Proof { .advice_queries .iter() .map(|&(column, at)| { - eval_polynomial(&advice_polys[column.index], domain.rotate_omega(x_3, at)) + eval_polynomial(&advice_polys[column.index()], domain.rotate_omega(x_3, at)) }) .collect(); @@ -403,7 +403,7 @@ impl Proof { .aux_queries .iter() .map(|&(column, at)| { - eval_polynomial(&aux_polys[column.index], domain.rotate_omega(x_3, at)) + eval_polynomial(&aux_polys[column.index()], domain.rotate_omega(x_3, at)) }) .collect(); @@ -411,7 +411,10 @@ impl Proof { .fixed_queries .iter() .map(|&(column, at)| { - eval_polynomial(&pk.fixed_polys[column.index], domain.rotate_omega(x_3, at)) + eval_polynomial( + &pk.fixed_polys[column.index()], + domain.rotate_omega(x_3, at), + ) }) .collect(); @@ -469,8 +472,8 @@ impl Proof { instances.push(ProverQuery { point, - poly: &advice_polys[column.index], - blind: advice_blinds[column.index], + poly: &advice_polys[column.index()], + blind: advice_blinds[column.index()], eval: advice_evals[query_index], }); } @@ -480,7 +483,7 @@ impl Proof { instances.push(ProverQuery { point, - poly: &aux_polys[column.index], + poly: &aux_polys[column.index()], blind: Blind::default(), eval: aux_evals[query_index], }); @@ -491,7 +494,7 @@ impl Proof { instances.push(ProverQuery { point, - poly: &pk.fixed_polys[column.index], + poly: &pk.fixed_polys[column.index()], blind: Blind::default(), eval: fixed_evals[query_index], }); diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 5ff87455..0ea391e2 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -93,7 +93,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &self.advice_commitments[column.index], + commitment: &self.advice_commitments[column.index()], eval: self.advice_evals[query_index], }); } @@ -102,7 +102,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &aux_commitments[column.index], + commitment: &aux_commitments[column.index()], eval: self.aux_evals[query_index], }); } @@ -111,7 +111,7 @@ impl<'a, C: CurveAffine> Proof { let point = vk.domain.rotate_omega(x_3, at); queries.push(VerifierQuery { point, - commitment: &vk.fixed_commitments[column.index], + commitment: &vk.fixed_commitments[column.index()], eval: self.fixed_evals[query_index], }); } From a856137619cba9e87fff4ae5139a4f022ef87082 Mon Sep 17 00:00:00 2001 From: ying tong Date: Wed, 11 Nov 2020 13:46:18 +0800 Subject: [PATCH 8/8] Minor refactors Co-authored-by: str4d --- src/plonk/circuit.rs | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 895cd8a4..b5d7f4ed 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -87,12 +87,10 @@ impl TryFrom> for Column { fn try_from(any: Column) -> Result { match any.column_type() { - Any::Advice => { - return Ok(Column { - index: any.index(), - column_type: Advice, - }) - } + Any::Advice => Ok(Column { + index: any.index(), + column_type: Advice, + }), _ => Err("Cannot convert into Column"), } } @@ -103,12 +101,10 @@ impl TryFrom> for Column { fn try_from(any: Column) -> Result { match any.column_type() { - Any::Fixed => { - return Ok(Column { - index: any.index(), - column_type: Fixed, - }) - } + Any::Fixed => Ok(Column { + index: any.index(), + column_type: Fixed, + }), _ => Err("Cannot convert into Column"), } } @@ -119,12 +115,10 @@ impl TryFrom> for Column { fn try_from(any: Column) -> Result { match any.column_type() { - Any::Aux => { - return Ok(Column { - index: any.index(), - column_type: Aux, - }) - } + Any::Aux => Ok(Column { + index: any.index(), + column_type: Aux, + }), _ => Err("Cannot convert into Column"), } } @@ -495,7 +489,7 @@ impl ConstraintSystem { } pub(crate) fn get_any_query_index(&self, column: Column, at: i32) -> usize { - let index = match column.column_type() { + match column.column_type() { Any::Advice => { self.get_advice_query_index(Column::::try_from(column).unwrap(), at) } @@ -503,9 +497,7 @@ impl ConstraintSystem { self.get_fixed_query_index(Column::::try_from(column).unwrap(), at) } Any::Aux => self.get_aux_query_index(Column::::try_from(column).unwrap(), at), - }; - - index + } } /// Create a new gate