diff --git a/src/plonk/domain.rs b/src/plonk/domain.rs index 81b74b6..52a79b0 100644 --- a/src/plonk/domain.rs +++ b/src/plonk/domain.rs @@ -1,4 +1,4 @@ -use crate::arithmetic::{best_fft, parallelize, Field, Group}; +use crate::arithmetic::{best_fft, parallelize, BatchInvert, Field, Group}; /// Describes a relative location in the evaluation domain; applying a rotation /// by i will rotate the vector in the evaluation domain by i. @@ -57,24 +57,20 @@ impl EvaluationDomain { extended_omega = extended_omega.square(); } let extended_omega = extended_omega; // 2^{j+k}'th root of unity - let extended_omega_inv = extended_omega.invert().unwrap(); + let mut extended_omega_inv = extended_omega; // Inversion computed later let mut omega = extended_omega; for _ in k..extended_k { omega = omega.square(); } let omega = omega; // 2^{k}'th root of unity - let omega_inv = omega.invert().unwrap(); + let mut omega_inv = omega; // Inversion computed later // We use zeta here because we know it generates a coset, and it's available // already. let g_coset = G::Scalar::ZETA; let g_coset_inv = g_coset.square(); - // TODO: merge these inversions together with t_evaluations batch inversion? - let ifft_divisor = G::Scalar::from_u64(1 << k).invert().unwrap(); - let extended_ifft_divisor = G::Scalar::from_u64(1 << extended_k).invert().unwrap(); - let mut t_evaluations = Vec::with_capacity(1 << (extended_k - k)); { // Compute the evaluations of t(X) in the coset evaluation domain. @@ -97,12 +93,25 @@ impl EvaluationDomain { } // Invert, because we're dividing by this polynomial. - G::Scalar::batch_invert(&mut t_evaluations); + // We invert in a batch, below. } + let mut ifft_divisor = G::Scalar::from_u64(1 << k); // Inversion computed later + let mut extended_ifft_divisor = G::Scalar::from_u64(1 << extended_k); // Inversion computed later + // The barycentric weight of 1 over the evaluation domain // 1 / \prod_{i != 0} (1 - omega^i) - let barycentric_weight = G::Scalar::from(n).invert().unwrap(); + let mut barycentric_weight = G::Scalar::from(n); // Inversion computed later + + // Compute batch inversion + t_evaluations + .iter_mut() + .chain(Some(&mut ifft_divisor)) + .chain(Some(&mut extended_ifft_divisor)) + .chain(Some(&mut barycentric_weight)) + .chain(Some(&mut extended_omega_inv)) + .chain(Some(&mut omega_inv)) + .batch_invert(); EvaluationDomain { n,