use std::sync::Arc;
use crate::{
fft::{
domain::{FFTPrecomputation, IFFTPrecomputation},
DensePolynomial,
EvaluationDomain,
Evaluations as EvaluationsOnDomain,
},
snark::marlin::{
ahp::{indexer::Circuit, verifier},
AHPError,
MarlinMode,
},
};
use snarkvm_fields::PrimeField;
use snarkvm_r1cs::SynthesisError;
pub struct State<'a, F: PrimeField, MM: MarlinMode> {
pub(super) index: &'a Circuit<F, MM>,
pub(super) input_domain: EvaluationDomain<F>,
pub(super) constraint_domain: EvaluationDomain<F>,
pub(super) non_zero_a_domain: EvaluationDomain<F>,
pub(super) non_zero_b_domain: EvaluationDomain<F>,
pub(super) non_zero_c_domain: EvaluationDomain<F>,
pub(in crate::snark) batch_size: usize,
pub(super) padded_public_variables: Vec<Vec<F>>,
pub(super) private_variables: Vec<Vec<F>>,
pub(super) z_a: Option<Vec<Vec<F>>>,
pub(super) z_b: Option<Vec<Vec<F>>>,
pub(super) x_poly: Vec<DensePolynomial<F>>,
pub(in crate::snark) first_round_oracles: Option<Arc<super::FirstOracles<F>>>,
pub(super) mz_poly_randomizer: Option<Vec<F>>,
pub(super) verifier_first_message: Option<verifier::FirstMessage<F>>,
pub(super) lhs_polynomials: Option<[DensePolynomial<F>; 3]>,
pub(super) sums: Option<[F; 3]>,
}
impl<'a, F: PrimeField, MM: MarlinMode> State<'a, F, MM> {
pub fn initialize(
padded_public_input: Vec<Vec<F>>,
private_variables: Vec<Vec<F>>,
index: &'a Circuit<F, MM>,
) -> Result<Self, AHPError> {
let index_info = &index.index_info;
let constraint_domain =
EvaluationDomain::new(index_info.num_constraints).ok_or(SynthesisError::PolynomialDegreeTooLarge)?;
let non_zero_a_domain =
EvaluationDomain::new(index_info.num_non_zero_a).ok_or(SynthesisError::PolynomialDegreeTooLarge)?;
let non_zero_b_domain =
EvaluationDomain::new(index_info.num_non_zero_b).ok_or(SynthesisError::PolynomialDegreeTooLarge)?;
let non_zero_c_domain =
EvaluationDomain::new(index_info.num_non_zero_c).ok_or(SynthesisError::PolynomialDegreeTooLarge)?;
let input_domain =
EvaluationDomain::new(padded_public_input[0].len()).ok_or(SynthesisError::PolynomialDegreeTooLarge)?;
let x_poly = padded_public_input
.iter()
.map(|padded_public_input| {
EvaluationsOnDomain::from_vec_and_domain(padded_public_input.clone(), input_domain).interpolate()
})
.collect();
let batch_size = private_variables.len();
assert_eq!(padded_public_input.len(), batch_size);
Ok(Self {
index,
input_domain,
constraint_domain,
non_zero_a_domain,
non_zero_b_domain,
non_zero_c_domain,
batch_size,
padded_public_variables: padded_public_input,
x_poly,
private_variables,
z_a: None,
z_b: None,
first_round_oracles: None,
mz_poly_randomizer: None,
verifier_first_message: None,
lhs_polynomials: None,
sums: None,
})
}
pub fn batch_size(&self) -> usize {
self.batch_size
}
pub fn public_inputs(&self) -> Vec<Vec<F>> {
self.padded_public_variables.iter().map(|v| super::ConstraintSystem::unformat_public_input(v)).collect()
}
pub fn padded_public_inputs(&self) -> Vec<Vec<F>> {
self.padded_public_variables.clone()
}
pub fn fft_precomputation(&self) -> &FFTPrecomputation<F> {
&self.index.fft_precomputation
}
pub fn ifft_precomputation(&self) -> &IFFTPrecomputation<F> {
&self.index.ifft_precomputation
}
}