use alloc::vec::Vec;
use crypto::{RandomCoin, RandomCoinError};
use math::{get_power_series, FieldElement};
#[derive(Debug, Clone)]
pub struct ConstraintCompositionCoefficients<E: FieldElement> {
pub transition: Vec<E>,
pub boundary: Vec<E>,
}
impl<E: FieldElement> ConstraintCompositionCoefficients<E> {
fn new(mut coefficients: Vec<E>, num_transition_constraints: usize) -> Self {
let boundary = coefficients.split_off(num_transition_constraints);
let transition = coefficients;
Self { transition, boundary }
}
pub fn draw_linear(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
num_transition_constraints: usize,
num_boundary_constraints: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = num_transition_constraints + num_boundary_constraints;
let coefficients = draw_linear_coefficients(public_coin, num_coefficients)?;
Ok(Self::new(coefficients, num_transition_constraints))
}
pub fn draw_algebraic(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
num_transition_constraints: usize,
num_boundary_constraints: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = num_transition_constraints + num_boundary_constraints;
let coefficients = draw_algebraic_coefficients(public_coin, num_coefficients)?;
Ok(Self::new(coefficients, num_transition_constraints))
}
pub fn draw_horner(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
num_transition_constraints: usize,
num_boundary_constraints: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = num_transition_constraints + num_boundary_constraints;
let mut coefficients = draw_algebraic_coefficients(public_coin, num_coefficients)?;
coefficients.reverse();
Ok(Self::new(coefficients, num_transition_constraints))
}
}
#[derive(Debug, Clone)]
pub struct DeepCompositionCoefficients<E: FieldElement> {
pub trace: Vec<E>,
pub constraints: Vec<E>,
}
impl<E: FieldElement> DeepCompositionCoefficients<E> {
fn new(mut coefficients: Vec<E>, trace_width: usize) -> Self {
let constraints = coefficients.split_off(trace_width);
let trace = coefficients;
Self { trace, constraints }
}
pub fn draw_linear(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
trace_width: usize,
num_constraint_composition_columns: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = trace_width + num_constraint_composition_columns;
let coefficients = draw_linear_coefficients(public_coin, num_coefficients)?;
Ok(Self::new(coefficients, trace_width))
}
pub fn draw_algebraic(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
trace_width: usize,
num_constraint_composition_columns: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = trace_width + num_constraint_composition_columns;
let coefficients = draw_algebraic_coefficients(public_coin, num_coefficients)?;
Ok(Self::new(coefficients, trace_width))
}
pub fn draw_horner(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
trace_width: usize,
num_constraint_composition_columns: usize,
) -> Result<Self, RandomCoinError> {
let num_coefficients = trace_width + num_constraint_composition_columns;
let mut coefficients = draw_algebraic_coefficients(public_coin, num_coefficients)?;
coefficients.reverse();
Ok(Self::new(coefficients, trace_width))
}
}
fn draw_linear_coefficients<E: FieldElement>(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
num_coefficients: usize,
) -> Result<Vec<E>, RandomCoinError> {
(0..num_coefficients).map(|_| public_coin.draw()).collect()
}
fn draw_algebraic_coefficients<E: FieldElement>(
public_coin: &mut impl RandomCoin<BaseField = E::BaseField>,
num_coefficients: usize,
) -> Result<Vec<E>, RandomCoinError> {
let alpha: E = public_coin.draw()?;
Ok(get_power_series(alpha, num_coefficients))
}