use midnight_proofs::{circuit::Layouter, plonk::Error, poly::CommitmentLabel};
use crate::{
field::AssignedNative,
verifier::{
kzg::VerifierQuery, transcript_gadget::TranscriptGadget, utils::AssignedBoundedScalar,
SelfEmulation,
},
};
#[derive(Clone, Debug)]
pub(crate) struct LookupEvaluated<S: SelfEmulation> {
pub(crate) product_eval: AssignedNative<S::F>,
pub(crate) product_next_eval: AssignedNative<S::F>,
pub(crate) permuted_input_eval: AssignedNative<S::F>,
pub(crate) permuted_input_inv_eval: AssignedNative<S::F>,
pub(crate) permuted_table_eval: AssignedNative<S::F>,
}
#[derive(Clone, Debug)]
pub(crate) struct PermutationCommitments<S: SelfEmulation> {
permuted_input_commitment: S::AssignedPoint,
permuted_table_commitment: S::AssignedPoint,
}
#[derive(Clone, Debug)]
pub(crate) struct Committed<S: SelfEmulation> {
permuted: PermutationCommitments<S>,
product_commitment: S::AssignedPoint,
}
#[derive(Clone, Debug)]
pub(crate) struct Evaluated<S: SelfEmulation> {
committed: Committed<S>,
pub(crate) evaluated: LookupEvaluated<S>,
}
pub(crate) fn read_permuted_commitments<S: SelfEmulation>(
layouter: &mut impl Layouter<S::F>,
transcript_gadget: &mut TranscriptGadget<S>,
) -> Result<PermutationCommitments<S>, Error> {
let permuted_input_commitment = transcript_gadget.read_point(layouter)?;
let permuted_table_commitment = transcript_gadget.read_point(layouter)?;
Ok(PermutationCommitments {
permuted_input_commitment,
permuted_table_commitment,
})
}
impl<S: SelfEmulation> PermutationCommitments<S> {
pub(crate) fn read_product_commitment(
self,
layouter: &mut impl Layouter<S::F>,
transcript_gadget: &mut TranscriptGadget<S>,
) -> Result<Committed<S>, Error> {
let product_commitment = transcript_gadget.read_point(layouter)?;
Ok(Committed {
permuted: self,
product_commitment,
})
}
}
impl<S: SelfEmulation> Committed<S> {
pub(crate) fn evaluate(
self,
layouter: &mut impl Layouter<S::F>,
transcript_gadget: &mut TranscriptGadget<S>,
) -> Result<Evaluated<S>, Error> {
let product_eval = transcript_gadget.read_scalar(layouter)?;
let product_next_eval = transcript_gadget.read_scalar(layouter)?;
let permuted_input_eval = transcript_gadget.read_scalar(layouter)?;
let permuted_input_inv_eval = transcript_gadget.read_scalar(layouter)?;
let permuted_table_eval = transcript_gadget.read_scalar(layouter)?;
Ok(Evaluated {
committed: self,
evaluated: LookupEvaluated {
product_eval,
product_next_eval,
permuted_input_eval,
permuted_input_inv_eval,
permuted_table_eval,
},
})
}
}
impl<S: SelfEmulation> Evaluated<S> {
pub(crate) fn queries(
&self,
one: &AssignedBoundedScalar<S::F>, x: &AssignedNative<S::F>, x_next: &AssignedNative<S::F>, x_prev: &AssignedNative<S::F>, ) -> Vec<VerifierQuery<S>> {
vec![
VerifierQuery::new(
one,
x,
CommitmentLabel::NoLabel,
&self.committed.product_commitment,
&self.evaluated.product_eval,
),
VerifierQuery::new(
one,
x,
CommitmentLabel::NoLabel,
&self.committed.permuted.permuted_input_commitment,
&self.evaluated.permuted_input_eval,
),
VerifierQuery::new(
one,
x,
CommitmentLabel::NoLabel,
&self.committed.permuted.permuted_table_commitment,
&self.evaluated.permuted_table_eval,
),
VerifierQuery::new(
one,
x_prev,
CommitmentLabel::NoLabel,
&self.committed.permuted.permuted_input_commitment,
&self.evaluated.permuted_input_inv_eval,
),
VerifierQuery::new(
one,
x_next,
CommitmentLabel::NoLabel,
&self.committed.product_commitment,
&self.evaluated.product_next_eval,
),
]
}
}