diff --git a/src/core/backend/cpu/quotients.rs b/src/core/backend/cpu/quotients.rs index 0e2260d9e..4dac113ca 100644 --- a/src/core/backend/cpu/quotients.rs +++ b/src/core/backend/cpu/quotients.rs @@ -43,8 +43,9 @@ pub fn accumulate_row_quotients( for (column_index, open_value) in &opening.column_indices_and_values { let column = &columns[*column_index]; let value = column[row]; - let linear_term = complex_conjugate_line(opening.point, *open_value, domain_point); - numerator = numerator * random_coeff + value - linear_term; + let current_numerator = + complex_conjugate_line(domain_point, value, opening.point, *open_value); + numerator = numerator * random_coeff + current_numerator; } let denominator = pair_vanishing( diff --git a/src/core/constraints.rs b/src/core/constraints.rs index e9c141992..9d5ecccf9 100644 --- a/src/core/constraints.rs +++ b/src/core/constraints.rs @@ -71,23 +71,23 @@ pub fn point_vanishing, EF: ExtensionOf>( h.y / (EF::one() + h.x) } -/// Evaluates a point on a line between a point and its complex conjugate. -/// Relies on the fact that every polynomial F over the base field holds: -/// F(p*) == F(p)* (* being the complex conjugate). +/// Evaluates a linear function in (domain_point.y, domain_value). +/// This function vanishes on the points +/// (complex_point.y, complex_value), +/// (complex_point.y.conjugate(), complex_value.conjugate()), pub fn complex_conjugate_line( - point: CirclePoint, - value: SecureField, - p: CirclePoint, + domain_point: CirclePoint, + domain_value: BaseField, + complex_point: CirclePoint, + complex_value: SecureField, ) -> SecureField { - // TODO(AlonH): This assertion will fail at a probability of 1 to 2^62. Use a better solution. - assert_ne!( - point.y, - point.y.complex_conjugate(), - "Cannot evaluate a line with a single point ({point:?})." + let (x0, y0) = (domain_point.y, domain_value); + let (x1, y1) = (complex_point.y, complex_value); + let (x2, y2) = ( + complex_point.y.complex_conjugate(), + complex_value.complex_conjugate(), ); - value - + (value.complex_conjugate() - value) * (-point.y + p.y) - / (point.complex_conjugate().y - point.y) + x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1) } #[cfg(test)] @@ -205,7 +205,12 @@ mod tests { // Compute the quotient polynomial. let mut quotient_polynomial_values = Vec::with_capacity(large_domain_size as usize); for point in large_domain.iter() { - let line = complex_conjugate_line(vanish_point, vanish_point_value, point); + let line = complex_conjugate_line( + point, + polynomial.eval_at_point(point), + vanish_point, + vanish_point_value, + ); let mut value = polynomial.eval_at_point(point) - line; value /= pair_vanishing( vanish_point, diff --git a/src/core/mod.rs b/src/core/mod.rs index 47f096fcc..73f912764 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -9,7 +9,6 @@ pub mod constraints; pub mod fft; pub mod fields; pub mod fri; -pub mod oods; pub mod poly; pub mod proof_of_work; pub mod prover; diff --git a/src/core/oods.rs b/src/core/oods.rs deleted file mode 100644 index 129dface6..000000000 --- a/src/core/oods.rs +++ /dev/null @@ -1,56 +0,0 @@ -use itertools::enumerate; - -use super::backend::cpu::CPUCircleEvaluation; -use super::circle::CirclePoint; -use super::constraints::{complex_conjugate_line, pair_vanishing, point_vanishing}; -use super::fields::m31::BaseField; -use super::fields::qm31::SecureField; -use super::fields::ComplexConjugate; -use super::poly::circle::CircleEvaluation; -use super::poly::{BitReversedOrder, NaturalOrder}; -use super::utils::bit_reverse_index; - -/// Evaluates the OODS quotient polynomial on a single point. -pub fn eval_oods_quotient_at_point( - point: CirclePoint, - value: SecureField, - oods_point: CirclePoint, - oods_value: SecureField, -) -> SecureField { - let num = value - oods_value; - let denom: SecureField = point_vanishing(oods_point, point); - num / denom -} - -/// Evaluates the pair OODS quotient polynomial on a single point. -/// See `get_pair_oods_quotient` for more details. -pub fn eval_pair_oods_quotient_at_point( - point: CirclePoint, - value: BaseField, - oods_point: CirclePoint, - oods_value: SecureField, -) -> SecureField { - let num = value - complex_conjugate_line(oods_point, oods_value, point); - let denom = pair_vanishing(oods_point, oods_point.complex_conjugate(), point.into_ef()); - num / denom -} - -/// Returns the OODS quotient polynomial evaluation over the whole domain. -/// Note the resulting polynomial's highest monomial might increase by one. -pub fn get_oods_quotient( - oods_point: CirclePoint, - oods_value: SecureField, - eval: &CPUCircleEvaluation, -) -> CPUCircleEvaluation { - let mut values = Vec::with_capacity(eval.domain.size()); - for (i, point) in enumerate(eval.domain.iter()) { - let index = bit_reverse_index(i, eval.domain.log_size()); - values.push(eval_oods_quotient_at_point( - point, - eval.values[index], - oods_point, - oods_value, - )); - } - CircleEvaluation::new(eval.domain, values) -}