pub fn sum_product_over_suffix<F: IsField>(
    factors: &[DenseMultilinearPolynomial<F>],
    prefix: &[FieldElement<F>],
) -> Result<FieldElement<F>, String>
where
    F::BaseType: Send + Sync,
    FieldElement<F>: Clone + Mul<Output = FieldElement<F>>,
{
    let num_total_vars = factors
        .first()
        .ok_or_else(|| "Cannot sum product of zero factors.".to_string())?
        .num_vars();
    let num_prefix_vars = prefix.len();

    if num_prefix_vars > num_total_vars {
        return Err("Prefix length cannot exceed total number of variables.".to_string());
    }

    let num_suffix_vars = num_total_vars - num_prefix_vars;

    (0..(1 << num_suffix_vars))
        .map(|i| {
            let mut current_point = prefix.to_vec();
            current_point.resize(num_total_vars, FieldElement::zero());

            for k in 0..num_suffix_vars {
                if (i >> k) & 1 == 1 {
                    current_point[num_prefix_vars + k] = FieldElement::one();
                } else {
                    current_point[num_prefix_vars + k] = FieldElement::zero();
                }
            }
            current_point
        })
        .map(|current_point| evaluate_product_at_point(factors, &current_point))
        .try_fold(FieldElement::zero(), |acc, result_product_at_point| {
            result_product_at_point.map(|product_at_point| acc + product_at_point)
        })
}
Sum the product of multiple multilinear polynomials over the boolean hypercube for suffix variables.
crates/provers/sumcheck/src/lib.rs