use midnight_proofs::{
circuit::Layouter,
plonk::{Error, Expression},
};
use crate::{
field::AssignedNative,
instructions::{ArithInstructions, AssignmentInstructions},
verifier::{
utils::{mul_add, try_reduce},
SelfEmulation,
},
};
pub(crate) mod lookup;
pub(crate) mod permutation;
pub(crate) mod trash;
pub(crate) fn eval_expression<S: SelfEmulation>(
layouter: &mut impl Layouter<S::F>,
scalar_chip: &S::ScalarChip,
advice: &[AssignedNative<S::F>], fixed: &[AssignedNative<S::F>], instance: &[AssignedNative<S::F>], expr: &Expression<S::F>,
) -> Result<AssignedNative<S::F>, Error> {
match expr {
Expression::Constant(k) => scalar_chip.assign_fixed(layouter, *k),
Expression::Selector(_) => {
panic!("Virtual selector are removed during optimisation")
}
Expression::Fixed(query) => Ok(fixed[query.index().unwrap()].clone()),
Expression::Advice(query) => Ok(advice[query.index.unwrap()].clone()),
Expression::Instance(query) => Ok(instance[query.index.unwrap()].clone()),
Expression::Challenge(_) => panic!("We do not suport multi-phase yet"),
Expression::Negated(e) => {
let val = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e)?;
scalar_chip.neg(layouter, &val)
}
Expression::Sum(e1, e2) => {
let e1 = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e1)?;
let e2 = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e2)?;
scalar_chip.add(layouter, &e1, &e2)
}
Expression::Product(e1, e2) => {
let val1 = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e1)?;
let val2 = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e2)?;
scalar_chip.mul(layouter, &val1, &val2, None)
}
Expression::Scaled(e, k) => {
let val = eval_expression::<S>(layouter, scalar_chip, advice, fixed, instance, e)?;
scalar_chip.mul_by_constant(layouter, &val, *k)
}
}
}
pub(crate) fn compress_expressions<S: SelfEmulation>(
layouter: &mut impl Layouter<S::F>,
scalar_chip: &S::ScalarChip,
advice_evals: &[AssignedNative<S::F>],
fixed_evals: &[AssignedNative<S::F>],
instance_evals: &[AssignedNative<S::F>],
r: &AssignedNative<S::F>,
expressions: &[Expression<S::F>],
) -> Result<AssignedNative<S::F>, Error> {
let evaluated_expressions = expressions
.iter()
.map(|expression| {
eval_expression::<S>(
layouter,
scalar_chip,
advice_evals,
fixed_evals,
instance_evals,
expression,
)
})
.collect::<Result<Vec<_>, Error>>()?;
try_reduce(evaluated_expressions, |acc, eval| {
mul_add(layouter, scalar_chip, &acc, r, &eval)
})
}