This folder contains the fast Fourier transform (FFT) over finite fields (also known as number theoretic transform, NTT). If you are unfamiliar with how lambdaworks handles fields, see examples. Currently, the following algorithms are supported:
- Cooley-Tukey Radix-2
- Cooley-Tukey Radix-4
We are also planning on adding a mixed radix algorithm. To use the FFT, the length of the vector, IsFFTFriendly
trait. The FFT works by recursively breaking a length
Since the main applications of the FFT are related to polynomial evaluation and interpolation, we provide functions describing these operations, which call the FFT under the hood:
evaluate_fft
evaluate_offset_fft
interpolate_fft
interpolate_offset_fft
These functions can be used with univariate polynomials. To use the functions,
let p_1 = Polynomial::new(&[FE::new(3), FE::new(4), FE::new(5) FE::new(6)]);
let evaluations = Polynomial::evaluate_offset_fft(p_1, 4, 4, FE::new(3))?;
Interpolate takes a vector of length
let evaluations = [FE::new(1), FE::new(2), FE::new(3) FE::new(4)];
let poly = Polynomial::interpolate_fft(&evaluations).unwrap();
These building blocks are used, for example, in the computation of the trace polynomials in the STARK protocol. The following function computes the polynomials whose evaluations coincide with the trace columns:
pub fn compute_trace_polys<S>(&self) -> Vec<Polynomial<FieldElement<F>>>
where
S: IsFFTField + IsSubFieldOf<F>,
FieldElement<F>: Send + Sync,
{
let columns = self.columns();
#[cfg(feature = "parallel")]
let iter = columns.par_iter();
#[cfg(not(feature = "parallel"))]
let iter = columns.iter();
iter.map(|col| Polynomial::interpolate_fft::<S>(col))
.collect::<Result<Vec<Polynomial<FieldElement<F>>>, FFTError>>()
.unwrap()
}