mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Introduce Column struct and ColumnType trait
This commit is contained in:
parent
2034179d82
commit
075988ae4e
5 changed files with 175 additions and 74 deletions
23
src/plonk.rs
23
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<Advice>, usize);
|
||||
|
||||
// Initialize the polynomial commitment parameters
|
||||
let params: Params<EqAffine> = Params::new::<DummyHash<Fq>>(K);
|
||||
|
||||
struct PLONKConfig {
|
||||
a: AdviceColumn,
|
||||
b: AdviceColumn,
|
||||
c: AdviceColumn,
|
||||
d: AdviceColumn,
|
||||
e: AdviceColumn,
|
||||
a: Column<Advice>,
|
||||
b: Column<Advice>,
|
||||
c: Column<Advice>,
|
||||
d: Column<Advice>,
|
||||
e: Column<Advice>,
|
||||
|
||||
sa: FixedColumn,
|
||||
sb: FixedColumn,
|
||||
sc: FixedColumn,
|
||||
sm: FixedColumn,
|
||||
sp: FixedColumn,
|
||||
sa: Column<Fixed>,
|
||||
sb: Column<Fixed>,
|
||||
sc: Column<Fixed>,
|
||||
sm: Column<Fixed>,
|
||||
sp: Column<Fixed>,
|
||||
|
||||
perm: usize,
|
||||
perm2: usize,
|
||||
|
|
|
|||
|
|
@ -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<C: ColumnType> {
|
||||
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<Column<Advice>> for Column<Any> {
|
||||
fn from(advice: Column<Advice>) -> Column<Any> {
|
||||
Column {
|
||||
index: advice.index,
|
||||
column_type: Any::Advice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Column<Fixed>> for Column<Any> {
|
||||
fn from(advice: Column<Fixed>) -> Column<Any> {
|
||||
Column {
|
||||
index: advice.index,
|
||||
column_type: Any::Fixed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Column<Aux>> for Column<Any> {
|
||||
fn from(advice: Column<Aux>) -> Column<Any> {
|
||||
Column {
|
||||
index: advice.index,
|
||||
column_type: Any::Aux,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Column<Any>> for Column<Advice> {
|
||||
fn from(any: Column<Any>) -> Column<Advice> {
|
||||
Column {
|
||||
index: any.index,
|
||||
column_type: Advice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Column<Any>> for Column<Fixed> {
|
||||
fn from(any: Column<Any>) -> Column<Fixed> {
|
||||
Column {
|
||||
index: any.index,
|
||||
column_type: Fixed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Column<Any>> for Column<Aux> {
|
||||
fn from(any: Column<Any>) -> Column<Aux> {
|
||||
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<F: Field> {
|
|||
/// Assign an advice column value (witness)
|
||||
fn assign_advice(
|
||||
&mut self,
|
||||
column: AdviceColumn,
|
||||
column: Column<Advice>,
|
||||
row: usize,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error>;
|
||||
|
|
@ -32,7 +112,7 @@ pub trait Assignment<F: Field> {
|
|||
/// Assign a fixed value
|
||||
fn assign_fixed(
|
||||
&mut self,
|
||||
column: FixedColumn,
|
||||
column: Column<Fixed>,
|
||||
row: usize,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error>;
|
||||
|
|
@ -197,16 +277,16 @@ pub struct ConstraintSystem<F> {
|
|||
pub(crate) num_advice_columns: usize,
|
||||
pub(crate) num_aux_columns: usize,
|
||||
pub(crate) gates: Vec<Expression<F>>,
|
||||
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<Advice>, Rotation)>,
|
||||
pub(crate) aux_queries: Vec<(Column<Aux>, Rotation)>,
|
||||
pub(crate) fixed_queries: Vec<(Column<Fixed>, Rotation)>,
|
||||
|
||||
// Mapping from a witness vector rotation to the index in the point vector.
|
||||
pub(crate) rotations: BTreeMap<Rotation, PointIndex>,
|
||||
|
||||
// Vector of permutation arguments, where each corresponds to a set of columns
|
||||
// that are involved in a permutation argument.
|
||||
pub(crate) permutations: Vec<Vec<AdviceColumn>>,
|
||||
pub(crate) permutations: Vec<Vec<Column<Advice>>>,
|
||||
}
|
||||
|
||||
impl<F: Field> Default for ConstraintSystem<F> {
|
||||
|
|
@ -230,7 +310,7 @@ impl<F: Field> Default for ConstraintSystem<F> {
|
|||
|
||||
impl<F: Field> ConstraintSystem<F> {
|
||||
/// Add a permutation argument for some advice columns
|
||||
pub fn permutation(&mut self, columns: &[AdviceColumn]) -> usize {
|
||||
pub fn permutation(&mut self, columns: &[Column<Advice>]) -> usize {
|
||||
let index = self.permutations.len();
|
||||
if self.permutations.is_empty() {
|
||||
let at = Rotation(-1);
|
||||
|
|
@ -246,7 +326,7 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
index
|
||||
}
|
||||
|
||||
fn query_fixed_index(&mut self, column: FixedColumn, at: i32) -> usize {
|
||||
fn query_fixed_index(&mut self, column: Column<Fixed>, at: i32) -> usize {
|
||||
let at = Rotation(at);
|
||||
{
|
||||
let len = self.rotations.len();
|
||||
|
|
@ -268,22 +348,11 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
}
|
||||
|
||||
/// Query a fixed column at a relative position
|
||||
pub fn query_fixed(&mut self, column: FixedColumn, at: i32) -> Expression<F> {
|
||||
pub fn query_fixed(&mut self, column: Column<Fixed>, at: i32) -> Expression<F> {
|
||||
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<Advice>, at: i32) -> usize {
|
||||
let at = Rotation(at);
|
||||
{
|
||||
let len = self.rotations.len();
|
||||
|
|
@ -305,11 +374,11 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
}
|
||||
|
||||
/// Query an advice column at a relative position
|
||||
pub fn query_advice(&mut self, column: AdviceColumn, at: i32) -> Expression<F> {
|
||||
pub fn query_advice(&mut self, column: Column<Advice>, at: i32) -> Expression<F> {
|
||||
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<Aux>, at: i32) -> usize {
|
||||
let at = Rotation(at);
|
||||
{
|
||||
let len = self.rotations.len();
|
||||
|
|
@ -331,10 +400,32 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
}
|
||||
|
||||
/// Query an auxiliary column at a relative position
|
||||
pub fn query_aux(&mut self, column: AuxColumn, at: i32) -> Expression<F> {
|
||||
pub fn query_aux(&mut self, column: Column<Aux>, at: i32) -> Expression<F> {
|
||||
Expression::Aux(self.query_aux_index(column, at))
|
||||
}
|
||||
|
||||
pub(crate) fn get_advice_query_index(&self, column: Column<Advice>, 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<Fixed>, 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<F>) {
|
||||
let poly = f(self);
|
||||
|
|
@ -342,22 +433,31 @@ impl<F: Field> ConstraintSystem<F> {
|
|||
}
|
||||
|
||||
/// 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<Fixed> {
|
||||
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<Advice> {
|
||||
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<Aux> {
|
||||
let tmp = Column {
|
||||
index: self.num_aux_columns,
|
||||
column_type: Aux,
|
||||
};
|
||||
self.num_aux_columns += 1;
|
||||
tmp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<F: Field> Assignment<F> for Assembly<F> {
|
||||
fn assign_advice(
|
||||
&mut self,
|
||||
_: AdviceColumn,
|
||||
_: Column<Advice>,
|
||||
_: usize,
|
||||
_: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error> {
|
||||
|
|
@ -38,13 +38,13 @@ where
|
|||
|
||||
fn assign_fixed(
|
||||
&mut self,
|
||||
column: FixedColumn,
|
||||
column: Column<Fixed>,
|
||||
row: usize,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> 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();
|
||||
|
|
|
|||
|
|
@ -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<C: CurveAffine> Proof<C> {
|
|||
impl<F: Field> Assignment<F> for WitnessCollection<F> {
|
||||
fn assign_advice(
|
||||
&mut self,
|
||||
column: AdviceColumn,
|
||||
column: Column<Advice>,
|
||||
row: usize,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> 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<C: CurveAffine> Proof<C> {
|
|||
|
||||
fn assign_fixed(
|
||||
&mut self,
|
||||
_: FixedColumn,
|
||||
_: Column<Fixed>,
|
||||
_: usize,
|
||||
_: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error> {
|
||||
|
|
@ -120,7 +120,7 @@ impl<C: CurveAffine> Proof<C> {
|
|||
.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<C: CurveAffine> Proof<C> {
|
|||
.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<C: CurveAffine> Proof<C> {
|
|||
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<C: CurveAffine> Proof<C> {
|
|||
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<C: CurveAffine> Proof<C> {
|
|||
.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<C: CurveAffine> Proof<C> {
|
|||
.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<C: CurveAffine> Proof<C> {
|
|||
.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<C: CurveAffine> Proof<C> {
|
|||
|
||||
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<C: CurveAffine> Proof<C> {
|
|||
|
||||
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<C: CurveAffine> Proof<C> {
|
|||
|
||||
instances.push(ProverQuery {
|
||||
point,
|
||||
poly: &pk.fixed_polys[column.0],
|
||||
poly: &pk.fixed_polys[column.index],
|
||||
blind: Blind::default(),
|
||||
eval: fixed_evals[query_index],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
|||
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<C> {
|
|||
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<C> {
|
|||
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],
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue