mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Pass Expressions to meta.lookup()
This commit is contained in:
parent
9401ceb68d
commit
d8534e1c50
7 changed files with 76 additions and 52 deletions
|
|
@ -283,8 +283,12 @@ fn main() {
|
||||||
* ... ... ... 0 0
|
* ... ... ... 0 0
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
meta.lookup(&[a.into()], &[sl.into()]);
|
let a_ = meta.query_any(a.into(), Rotation::cur());
|
||||||
meta.lookup(&[a.into(), b.into()], &[sl.into(), sl2.into()]);
|
let b_ = meta.query_any(b.into(), Rotation::cur());
|
||||||
|
let sl_ = meta.query_any(sl.into(), Rotation::cur());
|
||||||
|
let sl2_ = meta.query_any(sl2.into(), Rotation::cur());
|
||||||
|
meta.lookup(&[a_.clone()], &[sl_.clone()]);
|
||||||
|
meta.lookup(&[a_, b_], &[sl_, sl2_]);
|
||||||
|
|
||||||
meta.create_gate("Combined add-mult", |meta| {
|
meta.create_gate("Combined add-mult", |meta| {
|
||||||
let d = meta.query_advice(d, Rotation::next());
|
let d = meta.query_advice(d, Rotation::next());
|
||||||
|
|
|
||||||
25
src/dev.rs
25
src/dev.rs
|
|
@ -5,8 +5,8 @@ use ff::Field;
|
||||||
use crate::{
|
use crate::{
|
||||||
arithmetic::{FieldExt, Group},
|
arithmetic::{FieldExt, Group},
|
||||||
plonk::{
|
plonk::{
|
||||||
permutation, Advice, Any, Assignment, Circuit, Column, ColumnType, ConstraintSystem, Error,
|
permutation, Advice, Assignment, Circuit, Column, ColumnType, ConstraintSystem, Error,
|
||||||
Fixed,
|
Expression, Fixed,
|
||||||
},
|
},
|
||||||
poly::Rotation,
|
poly::Rotation,
|
||||||
};
|
};
|
||||||
|
|
@ -143,7 +143,7 @@ pub enum VerifyFailure {
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MockProver<F: Group> {
|
pub struct MockProver<F: Group + Field> {
|
||||||
n: u32,
|
n: u32,
|
||||||
cs: ConstraintSystem<F>,
|
cs: ConstraintSystem<F>,
|
||||||
|
|
||||||
|
|
@ -316,10 +316,21 @@ impl<F: FieldExt> MockProver<F> {
|
||||||
// Check that all lookups exist in their respective tables.
|
// Check that all lookups exist in their respective tables.
|
||||||
for (lookup_index, lookup) in self.cs.lookups.iter().enumerate() {
|
for (lookup_index, lookup) in self.cs.lookups.iter().enumerate() {
|
||||||
for input_row in 0..n {
|
for input_row in 0..n {
|
||||||
let load = |column: &Column<Any>, row| match column.column_type() {
|
let load = |column: &Expression<F>, row| match column {
|
||||||
Any::Fixed => self.fixed[column.index()][row as usize],
|
Expression::Fixed(index) => {
|
||||||
Any::Advice => self.advice[column.index()][row as usize],
|
let column_index = self.cs.fixed_queries[*index].0.index();
|
||||||
Any::Instance => self.instance[column.index()][row as usize],
|
self.fixed[column_index][row as usize]
|
||||||
|
}
|
||||||
|
Expression::Advice(index) => {
|
||||||
|
let column_index = self.cs.advice_queries[*index].0.index();
|
||||||
|
self.advice[column_index][row as usize]
|
||||||
|
}
|
||||||
|
Expression::Instance(index) => {
|
||||||
|
let column_index = self.cs.instance_queries[*index].0.index();
|
||||||
|
self.instance[column_index][row as usize]
|
||||||
|
}
|
||||||
|
// TODO: other Expression variants
|
||||||
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let inputs: Vec<_> = lookup
|
let inputs: Vec<_> = lookup
|
||||||
|
|
|
||||||
|
|
@ -467,8 +467,12 @@ fn test_proving() {
|
||||||
* ... ... ... 0 0
|
* ... ... ... 0 0
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
meta.lookup(&[a.into()], &[sl.into()]);
|
let a_ = meta.query_any(a.into(), Rotation::cur());
|
||||||
meta.lookup(&[a.into(), b.into()], &[sl.into(), sl2.into()]);
|
let b_ = meta.query_any(b.into(), Rotation::cur());
|
||||||
|
let sl_ = meta.query_any(sl.into(), Rotation::cur());
|
||||||
|
let sl2_ = meta.query_any(sl2.into(), Rotation::cur());
|
||||||
|
meta.lookup(&[a_.clone()], &[sl_.clone()]);
|
||||||
|
meta.lookup(&[a_, b_], &[sl_, sl2_]);
|
||||||
|
|
||||||
meta.create_gate("Combined add-mult", |meta| {
|
meta.create_gate("Combined add-mult", |meta| {
|
||||||
let d = meta.query_advice(d, Rotation::next());
|
let d = meta.query_advice(d, Rotation::next());
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,10 @@ pub trait ColumnType: 'static + Sized + std::fmt::Debug {}
|
||||||
/// A column with an index and type
|
/// A column with an index and type
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct Column<C: ColumnType> {
|
pub struct Column<C: ColumnType> {
|
||||||
index: usize,
|
/// Index of column
|
||||||
column_type: C,
|
pub index: usize,
|
||||||
|
/// Type of column
|
||||||
|
pub column_type: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ColumnType> Column<C> {
|
impl<C: ColumnType> Column<C> {
|
||||||
|
|
@ -362,7 +364,7 @@ pub(crate) struct PointIndex(pub usize);
|
||||||
/// This is a description of the circuit environment, such as the gate, column and
|
/// This is a description of the circuit environment, such as the gate, column and
|
||||||
/// permutation arrangements.
|
/// permutation arrangements.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ConstraintSystem<F> {
|
pub struct ConstraintSystem<F: Field> {
|
||||||
pub(crate) num_fixed_columns: usize,
|
pub(crate) num_fixed_columns: usize,
|
||||||
pub(crate) num_advice_columns: usize,
|
pub(crate) num_advice_columns: usize,
|
||||||
pub(crate) num_instance_columns: usize,
|
pub(crate) num_instance_columns: usize,
|
||||||
|
|
@ -377,7 +379,7 @@ pub struct ConstraintSystem<F> {
|
||||||
|
|
||||||
// Vector of lookup arguments, where each corresponds to a sequence of
|
// Vector of lookup arguments, where each corresponds to a sequence of
|
||||||
// input columns and a sequence of table columns involved in the lookup.
|
// input columns and a sequence of table columns involved in the lookup.
|
||||||
pub(crate) lookups: Vec<lookup::Argument>,
|
pub(crate) lookups: Vec<lookup::Argument<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the minimal parameters that determine a `ConstraintSystem`.
|
/// Represents the minimal parameters that determine a `ConstraintSystem`.
|
||||||
|
|
@ -456,19 +458,13 @@ impl<F: Field> ConstraintSystem<F> {
|
||||||
/// columns are not the same.
|
/// columns are not the same.
|
||||||
pub fn lookup(
|
pub fn lookup(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_columns: &[Column<Any>],
|
input_columns: &[Expression<F>],
|
||||||
table_columns: &[Column<Any>],
|
table_columns: &[Expression<F>],
|
||||||
) -> usize {
|
) -> usize {
|
||||||
assert_eq!(input_columns.len(), table_columns.len());
|
assert_eq!(input_columns.len(), table_columns.len());
|
||||||
|
|
||||||
let index = self.lookups.len();
|
let index = self.lookups.len();
|
||||||
|
|
||||||
for input in input_columns {
|
|
||||||
self.query_any_index(*input, Rotation::cur());
|
|
||||||
}
|
|
||||||
for table in table_columns {
|
|
||||||
self.query_any_index(*table, Rotation::cur());
|
|
||||||
}
|
|
||||||
self.lookups
|
self.lookups
|
||||||
.push(lookup::Argument::new(input_columns, table_columns));
|
.push(lookup::Argument::new(input_columns, table_columns));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
use super::circuit::{Any, Column};
|
use super::circuit::Expression;
|
||||||
|
use ff::Field;
|
||||||
|
|
||||||
pub(crate) mod prover;
|
pub(crate) mod prover;
|
||||||
pub(crate) mod verifier;
|
pub(crate) mod verifier;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct Argument {
|
pub(crate) struct Argument<F: Field> {
|
||||||
pub input_columns: Vec<Column<Any>>,
|
pub input_columns: Vec<Expression<F>>,
|
||||||
pub table_columns: Vec<Column<Any>>,
|
pub table_columns: Vec<Expression<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Argument {
|
impl<F: Field> Argument<F> {
|
||||||
pub fn new(input_columns: &[Column<Any>], table_columns: &[Column<Any>]) -> Self {
|
pub fn new(input_columns: &[Expression<F>], table_columns: &[Expression<F>]) -> Self {
|
||||||
assert_eq!(input_columns.len(), table_columns.len());
|
assert_eq!(input_columns.len(), table_columns.len());
|
||||||
Argument {
|
Argument {
|
||||||
input_columns: input_columns.to_vec(),
|
input_columns: input_columns.to_vec(),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use super::super::{
|
use super::super::{
|
||||||
circuit::{Any, Column},
|
circuit::{Advice, Aux, Column, Expression, Fixed},
|
||||||
ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, ProvingKey,
|
ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, ProvingKey,
|
||||||
};
|
};
|
||||||
use super::Argument;
|
use super::Argument;
|
||||||
|
|
@ -57,7 +57,7 @@ pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
|
||||||
constructed: Constructed<C>,
|
constructed: Constructed<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Argument {
|
impl<F: FieldExt> Argument<F> {
|
||||||
/// Given a Lookup with input columns [A_0, A_1, ..., A_{m-1}] and table columns
|
/// Given a Lookup with input columns [A_0, A_1, ..., A_{m-1}] and table columns
|
||||||
/// [S_0, S_1, ..., S_{m-1}], this method
|
/// [S_0, S_1, ..., S_{m-1}], this method
|
||||||
/// - constructs A_compressed = \theta^{m-1} A_0 + theta^{m-2} A_1 + ... + \theta A_{m-2} + A_{m-1}
|
/// - constructs A_compressed = \theta^{m-1} A_0 + theta^{m-2} A_1 + ... + \theta A_{m-2} + A_{m-1}
|
||||||
|
|
@ -82,20 +82,27 @@ impl Argument {
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> Result<Permuted<'a, C>, Error> {
|
) -> Result<Permuted<'a, C>, Error> {
|
||||||
// Closure to get values of columns and compress them
|
// Closure to get values of columns and compress them
|
||||||
let compress_columns = |columns: &[Column<Any>]| {
|
let compress_columns = |columns: &[Expression<F>]| {
|
||||||
// Values of input columns involved in the lookup
|
// Values of input columns involved in the lookup
|
||||||
let (unpermuted_columns, unpermuted_cosets): (Vec<_>, Vec<_>) = columns
|
let (unpermuted_columns, unpermuted_cosets): (Vec<_>, Vec<_>) = columns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&column| {
|
.map(|column| {
|
||||||
let (values, cosets) = match column.column_type() {
|
match column {
|
||||||
Any::Advice => (advice_values, advice_cosets),
|
Expression::Advice(index) => {
|
||||||
Any::Fixed => (fixed_values, fixed_cosets),
|
let column_index = pk.vk.cs.advice_queries[*index].0.index();
|
||||||
Any::Instance => (instance_values, instance_cosets),
|
(&advice_values[column_index], &advice_cosets[*index])
|
||||||
};
|
}
|
||||||
(
|
Expression::Fixed(index) => {
|
||||||
&values[column.index()],
|
let column_index = pk.vk.cs.fixed_queries[*index].0.index();
|
||||||
&cosets[pk.vk.cs.get_any_query_index(column, Rotation::cur())],
|
(&fixed_values[column_index], &fixed_cosets[*index])
|
||||||
)
|
}
|
||||||
|
Expression::Instance(index) => {
|
||||||
|
let column_index = pk.vk.cs.instance_queries[*index].0.index();
|
||||||
|
(&instance_values[column_index], &instance_cosets[*index])
|
||||||
|
}
|
||||||
|
// TODO: other Expression variants
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use super::super::circuit::{Any, Column};
|
use super::super::circuit::{Advice, Aux, Column, Expression, Fixed};
|
||||||
use super::Argument;
|
use super::Argument;
|
||||||
use crate::{
|
use crate::{
|
||||||
arithmetic::CurveAffine,
|
arithmetic::{CurveAffine, FieldExt},
|
||||||
plonk::{ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, VerifyingKey},
|
plonk::{ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, VerifyingKey},
|
||||||
poly::{multiopen::VerifierQuery, Rotation},
|
poly::{multiopen::VerifierQuery, Rotation},
|
||||||
transcript::TranscriptRead,
|
transcript::TranscriptRead,
|
||||||
|
|
@ -29,7 +29,7 @@ pub struct Evaluated<C: CurveAffine> {
|
||||||
permuted_table_eval: C::Scalar,
|
permuted_table_eval: C::Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Argument {
|
impl<F: FieldExt> Argument<F> {
|
||||||
pub(in crate::plonk) fn read_permuted_commitments<C: CurveAffine, T: TranscriptRead<C>>(
|
pub(in crate::plonk) fn read_permuted_commitments<C: CurveAffine, T: TranscriptRead<C>>(
|
||||||
&self,
|
&self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
|
@ -101,7 +101,7 @@ impl<C: CurveAffine> Evaluated<C> {
|
||||||
&'a self,
|
&'a self,
|
||||||
vk: &'a VerifyingKey<C>,
|
vk: &'a VerifyingKey<C>,
|
||||||
l_0: C::Scalar,
|
l_0: C::Scalar,
|
||||||
argument: &'a Argument,
|
argument: &'a Argument<C::Scalar>,
|
||||||
theta: ChallengeTheta<C>,
|
theta: ChallengeTheta<C>,
|
||||||
beta: ChallengeBeta<C>,
|
beta: ChallengeBeta<C>,
|
||||||
gamma: ChallengeGamma<C>,
|
gamma: ChallengeGamma<C>,
|
||||||
|
|
@ -116,15 +116,16 @@ impl<C: CurveAffine> Evaluated<C> {
|
||||||
* &(self.permuted_input_eval + &*beta)
|
* &(self.permuted_input_eval + &*beta)
|
||||||
* &(self.permuted_table_eval + &*gamma);
|
* &(self.permuted_table_eval + &*gamma);
|
||||||
|
|
||||||
let compress_columns = |columns: &[Column<Any>]| {
|
let compress_columns = |columns: &[Expression<C::Scalar>]| {
|
||||||
columns
|
columns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|column| {
|
.map(|column| {
|
||||||
let index = vk.cs.get_any_query_index(*column, Rotation::cur());
|
match column {
|
||||||
match column.column_type() {
|
Expression::Advice(index) => advice_evals[*index],
|
||||||
Any::Advice => advice_evals[index],
|
Expression::Fixed(index) => fixed_evals[*index],
|
||||||
Any::Fixed => fixed_evals[index],
|
Expression::Instance(index) => instance_evals[*index],
|
||||||
Any::Instance => instance_evals[index],
|
// TODO: other Expression variants
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fold(C::Scalar::zero(), |acc, eval| acc * &*theta + &eval)
|
.fold(C::Scalar::zero(), |acc, eval| acc * &*theta + &eval)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue