Add Expression::Const variant

This commit is contained in:
therealyingtong 2021-02-13 18:36:29 +08:00 committed by Sean Bowe
parent 6a7f869f66
commit 4bf46fc349
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
7 changed files with 34 additions and 0 deletions

View File

@ -296,6 +296,7 @@ impl<F: FieldExt> MockProver<F> {
} }
if gate.evaluate( if gate.evaluate(
&|scalar| scalar,
&load(n, row, &self.cs.fixed_queries, &self.fixed), &load(n, row, &self.cs.fixed_queries, &self.fixed),
&load(n, row, &self.cs.advice_queries, &self.advice), &load(n, row, &self.cs.advice_queries, &self.advice),
&load(n, row, &self.cs.instance_queries, &self.instance), &load(n, row, &self.cs.instance_queries, &self.instance),
@ -318,6 +319,7 @@ impl<F: FieldExt> MockProver<F> {
for input_row in 0..n { for input_row in 0..n {
let load = |expression: &Expression<F>, row| { let load = |expression: &Expression<F>, row| {
expression.evaluate( expression.evaluate(
&|scalar| scalar,
&|index| { &|index| {
let column_index = self.cs.fixed_queries[index].0.index(); let column_index = self.cs.fixed_queries[index].0.index();
self.fixed[column_index][row as usize] self.fixed[column_index][row as usize]

View File

@ -224,6 +224,8 @@ pub trait Circuit<F: Field> {
/// Low-degree expression representing an identity that must hold over the committed columns. /// Low-degree expression representing an identity that must hold over the committed columns.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Expression<F> { pub enum Expression<F> {
/// This is a constant polynomial
Const(F),
/// This is a fixed column queried at a certain relative location /// This is a fixed column queried at a certain relative location
Fixed(usize), Fixed(usize),
/// This is an advice (witness) column queried at a certain relative location /// This is an advice (witness) column queried at a certain relative location
@ -243,6 +245,7 @@ impl<F: Field> Expression<F> {
/// operations. /// operations.
pub fn evaluate<T>( pub fn evaluate<T>(
&self, &self,
const_column: &impl Fn(F) -> T,
fixed_column: &impl Fn(usize) -> T, fixed_column: &impl Fn(usize) -> T,
advice_column: &impl Fn(usize) -> T, advice_column: &impl Fn(usize) -> T,
instance_column: &impl Fn(usize) -> T, instance_column: &impl Fn(usize) -> T,
@ -251,11 +254,13 @@ impl<F: Field> Expression<F> {
scaled: &impl Fn(T, F) -> T, scaled: &impl Fn(T, F) -> T,
) -> T { ) -> T {
match self { match self {
Expression::Const(scalar) => const_column(*scalar),
Expression::Fixed(index) => fixed_column(*index), Expression::Fixed(index) => fixed_column(*index),
Expression::Advice(index) => advice_column(*index), Expression::Advice(index) => advice_column(*index),
Expression::Instance(index) => instance_column(*index), Expression::Instance(index) => instance_column(*index),
Expression::Sum(a, b) => { Expression::Sum(a, b) => {
let a = a.evaluate( let a = a.evaluate(
const_column,
fixed_column, fixed_column,
advice_column, advice_column,
instance_column, instance_column,
@ -264,6 +269,7 @@ impl<F: Field> Expression<F> {
scaled, scaled,
); );
let b = b.evaluate( let b = b.evaluate(
const_column,
fixed_column, fixed_column,
advice_column, advice_column,
instance_column, instance_column,
@ -275,6 +281,7 @@ impl<F: Field> Expression<F> {
} }
Expression::Product(a, b) => { Expression::Product(a, b) => {
let a = a.evaluate( let a = a.evaluate(
const_column,
fixed_column, fixed_column,
advice_column, advice_column,
instance_column, instance_column,
@ -283,6 +290,7 @@ impl<F: Field> Expression<F> {
scaled, scaled,
); );
let b = b.evaluate( let b = b.evaluate(
const_column,
fixed_column, fixed_column,
advice_column, advice_column,
instance_column, instance_column,
@ -294,6 +302,7 @@ impl<F: Field> Expression<F> {
} }
Expression::Scaled(a, f) => { Expression::Scaled(a, f) => {
let a = a.evaluate( let a = a.evaluate(
const_column,
fixed_column, fixed_column,
advice_column, advice_column,
instance_column, instance_column,
@ -309,6 +318,7 @@ impl<F: Field> Expression<F> {
/// Compute the degree of this polynomial /// Compute the degree of this polynomial
pub fn degree(&self) -> usize { pub fn degree(&self) -> usize {
match self { match self {
Expression::Const(_) => 0,
Expression::Fixed(_) => 1, Expression::Fixed(_) => 1,
Expression::Advice(_) => 1, Expression::Advice(_) => 1,
Expression::Instance(_) => 1, Expression::Instance(_) => 1,

View File

@ -96,6 +96,7 @@ impl<F: FieldExt> Argument<F> {
.iter() .iter()
.map(|expression| { .map(|expression| {
expression.evaluate( expression.evaluate(
&|scalar| pk.vk.domain.const_lagrange(scalar),
&|index| { &|index| {
let query = pk.vk.cs.fixed_queries[index]; let query = pk.vk.cs.fixed_queries[index];
let column_index = query.0.index(); let column_index = query.0.index();
@ -137,6 +138,7 @@ impl<F: FieldExt> Argument<F> {
.iter() .iter()
.map(|expression| { .map(|expression| {
expression.evaluate( expression.evaluate(
&|scalar| pk.vk.domain.const_extended(scalar),
&|index| fixed_cosets[index].clone(), &|index| fixed_cosets[index].clone(),
&|index| advice_cosets[index].clone(), &|index| advice_cosets[index].clone(),
&|index| instance_cosets[index].clone(), &|index| instance_cosets[index].clone(),

View File

@ -120,6 +120,7 @@ impl<C: CurveAffine> Evaluated<C> {
.iter() .iter()
.map(|expression| { .map(|expression| {
expression.evaluate( expression.evaluate(
&|scalar| scalar,
&|index| fixed_evals[index], &|index| fixed_evals[index],
&|index| advice_evals[index], &|index| advice_evals[index],
&|index| instance_evals[index], &|index| instance_evals[index],

View File

@ -373,6 +373,7 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
// Custom constraints // Custom constraints
.chain(meta.gates.iter().map(move |(_, poly)| { .chain(meta.gates.iter().map(move |(_, poly)| {
poly.evaluate( poly.evaluate(
&|scalar| pk.vk.domain.const_extended(scalar),
&|index| pk.fixed_cosets[index].clone(), &|index| pk.fixed_cosets[index].clone(),
&|index| advice.advice_cosets[index].clone(), &|index| advice.advice_cosets[index].clone(),
&|index| instance.instance_cosets[index].clone(), &|index| instance.instance_cosets[index].clone(),

View File

@ -168,6 +168,7 @@ pub fn verify_proof<'a, C: CurveAffine, T: TranscriptRead<C>>(
// Evaluate the circuit using the custom gates provided // Evaluate the circuit using the custom gates provided
.chain(vk.cs.gates.iter().map(move |(_, poly)| { .chain(vk.cs.gates.iter().map(move |(_, poly)| {
poly.evaluate( poly.evaluate(
&|scalar| scalar,
&|index| fixed_evals[index], &|index| fixed_evals[index],
&|index| advice_evals[index], &|index| advice_evals[index],
&|index| instance_evals[index], &|index| instance_evals[index],

View File

@ -177,6 +177,14 @@ impl<G: Group> EvaluationDomain<G> {
} }
} }
/// Returns a constant polynomial in the Lagrange coefficient basis
pub fn const_lagrange(&self, scalar: G) -> Polynomial<G, LagrangeCoeff> {
Polynomial {
values: vec![scalar; self.n as usize],
_marker: PhantomData,
}
}
/// Returns an empty (zero) polynomial in the extended Lagrange coefficient /// Returns an empty (zero) polynomial in the extended Lagrange coefficient
/// basis /// basis
pub fn empty_extended(&self) -> Polynomial<G, ExtendedLagrangeCoeff> { pub fn empty_extended(&self) -> Polynomial<G, ExtendedLagrangeCoeff> {
@ -186,6 +194,15 @@ impl<G: Group> EvaluationDomain<G> {
} }
} }
/// Returns a constant polynomial in the extended Lagrange coefficient
/// basis
pub fn const_extended(&self, scalar: G) -> Polynomial<G, ExtendedLagrangeCoeff> {
Polynomial {
values: vec![scalar; self.extended_len()],
_marker: PhantomData,
}
}
/// This takes us from an n-length vector into the coefficient form. /// This takes us from an n-length vector into the coefficient form.
/// ///
/// This function will panic if the provided vector is not the correct /// This function will panic if the provided vector is not the correct