From 075988ae4e80c9113eec1248aae992969d7b5ce7 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Fri, 6 Nov 2020 11:25:50 +0800 Subject: [PATCH] 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 6200dcc..6a457d4 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 c17d4bb..793e6d7 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 9a0f029..13f2915 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 3aa5af9..507235a 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 855c6da..5ff8745 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], }); }