use std::collections::BTreeMap;
use snarkvm_fields::PrimeField;
use crate::polycommit::sonic_pc::{LabeledPolynomial, LabeledPolynomialWithBasis, PolynomialInfo, PolynomialLabel};
#[derive(Debug, Clone)]
pub struct FirstOracles<F: PrimeField> {
pub(in crate::snark::marlin) batches: Vec<SingleEntry<F>>,
pub mask_poly: Option<LabeledPolynomial<F>>,
}
impl<F: PrimeField> FirstOracles<F> {
#[allow(clippy::needless_collect)]
pub fn iter_for_commit(&mut self) -> impl Iterator<Item = LabeledPolynomialWithBasis<'static, F>> {
let t = self.batches.iter_mut().flat_map(|b| b.iter_for_commit()).collect::<Vec<_>>();
t.into_iter().chain(self.mask_poly.clone().map(Into::into))
}
pub fn iter_for_open(&self) -> impl Iterator<Item = &'_ LabeledPolynomial<F>> {
self.batches.iter().flat_map(|b| b.iter_for_open()).chain(self.mask_poly.as_ref())
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
self.batches.iter().all(|b| b.matches_info(info))
&& self.mask_poly.as_ref().map_or(true, |p| Some(p.info()) == info.get(p.label()))
}
}
#[derive(Debug, Clone)]
pub(in crate::snark::marlin) struct SingleEntry<F: PrimeField> {
pub(super) z_a: LabeledPolynomialWithBasis<'static, F>,
pub(super) z_b: LabeledPolynomialWithBasis<'static, F>,
pub(super) w_poly: LabeledPolynomial<F>,
pub(super) z_a_poly: LabeledPolynomial<F>,
pub(super) z_b_poly: LabeledPolynomial<F>,
}
impl<F: PrimeField> SingleEntry<F> {
pub fn iter_for_commit(&mut self) -> impl Iterator<Item = LabeledPolynomialWithBasis<'static, F>> {
let w_poly = self.w_poly.clone();
let mut z_a_copy = LabeledPolynomialWithBasis { polynomial: vec![], info: self.z_a.info().clone() };
std::mem::swap(&mut self.z_a, &mut z_a_copy);
let mut z_b_copy = LabeledPolynomialWithBasis { polynomial: vec![], info: self.z_b.info().clone() };
std::mem::swap(&mut self.z_b, &mut z_b_copy);
[w_poly.into(), z_a_copy, z_b_copy].into_iter()
}
pub fn iter_for_open(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[(&self.w_poly), &self.z_a_poly, &self.z_b_poly].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.w_poly.info()) == info.get(self.w_poly.label())
&& Some(self.z_a.info()) == info.get(self.z_a.label())
&& Some(self.z_b.info()) == info.get(self.z_b.label())
&& Some(self.z_a_poly.info()) == info.get(self.z_a_poly.label())
&& Some(self.z_b_poly.info()) == info.get(self.z_b_poly.label())
}
}
#[derive(Debug)]
pub struct SecondOracles<F: PrimeField> {
pub g_1: LabeledPolynomial<F>,
pub h_1: LabeledPolynomial<F>,
}
impl<F: PrimeField> SecondOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.g_1, &self.h_1].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.h_1.info()) == info.get(self.h_1.label()) && Some(self.g_1.info()) == info.get(self.g_1.label())
}
}
#[derive(Debug)]
pub struct ThirdOracles<F: PrimeField> {
pub g_a: LabeledPolynomial<F>,
pub g_b: LabeledPolynomial<F>,
pub g_c: LabeledPolynomial<F>,
}
impl<F: PrimeField> ThirdOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.g_a, &self.g_b, &self.g_c].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.g_a.info()) == info.get(self.g_a.label())
&& Some(self.g_b.info()) == info.get(self.g_b.label())
&& Some(self.g_c.info()) == info.get(self.g_c.label())
}
}
#[derive(Debug)]
pub struct FourthOracles<F: PrimeField> {
pub h_2: LabeledPolynomial<F>,
}
impl<F: PrimeField> FourthOracles<F> {
pub fn iter(&self) -> impl Iterator<Item = &LabeledPolynomial<F>> {
[&self.h_2].into_iter()
}
pub fn matches_info(&self, info: &BTreeMap<PolynomialLabel, PolynomialInfo>) -> bool {
Some(self.h_2.info()) == info.get(self.h_2.label())
}
}