use alloc::vec::Vec; use core::{ f64::consts::PI, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; #[cfg(not(feature = "std"))] use num::Float; use num::{One, Zero}; use num_complex::Complex64; use super::{field::FalconFelt, polynomial::Polynomial, Inverse}; /// Implements Cyclotomic FFT without bitreversing the outputs, and using precomputed powers of the /// 2n-th primitive root of unity. pub trait FastFft: Sized + Clone { type Field: Add + Mul + AddAssign + MulAssign + Neg + Sub + SubAssign; fn fft_inplace(&mut self); fn fft(&self) -> Self { let mut a = self.clone(); a.fft_inplace(); a } fn merge_fft(a: &Self, b: &Self) -> Self; fn split_fft(&self) -> (Self, Self); fn ifft_inplace(&mut self); fn ifft(&self) -> Self { let mut a = self.clone(); a.ifft_inplace(); a } } pub trait CyclotomicFourier where Self: Sized + Copy + One + Zero + Add + Sub + Mul + MulAssign + Inverse, { /// Gets the inverse of 2^n. #[allow(dead_code)] fn power_of_two_inverse(n: usize) -> Self { let mut a = Self::one() + Self::one(); for _ in 0..n { a *= a; } Self::inverse_or_zero(a) } /// Gets a primitive nth (with n a power of 2) root of unity. #[allow(dead_code)] fn primitive_root_of_unity(n: usize) -> Self; /// Computes the integer whose n-bit binary expansion is the reverse of that of the argument. fn bitreverse_index(arg: usize, n: usize) -> usize { assert!(n > 0); assert_eq!(n & (n - 1), 0); let mut rev = 0; let mut m = n >> 1; let mut k = 1; while m > 0 { rev |= (((arg & m) != 0) as usize) * k; k <<= 1; m >>= 1; } rev } /// Computes the first n powers of the 2nd root of unity, and put them in bit-reversed order. #[allow(dead_code)] fn bitreversed_powers(n: usize) -> Vec { let psi = Self::primitive_root_of_unity(2 * n); let mut array = vec![Self::zero(); n]; let mut alpha = Self::one(); for a in array.iter_mut() { *a = alpha; alpha *= psi; } Self::bitreverse_array(&mut array); array } /// Computes the first n powers of the 2nd root of unity, invert them, and put them in /// bit-reversed order. #[allow(dead_code)] fn bitreversed_powers_inverse(n: usize) -> Vec { let psi = Self::primitive_root_of_unity(2 * n).inverse_or_zero(); let mut array = vec![Self::zero(); n]; let mut alpha = Self::one(); for a in array.iter_mut() { *a = alpha; alpha *= psi; } Self::bitreverse_array(&mut array); array } /// Reorders the given elements in the array by reversing the binary expansions of their /// indices. fn bitreverse_array(array: &mut [T]) { let n = array.len(); for i in 0..n { let j = Self::bitreverse_index(i, n); if i < j { array.swap(i, j); } } } /// Computes the evaluations of the polynomial on the roots of the polynomial X^n + 1 using a /// fast Fourier transform. Algorithm 1 from https://eprint.iacr.org/2016/504.pdf. /// /// Arguments: /// /// - a : &mut [Self] (a reference to) a mutable array of field elements which is to be /// transformed under the FFT. The transformation happens in- place. /// /// - psi_rev: &[Self] (a reference to) an array of powers of psi, from 0 to n-1, but ordered /// by bit-reversed index. Here psi is a primitive root of order 2n. You can use /// `Self::bitreversed_powers(psi, n)` for this purpose, but this trait implementation is not /// const. For the performance benefit you want a precompiled array, which you can get if you /// can get by implementing the same method and marking it "const". fn fft(a: &mut [Self], psi_rev: &[Self]) { let n = a.len(); let mut t = n; let mut m = 1; while m < n { t >>= 1; for i in 0..m { let j1 = 2 * i * t; let j2 = j1 + t - 1; let s = psi_rev[m + i]; for j in j1..=j2 { let u = a[j]; let v = a[j + t] * s; a[j] = u + v; a[j + t] = u - v; } } m <<= 1; } } /// Computes the coefficients of the polynomial with the given evaluations on the roots of /// X^n + 1 using an inverse fast Fourier transform. /// Algorithm 2 from https://eprint.iacr.org/2016/504.pdf. /// /// Arguments: /// /// - a : &mut [Self] (a reference to) a mutable array of field elements which is to be /// transformed under the IFFT. The transformation happens in- place. /// /// - psi_inv_rev: &[Self] (a reference to) an array of powers of psi^-1, from 0 to n-1, but /// ordered by bit-reversed index. Here psi is a primitive root of order 2n. You can use /// `Self::bitreversed_powers(Self::inverse_or_zero(psi), n)` for this purpose, but this /// trait implementation is not const. For the performance benefit you want a precompiled /// array, which you can get if you can get by implementing the same methods and marking them /// "const". fn ifft(a: &mut [Self], psi_inv_rev: &[Self], ninv: Self) { let n = a.len(); let mut t = 1; let mut m = n; while m > 1 { let h = m / 2; let mut j1 = 0; for i in 0..h { let j2 = j1 + t - 1; let s = psi_inv_rev[h + i]; for j in j1..=j2 { let u = a[j]; let v = a[j + t]; a[j] = u + v; a[j + t] = (u - v) * s; } j1 += 2 * t; } t <<= 1; m >>= 1; } for ai in a.iter_mut() { *ai *= ninv; } } fn split_fft(f: &[Self], psi_inv_rev: &[Self]) -> (Vec, Vec) { let n_over_2 = f.len() / 2; let mut f0 = vec![Self::zero(); n_over_2]; let mut f1 = vec![Self::zero(); n_over_2]; let two_inv = (Self::one() + Self::one()).inverse_or_zero(); for i in 0..n_over_2 { let two_i = i * 2; let two_zeta_inv = two_inv * psi_inv_rev[n_over_2 + i]; f0[i] = two_inv * (f[two_i] + f[two_i + 1]); f1[i] = two_zeta_inv * (f[two_i] - f[two_i + 1]); } (f0, f1) } fn merge_fft(f0: &[Self], f1: &[Self], psi_rev: &[Self]) -> Vec { let n_over_2 = f0.len(); let n = 2 * n_over_2; let mut f = vec![Self::zero(); n]; for i in 0..n_over_2 { let two_i = i * 2; f[two_i] = f0[i] + psi_rev[n_over_2 + i] * f1[i]; f[two_i + 1] = f0[i] - psi_rev[n_over_2 + i] * f1[i]; } f } } impl CyclotomicFourier for Complex64 { fn primitive_root_of_unity(n: usize) -> Self { let angle = 2. * PI / (n as f64); Complex64::new(f64::cos(angle), f64::sin(angle)) } /// Custom implementation of CyclotomicFourier::bitreversed_powers for /// better precision. fn bitreversed_powers(n: usize) -> Vec { let mut array = vec![Self::zero(); n]; let half_circle = PI; for (i, a) in array.iter_mut().enumerate() { let angle = (i as f64) * half_circle / (n as f64); *a = Self::new(f64::cos(angle), f64::sin(angle)); } Self::bitreverse_array(&mut array); array } /// Custom implementation of CyclotomicFourier::bitreversed_powers_inverse /// for better precision. fn bitreversed_powers_inverse(n: usize) -> Vec { let mut array = vec![Self::zero(); n]; let half_circle = PI; for (i, a) in array.iter_mut().enumerate() { let angle = (i as f64) * half_circle / (n as f64); *a = Self::new(f64::cos(angle), -f64::sin(angle)); } Self::bitreverse_array(&mut array); array } } impl FastFft for Polynomial { type Field = Complex64; fn fft_inplace(&mut self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); Complex64::fft(&mut self.coefficients, &COMPLEX_BITREVERSED_POWERS); } fn ifft_inplace(&mut self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); let psi_inv_rev: Vec = COMPLEX_BITREVERSED_POWERS.iter().map(|c| Complex64::new(c.re, -c.im)).collect(); let ninv = Complex64::new(1.0 / (n as f64), 0.0); Complex64::ifft(&mut self.coefficients, &psi_inv_rev, ninv); } fn merge_fft(a: &Self, b: &Self) -> Self { let n = a.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); Self { coefficients: Self::Field::merge_fft( &a.coefficients, &b.coefficients, &COMPLEX_BITREVERSED_POWERS, ), } } fn split_fft(&self) -> (Self, Self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); let psi_inv_rev: Vec = COMPLEX_BITREVERSED_POWERS.iter().map(|c| Complex64::new(c.re, -c.im)).collect(); let (a, b) = Self::Field::split_fft(&self.coefficients, &psi_inv_rev); (Self { coefficients: a }, Self { coefficients: b }) } } impl FastFft for Polynomial { type Field = FalconFelt; fn fft_inplace(&mut self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); FalconFelt::fft(&mut self.coefficients, &FELT_BITREVERSED_POWERS); } fn ifft_inplace(&mut self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); let ninv = match n { 1 => FELT_NINV_1, 2 => FELT_NINV_2, 4 => FELT_NINV_4, 8 => FELT_NINV_8, 16 => FELT_NINV_16, 32 => FELT_NINV_32, 64 => FELT_NINV_64, 128 => FELT_NINV_128, 256 => FELT_NINV_256, 512 => FELT_NINV_512, _ => unreachable!("vector length is not power of 2 or larger than 512"), }; FalconFelt::ifft(&mut self.coefficients, &FELT_BITREVERSED_POWERS_INVERSE, ninv); } fn merge_fft(a: &Self, b: &Self) -> Self { let n = a.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); Self { coefficients: Self::Field::merge_fft( &a.coefficients, &b.coefficients, &FELT_BITREVERSED_POWERS, ), } } fn split_fft(&self) -> (Self, Self) { let n = self.coefficients.len(); debug_assert!( (1..=512).contains(&n), "unsupported: n = {n} not a power of 2 or larger than 512" ); let (a, b) = Self::Field::split_fft(&self.coefficients, &FELT_BITREVERSED_POWERS_INVERSE); (Self { coefficients: a }, Self { coefficients: b }) } } #[allow(clippy::approx_constant)] const COMPLEX_BITREVERSED_POWERS: [Complex64; 512] = [ Complex64::new(1.0, 0.0), Complex64::new(0.00000000000000006123233995736766, 1.0), Complex64::new(0.7071067811865476, 0.7071067811865475), Complex64::new(-0.7071067811865475, 0.7071067811865476), Complex64::new(0.9238795325112867, 0.3826834323650898), Complex64::new(-0.3826834323650897, 0.9238795325112867), Complex64::new(0.38268343236508984, 0.9238795325112867), Complex64::new(-0.9238795325112867, 0.3826834323650899), Complex64::new(0.9807852804032304, 0.19509032201612825), Complex64::new(-0.1950903220161282, 0.9807852804032304), Complex64::new(0.5555702330196023, 0.8314696123025452), Complex64::new(-0.8314696123025453, 0.5555702330196022), Complex64::new(0.8314696123025452, 0.5555702330196022), Complex64::new(-0.555570233019602, 0.8314696123025455), Complex64::new(0.19509032201612833, 0.9807852804032304), Complex64::new(-0.9807852804032304, 0.1950903220161286), Complex64::new(0.9951847266721969, 0.0980171403295606), Complex64::new(-0.09801714032956065, 0.9951847266721969), Complex64::new(0.6343932841636455, 0.773010453362737), Complex64::new(-0.773010453362737, 0.6343932841636455), Complex64::new(0.881921264348355, 0.47139673682599764), Complex64::new(-0.4713967368259977, 0.881921264348355), Complex64::new(0.29028467725446233, 0.9569403357322089), Complex64::new(-0.9569403357322088, 0.2902846772544624), Complex64::new(0.9569403357322088, 0.29028467725446233), Complex64::new(-0.29028467725446216, 0.9569403357322089), Complex64::new(0.4713967368259978, 0.8819212643483549), Complex64::new(-0.8819212643483549, 0.47139673682599786), Complex64::new(0.773010453362737, 0.6343932841636455), Complex64::new(-0.6343932841636454, 0.7730104533627371), Complex64::new(0.09801714032956077, 0.9951847266721968), Complex64::new(-0.9951847266721968, 0.09801714032956083), Complex64::new(0.9987954562051724, 0.049067674327418015), Complex64::new(-0.04906767432741801, 0.9987954562051724), Complex64::new(0.6715589548470183, 0.7409511253549591), Complex64::new(-0.7409511253549589, 0.6715589548470186), Complex64::new(0.9039892931234433, 0.4275550934302821), Complex64::new(-0.42755509343028186, 0.9039892931234434), Complex64::new(0.33688985339222005, 0.9415440651830208), Complex64::new(-0.9415440651830207, 0.33688985339222033), Complex64::new(0.970031253194544, 0.24298017990326387), Complex64::new(-0.24298017990326387, 0.970031253194544), Complex64::new(0.5141027441932217, 0.8577286100002721), Complex64::new(-0.857728610000272, 0.5141027441932218), Complex64::new(0.8032075314806449, 0.5956993044924334), Complex64::new(-0.5956993044924334, 0.8032075314806449), Complex64::new(0.14673047445536175, 0.989176509964781), Complex64::new(-0.989176509964781, 0.1467304744553618), Complex64::new(0.989176509964781, 0.14673047445536175), Complex64::new(-0.14673047445536164, 0.989176509964781), Complex64::new(0.5956993044924335, 0.8032075314806448), Complex64::new(-0.8032075314806448, 0.5956993044924335), Complex64::new(0.8577286100002721, 0.5141027441932217), Complex64::new(-0.5141027441932217, 0.8577286100002721), Complex64::new(0.24298017990326398, 0.970031253194544), Complex64::new(-0.970031253194544, 0.24298017990326407), Complex64::new(0.9415440651830208, 0.33688985339222005), Complex64::new(-0.33688985339221994, 0.9415440651830208), Complex64::new(0.4275550934302822, 0.9039892931234433), Complex64::new(-0.9039892931234433, 0.42755509343028203), Complex64::new(0.7409511253549591, 0.6715589548470183), Complex64::new(-0.6715589548470184, 0.740951125354959), Complex64::new(0.049067674327418126, 0.9987954562051724), Complex64::new(-0.9987954562051724, 0.049067674327417966), Complex64::new(0.9996988186962042, 0.024541228522912288), Complex64::new(-0.024541228522912142, 0.9996988186962042), Complex64::new(0.6895405447370669, 0.7242470829514669), Complex64::new(-0.7242470829514668, 0.689540544737067), Complex64::new(0.9142097557035307, 0.40524131400498986), Complex64::new(-0.40524131400498975, 0.9142097557035307), Complex64::new(0.3598950365349883, 0.9329927988347388), Complex64::new(-0.9329927988347388, 0.35989503653498833), Complex64::new(0.9757021300385286, 0.2191012401568698), Complex64::new(-0.21910124015686966, 0.9757021300385286), Complex64::new(0.5349976198870973, 0.844853565249707), Complex64::new(-0.8448535652497071, 0.5349976198870972), Complex64::new(0.8175848131515837, 0.5758081914178453), Complex64::new(-0.5758081914178453, 0.8175848131515837), Complex64::new(0.17096188876030136, 0.9852776423889412), Complex64::new(-0.9852776423889412, 0.17096188876030122), Complex64::new(0.99247953459871, 0.1224106751992162), Complex64::new(-0.12241067519921615, 0.99247953459871), Complex64::new(0.6152315905806268, 0.7883464276266062), Complex64::new(-0.7883464276266062, 0.6152315905806269), Complex64::new(0.8700869911087115, 0.49289819222978404), Complex64::new(-0.492898192229784, 0.8700869911087115), Complex64::new(0.2667127574748984, 0.9637760657954398), Complex64::new(-0.9637760657954398, 0.2667127574748985), Complex64::new(0.9495281805930367, 0.3136817403988915), Complex64::new(-0.3136817403988914, 0.9495281805930367), Complex64::new(0.4496113296546066, 0.8932243011955153), Complex64::new(-0.8932243011955152, 0.4496113296546069), Complex64::new(0.7572088465064846, 0.6531728429537768), Complex64::new(-0.6531728429537765, 0.7572088465064847), Complex64::new(0.07356456359966745, 0.9972904566786902), Complex64::new(-0.9972904566786902, 0.07356456359966773), Complex64::new(0.9972904566786902, 0.07356456359966743), Complex64::new(-0.07356456359966733, 0.9972904566786902), Complex64::new(0.6531728429537768, 0.7572088465064845), Complex64::new(-0.7572088465064846, 0.6531728429537766), Complex64::new(0.8932243011955153, 0.44961132965460654), Complex64::new(-0.4496113296546067, 0.8932243011955152), Complex64::new(0.3136817403988916, 0.9495281805930367), Complex64::new(-0.9495281805930367, 0.3136817403988914), Complex64::new(0.9637760657954398, 0.26671275747489837), Complex64::new(-0.2667127574748983, 0.9637760657954398), Complex64::new(0.4928981922297841, 0.8700869911087113), Complex64::new(-0.8700869911087113, 0.49289819222978415), Complex64::new(0.7883464276266063, 0.6152315905806268), Complex64::new(-0.6152315905806267, 0.7883464276266063), Complex64::new(0.12241067519921628, 0.99247953459871), Complex64::new(-0.99247953459871, 0.12241067519921635), Complex64::new(0.9852776423889412, 0.17096188876030122), Complex64::new(-0.17096188876030124, 0.9852776423889412), Complex64::new(0.5758081914178453, 0.8175848131515837), Complex64::new(-0.8175848131515836, 0.5758081914178454), Complex64::new(0.8448535652497071, 0.5349976198870972), Complex64::new(-0.534997619887097, 0.8448535652497072), Complex64::new(0.21910124015686977, 0.9757021300385286), Complex64::new(-0.9757021300385285, 0.21910124015687005), Complex64::new(0.932992798834739, 0.3598950365349881), Complex64::new(-0.35989503653498817, 0.9329927988347388), Complex64::new(0.40524131400498986, 0.9142097557035307), Complex64::new(-0.9142097557035307, 0.4052413140049899), Complex64::new(0.724247082951467, 0.6895405447370668), Complex64::new(-0.6895405447370669, 0.7242470829514669), Complex64::new(0.024541228522912264, 0.9996988186962042), Complex64::new(-0.9996988186962042, 0.024541228522912326), Complex64::new(0.9999247018391445, 0.012271538285719925), Complex64::new(-0.012271538285719823, 0.9999247018391445), Complex64::new(0.6983762494089729, 0.7157308252838186), Complex64::new(-0.7157308252838186, 0.6983762494089729), Complex64::new(0.9191138516900578, 0.3939920400610481), Complex64::new(-0.393992040061048, 0.9191138516900578), Complex64::new(0.3713171939518376, 0.9285060804732155), Complex64::new(-0.9285060804732155, 0.3713171939518377), Complex64::new(0.9783173707196277, 0.20711137619221856), Complex64::new(-0.20711137619221845, 0.9783173707196277), Complex64::new(0.5453249884220465, 0.838224705554838), Complex64::new(-0.8382247055548381, 0.5453249884220464), Complex64::new(0.8245893027850253, 0.5657318107836131), Complex64::new(-0.5657318107836132, 0.8245893027850252), Complex64::new(0.18303988795514106, 0.9831054874312163), Complex64::new(-0.9831054874312163, 0.1830398879551409), Complex64::new(0.9939069700023561, 0.11022220729388306), Complex64::new(-0.11022220729388306, 0.9939069700023561), Complex64::new(0.6248594881423865, 0.7807372285720944), Complex64::new(-0.7807372285720945, 0.6248594881423863), Complex64::new(0.8760700941954066, 0.4821837720791227), Complex64::new(-0.4821837720791227, 0.8760700941954066), Complex64::new(0.27851968938505306, 0.9604305194155658), Complex64::new(-0.9604305194155658, 0.27851968938505317), Complex64::new(0.9533060403541939, 0.3020059493192281), Complex64::new(-0.3020059493192281, 0.9533060403541939), Complex64::new(0.46053871095824, 0.8876396204028539), Complex64::new(-0.8876396204028538, 0.4605387109582402), Complex64::new(0.765167265622459, 0.6438315428897914), Complex64::new(-0.6438315428897913, 0.7651672656224591), Complex64::new(0.08579731234443988, 0.996312612182778), Complex64::new(-0.996312612182778, 0.08579731234444016), Complex64::new(0.9981181129001492, 0.06132073630220858), Complex64::new(-0.06132073630220853, 0.9981181129001492), Complex64::new(0.6624157775901718, 0.7491363945234593), Complex64::new(-0.7491363945234591, 0.662415777590172), Complex64::new(0.8986744656939538, 0.43861623853852766), Complex64::new(-0.4386162385385274, 0.8986744656939539), Complex64::new(0.325310292162263, 0.9456073253805213), Complex64::new(-0.9456073253805212, 0.32531029216226326), Complex64::new(0.9669764710448521, 0.25486565960451457), Complex64::new(-0.2548656596045145, 0.9669764710448521), Complex64::new(0.5035383837257176, 0.8639728561215867), Complex64::new(-0.8639728561215867, 0.5035383837257177), Complex64::new(0.7958369046088836, 0.6055110414043255), Complex64::new(-0.6055110414043254, 0.7958369046088836), Complex64::new(0.13458070850712622, 0.99090263542778), Complex64::new(-0.99090263542778, 0.13458070850712628), Complex64::new(0.9873014181578584, 0.15885814333386145), Complex64::new(-0.15885814333386128, 0.9873014181578584), Complex64::new(0.5857978574564389, 0.8104571982525948), Complex64::new(-0.8104571982525947, 0.585797857456439), Complex64::new(0.8513551931052652, 0.524589682678469), Complex64::new(-0.5245896826784687, 0.8513551931052652), Complex64::new(0.23105810828067128, 0.9729399522055601), Complex64::new(-0.9729399522055601, 0.23105810828067133), Complex64::new(0.937339011912575, 0.34841868024943456), Complex64::new(-0.3484186802494344, 0.937339011912575), Complex64::new(0.4164295600976373, 0.9091679830905223), Complex64::new(-0.9091679830905224, 0.41642956009763715), Complex64::new(0.7326542716724128, 0.680600997795453), Complex64::new(-0.680600997795453, 0.7326542716724128), Complex64::new(0.03680722294135899, 0.9993223845883495), Complex64::new(-0.9993223845883495, 0.03680722294135883), Complex64::new(0.9993223845883495, 0.03680722294135883), Complex64::new(-0.036807222941358866, 0.9993223845883495), Complex64::new(0.6806009977954531, 0.7326542716724128), Complex64::new(-0.7326542716724127, 0.6806009977954532), Complex64::new(0.9091679830905224, 0.41642956009763715), Complex64::new(-0.416429560097637, 0.9091679830905225), Complex64::new(0.3484186802494345, 0.937339011912575), Complex64::new(-0.9373390119125748, 0.3484186802494348), Complex64::new(0.9729399522055602, 0.2310581082806711), Complex64::new(-0.23105810828067114, 0.9729399522055602), Complex64::new(0.5245896826784688, 0.8513551931052652), Complex64::new(-0.8513551931052652, 0.524589682678469), Complex64::new(0.8104571982525948, 0.5857978574564389), Complex64::new(-0.5857978574564389, 0.8104571982525948), Complex64::new(0.1588581433338614, 0.9873014181578584), Complex64::new(-0.9873014181578584, 0.15885814333386147), Complex64::new(0.99090263542778, 0.13458070850712617), Complex64::new(-0.1345807085071261, 0.99090263542778), Complex64::new(0.6055110414043255, 0.7958369046088835), Complex64::new(-0.7958369046088835, 0.6055110414043257), Complex64::new(0.8639728561215868, 0.5035383837257176), Complex64::new(-0.5035383837257175, 0.8639728561215868), Complex64::new(0.2548656596045146, 0.9669764710448521), Complex64::new(-0.9669764710448521, 0.2548656596045147), Complex64::new(0.9456073253805213, 0.3253102921622629), Complex64::new(-0.32531029216226287, 0.9456073253805214), Complex64::new(0.4386162385385277, 0.8986744656939538), Complex64::new(-0.8986744656939539, 0.43861623853852755), Complex64::new(0.7491363945234594, 0.6624157775901718), Complex64::new(-0.6624157775901719, 0.7491363945234593), Complex64::new(0.06132073630220865, 0.9981181129001492), Complex64::new(-0.9981181129001492, 0.06132073630220849), Complex64::new(0.996312612182778, 0.0857973123444399), Complex64::new(-0.08579731234443976, 0.996312612182778), Complex64::new(0.6438315428897915, 0.765167265622459), Complex64::new(-0.765167265622459, 0.6438315428897914), Complex64::new(0.8876396204028539, 0.46053871095824), Complex64::new(-0.46053871095824006, 0.8876396204028539), Complex64::new(0.3020059493192282, 0.9533060403541938), Complex64::new(-0.9533060403541939, 0.30200594931922803), Complex64::new(0.9604305194155658, 0.27851968938505306), Complex64::new(-0.27851968938505295, 0.9604305194155659), Complex64::new(0.48218377207912283, 0.8760700941954066), Complex64::new(-0.8760700941954065, 0.4821837720791229), Complex64::new(0.7807372285720945, 0.6248594881423863), Complex64::new(-0.6248594881423862, 0.7807372285720946), Complex64::new(0.11022220729388318, 0.9939069700023561), Complex64::new(-0.9939069700023561, 0.11022220729388324), Complex64::new(0.9831054874312163, 0.18303988795514095), Complex64::new(-0.18303988795514092, 0.9831054874312163), Complex64::new(0.5657318107836132, 0.8245893027850253), Complex64::new(-0.8245893027850251, 0.5657318107836135), Complex64::new(0.8382247055548381, 0.5453249884220465), Complex64::new(-0.5453249884220462, 0.8382247055548382), Complex64::new(0.20711137619221856, 0.9783173707196277), Complex64::new(-0.9783173707196275, 0.20711137619221884), Complex64::new(0.9285060804732156, 0.37131719395183754), Complex64::new(-0.3713171939518375, 0.9285060804732156), Complex64::new(0.3939920400610481, 0.9191138516900578), Complex64::new(-0.9191138516900578, 0.39399204006104815), Complex64::new(0.7157308252838186, 0.6983762494089729), Complex64::new(-0.6983762494089728, 0.7157308252838187), Complex64::new(0.012271538285719944, 0.9999247018391445), Complex64::new(-0.9999247018391445, 0.012271538285720007), Complex64::new(0.9999811752826011, 0.006135884649154475), Complex64::new(-0.006135884649154393, 0.9999811752826011), Complex64::new(0.7027547444572253, 0.7114321957452164), Complex64::new(-0.7114321957452165, 0.7027547444572252), Complex64::new(0.921514039342042, 0.38834504669882625), Complex64::new(-0.3883450466988262, 0.921514039342042), Complex64::new(0.3770074102164183, 0.9262102421383113), Complex64::new(-0.9262102421383114, 0.37700741021641815), Complex64::new(0.9795697656854405, 0.2011046348420919), Complex64::new(-0.20110463484209182, 0.9795697656854405), Complex64::new(0.5504579729366048, 0.83486287498638), Complex64::new(-0.83486287498638, 0.5504579729366049), Complex64::new(0.8280450452577558, 0.560661576197336), Complex64::new(-0.5606615761973359, 0.8280450452577558), Complex64::new(0.18906866414980628, 0.9819638691095552), Complex64::new(-0.9819638691095552, 0.18906866414980636), Complex64::new(0.9945645707342554, 0.10412163387205459), Complex64::new(-0.1041216338720546, 0.9945645707342554), Complex64::new(0.6296382389149271, 0.7768884656732324), Complex64::new(-0.7768884656732323, 0.6296382389149272), Complex64::new(0.8790122264286335, 0.4767992300633221), Complex64::new(-0.4767992300633219, 0.8790122264286335), Complex64::new(0.2844075372112718, 0.9587034748958716), Complex64::new(-0.9587034748958715, 0.2844075372112721), Complex64::new(0.9551411683057708, 0.2961508882436238), Complex64::new(-0.29615088824362384, 0.9551411683057707), Complex64::new(0.4659764957679661, 0.8847970984309378), Complex64::new(-0.8847970984309378, 0.4659764957679662), Complex64::new(0.7691033376455797, 0.6391244448637757), Complex64::new(-0.6391244448637757, 0.7691033376455796), Complex64::new(0.0919089564971327, 0.9957674144676598), Complex64::new(-0.9957674144676598, 0.09190895649713275), Complex64::new(0.9984755805732948, 0.055195244349689934), Complex64::new(-0.05519524434968991, 0.9984755805732948), Complex64::new(0.6669999223036375, 0.745057785441466), Complex64::new(-0.745057785441466, 0.6669999223036376), Complex64::new(0.901348847046022, 0.43309381885315196), Complex64::new(-0.4330938188531519, 0.901348847046022), Complex64::new(0.33110630575987643, 0.9435934581619604), Complex64::new(-0.9435934581619604, 0.3311063057598765), Complex64::new(0.9685220942744174, 0.24892760574572015), Complex64::new(-0.24892760574572012, 0.9685220942744174), Complex64::new(0.508830142543107, 0.8608669386377673), Complex64::new(-0.8608669386377671, 0.5088301425431073), Complex64::new(0.799537269107905, 0.600616479383869), Complex64::new(-0.6006164793838688, 0.7995372691079052), Complex64::new(0.14065823933284924, 0.9900582102622971), Complex64::new(-0.990058210262297, 0.14065823933284954), Complex64::new(0.9882575677307495, 0.15279718525844344), Complex64::new(-0.1527971852584433, 0.9882575677307495), Complex64::new(0.5907597018588743, 0.8068475535437992), Complex64::new(-0.8068475535437993, 0.5907597018588742), Complex64::new(0.8545579883654005, 0.5193559901655896), Complex64::new(-0.5193559901655896, 0.8545579883654005), Complex64::new(0.23702360599436734, 0.9715038909862518), Complex64::new(-0.9715038909862518, 0.23702360599436717), Complex64::new(0.9394592236021899, 0.3426607173119944), Complex64::new(-0.34266071731199427, 0.9394592236021899), Complex64::new(0.4220002707997998, 0.9065957045149153), Complex64::new(-0.9065957045149153, 0.42200027079979985), Complex64::new(0.7368165688773699, 0.6760927035753159), Complex64::new(-0.6760927035753158, 0.73681656887737), Complex64::new(0.04293825693494096, 0.9990777277526454), Complex64::new(-0.9990777277526454, 0.04293825693494102), Complex64::new(0.9995294175010931, 0.030674803176636626), Complex64::new(-0.03067480317663646, 0.9995294175010931), Complex64::new(0.6850836677727004, 0.7284643904482252), Complex64::new(-0.7284643904482252, 0.6850836677727004), Complex64::new(0.9117060320054299, 0.4108431710579039), Complex64::new(-0.4108431710579038, 0.9117060320054299), Complex64::new(0.3541635254204905, 0.9351835099389475), Complex64::new(-0.9351835099389476, 0.3541635254204904), Complex64::new(0.9743393827855759, 0.22508391135979283), Complex64::new(-0.22508391135979267, 0.9743393827855759), Complex64::new(0.5298036246862948, 0.8481203448032971), Complex64::new(-0.8481203448032971, 0.5298036246862948), Complex64::new(0.8140363297059484, 0.5808139580957645), Complex64::new(-0.5808139580957644, 0.8140363297059485), Complex64::new(0.1649131204899701, 0.9863080972445987), Complex64::new(-0.9863080972445986, 0.16491312048997014), Complex64::new(0.9917097536690995, 0.12849811079379317), Complex64::new(-0.1284981107937931, 0.9917097536690995), Complex64::new(0.6103828062763095, 0.7921065773002124), Complex64::new(-0.7921065773002122, 0.6103828062763097), Complex64::new(0.8670462455156926, 0.49822766697278187), Complex64::new(-0.4982276669727816, 0.8670462455156928), Complex64::new(0.26079411791527557, 0.9653944416976894), Complex64::new(-0.9653944416976893, 0.26079411791527585), Complex64::new(0.9475855910177411, 0.3195020308160157), Complex64::new(-0.31950203081601564, 0.9475855910177412), Complex64::new(0.44412214457042926, 0.8959662497561851), Complex64::new(-0.8959662497561851, 0.4441221445704293), Complex64::new(0.7531867990436125, 0.6578066932970786), Complex64::new(-0.6578066932970786, 0.7531867990436125), Complex64::new(0.0674439195636641, 0.9977230666441916), Complex64::new(-0.9977230666441916, 0.06744391956366418), Complex64::new(0.9968202992911657, 0.07968243797143013), Complex64::new(-0.07968243797143001, 0.9968202992911658), Complex64::new(0.6485144010221126, 0.7612023854842618), Complex64::new(-0.7612023854842617, 0.6485144010221126), Complex64::new(0.8904487232447579, 0.45508358712634384), Complex64::new(-0.4550835871263437, 0.890448723244758), Complex64::new(0.307849640041535, 0.9514350209690083), Complex64::new(-0.9514350209690083, 0.30784964004153503), Complex64::new(0.9621214042690416, 0.272621355449949), Complex64::new(-0.27262135544994887, 0.9621214042690416), Complex64::new(0.48755016014843605, 0.8730949784182901), Complex64::new(-0.8730949784182901, 0.4875501601484359), Complex64::new(0.7845565971555752, 0.6200572117632891), Complex64::new(-0.6200572117632892, 0.7845565971555751), Complex64::new(0.11631863091190488, 0.9932119492347945), Complex64::new(-0.9932119492347945, 0.11631863091190471), Complex64::new(0.984210092386929, 0.17700422041214875), Complex64::new(-0.17700422041214875, 0.984210092386929), Complex64::new(0.5707807458869674, 0.8211025149911046), Complex64::new(-0.8211025149911046, 0.5707807458869673), Complex64::new(0.8415549774368984, 0.5401714727298929), Complex64::new(-0.5401714727298929, 0.8415549774368984), Complex64::new(0.21311031991609136, 0.9770281426577544), Complex64::new(-0.9770281426577544, 0.21311031991609142), Complex64::new(0.9307669610789837, 0.36561299780477385), Complex64::new(-0.36561299780477385, 0.9307669610789837), Complex64::new(0.3996241998456468, 0.9166790599210427), Complex64::new(-0.9166790599210426, 0.39962419984564707), Complex64::new(0.7200025079613817, 0.693971460889654), Complex64::new(-0.6939714608896538, 0.7200025079613818), Complex64::new(0.01840672990580482, 0.9998305817958234), Complex64::new(-0.9998305817958234, 0.0184067299058051), Complex64::new(0.9998305817958234, 0.01840672990580482), Complex64::new(-0.018406729905804695, 0.9998305817958234), Complex64::new(0.693971460889654, 0.7200025079613817), Complex64::new(-0.7200025079613817, 0.693971460889654), Complex64::new(0.9166790599210427, 0.3996241998456468), Complex64::new(-0.3996241998456467, 0.9166790599210427), Complex64::new(0.36561299780477396, 0.9307669610789837), Complex64::new(-0.9307669610789837, 0.3656129978047738), Complex64::new(0.9770281426577544, 0.21311031991609136), Complex64::new(-0.21311031991609125, 0.9770281426577544), Complex64::new(0.540171472729893, 0.8415549774368983), Complex64::new(-0.8415549774368983, 0.540171472729893), Complex64::new(0.8211025149911046, 0.5707807458869673), Complex64::new(-0.5707807458869671, 0.8211025149911048), Complex64::new(0.17700422041214886, 0.984210092386929), Complex64::new(-0.984210092386929, 0.17700422041214894), Complex64::new(0.9932119492347945, 0.11631863091190475), Complex64::new(-0.11631863091190475, 0.9932119492347945), Complex64::new(0.6200572117632892, 0.7845565971555752), Complex64::new(-0.784556597155575, 0.6200572117632894), Complex64::new(0.8730949784182901, 0.487550160148436), Complex64::new(-0.4875501601484357, 0.8730949784182902), Complex64::new(0.272621355449949, 0.9621214042690416), Complex64::new(-0.9621214042690415, 0.27262135544994925), Complex64::new(0.9514350209690083, 0.30784964004153487), Complex64::new(-0.30784964004153487, 0.9514350209690083), Complex64::new(0.45508358712634384, 0.8904487232447579), Complex64::new(-0.8904487232447579, 0.4550835871263439), Complex64::new(0.7612023854842618, 0.6485144010221124), Complex64::new(-0.6485144010221124, 0.7612023854842619), Complex64::new(0.07968243797143013, 0.9968202992911657), Complex64::new(-0.9968202992911657, 0.0796824379714302), Complex64::new(0.9977230666441916, 0.06744391956366405), Complex64::new(-0.06744391956366398, 0.9977230666441916), Complex64::new(0.6578066932970786, 0.7531867990436124), Complex64::new(-0.7531867990436124, 0.6578066932970787), Complex64::new(0.8959662497561852, 0.4441221445704292), Complex64::new(-0.44412214457042914, 0.8959662497561852), Complex64::new(0.31950203081601575, 0.9475855910177411), Complex64::new(-0.9475855910177411, 0.3195020308160158), Complex64::new(0.9653944416976894, 0.2607941179152755), Complex64::new(-0.26079411791527546, 0.9653944416976894), Complex64::new(0.49822766697278187, 0.8670462455156926), Complex64::new(-0.8670462455156928, 0.49822766697278176), Complex64::new(0.7921065773002124, 0.6103828062763095), Complex64::new(-0.6103828062763096, 0.7921065773002123), Complex64::new(0.12849811079379322, 0.9917097536690995), Complex64::new(-0.9917097536690995, 0.12849811079379309), Complex64::new(0.9863080972445987, 0.16491312048996992), Complex64::new(-0.16491312048996995, 0.9863080972445987), Complex64::new(0.5808139580957645, 0.8140363297059483), Complex64::new(-0.8140363297059484, 0.5808139580957645), Complex64::new(0.8481203448032972, 0.5298036246862946), Complex64::new(-0.5298036246862947, 0.8481203448032972), Complex64::new(0.22508391135979278, 0.9743393827855759), Complex64::new(-0.9743393827855759, 0.22508391135979283), Complex64::new(0.9351835099389476, 0.35416352542049034), Complex64::new(-0.3541635254204904, 0.9351835099389476), Complex64::new(0.4108431710579039, 0.9117060320054299), Complex64::new(-0.9117060320054298, 0.41084317105790413), Complex64::new(0.7284643904482252, 0.6850836677727004), Complex64::new(-0.6850836677727002, 0.7284643904482253), Complex64::new(0.03067480317663658, 0.9995294175010931), Complex64::new(-0.9995294175010931, 0.030674803176636865), Complex64::new(0.9990777277526454, 0.04293825693494082), Complex64::new(-0.042938256934940834, 0.9990777277526454), Complex64::new(0.676092703575316, 0.7368165688773698), Complex64::new(-0.7368165688773699, 0.6760927035753159), Complex64::new(0.9065957045149153, 0.4220002707997997), Complex64::new(-0.4220002707997997, 0.9065957045149153), Complex64::new(0.3426607173119944, 0.9394592236021899), Complex64::new(-0.9394592236021899, 0.34266071731199443), Complex64::new(0.9715038909862518, 0.2370236059943672), Complex64::new(-0.23702360599436723, 0.9715038909862518), Complex64::new(0.5193559901655895, 0.8545579883654005), Complex64::new(-0.8545579883654004, 0.5193559901655898), Complex64::new(0.8068475535437993, 0.5907597018588742), Complex64::new(-0.590759701858874, 0.8068475535437994), Complex64::new(0.1527971852584434, 0.9882575677307495), Complex64::new(-0.9882575677307495, 0.15279718525844369), Complex64::new(0.9900582102622971, 0.1406582393328492), Complex64::new(-0.14065823933284913, 0.9900582102622971), Complex64::new(0.600616479383869, 0.799537269107905), Complex64::new(-0.7995372691079051, 0.6006164793838689), Complex64::new(0.8608669386377673, 0.508830142543107), Complex64::new(-0.5088301425431071, 0.8608669386377672), Complex64::new(0.24892760574572026, 0.9685220942744173), Complex64::new(-0.9685220942744174, 0.2489276057457201), Complex64::new(0.9435934581619604, 0.33110630575987643), Complex64::new(-0.3311063057598763, 0.9435934581619604), Complex64::new(0.433093818853152, 0.901348847046022), Complex64::new(-0.9013488470460219, 0.43309381885315207), Complex64::new(0.7450577854414661, 0.6669999223036375), Complex64::new(-0.6669999223036374, 0.7450577854414661), Complex64::new(0.05519524434969003, 0.9984755805732948), Complex64::new(-0.9984755805732948, 0.055195244349690094), Complex64::new(0.9957674144676598, 0.09190895649713272), Complex64::new(-0.09190895649713257, 0.9957674144676598), Complex64::new(0.6391244448637757, 0.7691033376455796), Complex64::new(-0.7691033376455795, 0.6391244448637758), Complex64::new(0.8847970984309378, 0.4659764957679662), Complex64::new(-0.465976495767966, 0.8847970984309379), Complex64::new(0.29615088824362396, 0.9551411683057707), Complex64::new(-0.9551411683057707, 0.296150888243624), Complex64::new(0.9587034748958716, 0.2844075372112719), Complex64::new(-0.2844075372112717, 0.9587034748958716), Complex64::new(0.47679923006332225, 0.8790122264286334), Complex64::new(-0.8790122264286335, 0.4767992300633221), Complex64::new(0.7768884656732324, 0.629638238914927), Complex64::new(-0.6296382389149271, 0.7768884656732324), Complex64::new(0.10412163387205473, 0.9945645707342554), Complex64::new(-0.9945645707342554, 0.10412163387205457), Complex64::new(0.9819638691095552, 0.1890686641498062), Complex64::new(-0.18906866414980616, 0.9819638691095552), Complex64::new(0.560661576197336, 0.8280450452577558), Complex64::new(-0.8280450452577557, 0.5606615761973361), Complex64::new(0.83486287498638, 0.5504579729366048), Complex64::new(-0.5504579729366047, 0.8348628749863801), Complex64::new(0.20110463484209196, 0.9795697656854405), Complex64::new(-0.9795697656854405, 0.201104634842092), Complex64::new(0.9262102421383114, 0.37700741021641826), Complex64::new(-0.3770074102164182, 0.9262102421383114), Complex64::new(0.3883450466988263, 0.9215140393420419), Complex64::new(-0.9215140393420418, 0.3883450466988266), Complex64::new(0.7114321957452164, 0.7027547444572253), Complex64::new(-0.7027547444572251, 0.7114321957452167), Complex64::new(0.006135884649154515, 0.9999811752826011), Complex64::new(-0.9999811752826011, 0.006135884649154799), ]; const FELT_BITREVERSED_POWERS: [FalconFelt; 512] = [ FalconFelt::new(1), FalconFelt::new(1479), FalconFelt::new(8246), FalconFelt::new(5146), FalconFelt::new(4134), FalconFelt::new(6553), FalconFelt::new(11567), FalconFelt::new(1305), FalconFelt::new(5860), FalconFelt::new(3195), FalconFelt::new(1212), FalconFelt::new(10643), FalconFelt::new(3621), FalconFelt::new(9744), FalconFelt::new(8785), FalconFelt::new(3542), FalconFelt::new(7311), FalconFelt::new(10938), FalconFelt::new(8961), FalconFelt::new(5777), FalconFelt::new(5023), FalconFelt::new(6461), FalconFelt::new(5728), FalconFelt::new(4591), FalconFelt::new(3006), FalconFelt::new(9545), FalconFelt::new(563), FalconFelt::new(9314), FalconFelt::new(2625), FalconFelt::new(11340), FalconFelt::new(4821), FalconFelt::new(2639), FalconFelt::new(12149), FalconFelt::new(1853), FalconFelt::new(726), FalconFelt::new(4611), FalconFelt::new(11112), FalconFelt::new(4255), FalconFelt::new(2768), FalconFelt::new(1635), FalconFelt::new(2963), FalconFelt::new(7393), FalconFelt::new(2366), FalconFelt::new(9238), FalconFelt::new(9198), FalconFelt::new(12208), FalconFelt::new(11289), FalconFelt::new(7969), FalconFelt::new(8736), FalconFelt::new(4805), FalconFelt::new(11227), FalconFelt::new(2294), FalconFelt::new(9542), FalconFelt::new(4846), FalconFelt::new(9154), FalconFelt::new(8577), FalconFelt::new(9275), FalconFelt::new(3201), FalconFelt::new(7203), FalconFelt::new(10963), FalconFelt::new(1170), FalconFelt::new(9970), FalconFelt::new(955), FalconFelt::new(11499), FalconFelt::new(8340), FalconFelt::new(8993), FalconFelt::new(2396), FalconFelt::new(4452), FalconFelt::new(6915), FalconFelt::new(2837), FalconFelt::new(130), FalconFelt::new(7935), FalconFelt::new(11336), FalconFelt::new(3748), FalconFelt::new(6522), FalconFelt::new(11462), FalconFelt::new(5067), FalconFelt::new(10092), FalconFelt::new(12171), FalconFelt::new(9813), FalconFelt::new(8011), FalconFelt::new(1673), FalconFelt::new(5331), FalconFelt::new(7300), FalconFelt::new(10908), FalconFelt::new(9764), FalconFelt::new(4177), FalconFelt::new(8705), FalconFelt::new(480), FalconFelt::new(9447), FalconFelt::new(1022), FalconFelt::new(12280), FalconFelt::new(5791), FalconFelt::new(11745), FalconFelt::new(9821), FalconFelt::new(11950), FalconFelt::new(12144), FalconFelt::new(6747), FalconFelt::new(8652), FalconFelt::new(3459), FalconFelt::new(2731), FalconFelt::new(8357), FalconFelt::new(6378), FalconFelt::new(7399), FalconFelt::new(10530), FalconFelt::new(3707), FalconFelt::new(8595), FalconFelt::new(5179), FalconFelt::new(3382), FalconFelt::new(355), FalconFelt::new(4231), FalconFelt::new(2548), FalconFelt::new(9048), FalconFelt::new(11560), FalconFelt::new(3289), FalconFelt::new(10276), FalconFelt::new(9005), FalconFelt::new(9408), FalconFelt::new(5092), FalconFelt::new(10200), FalconFelt::new(6534), FalconFelt::new(4632), FalconFelt::new(4388), FalconFelt::new(1260), FalconFelt::new(334), FalconFelt::new(2426), FalconFelt::new(1428), FalconFelt::new(10593), FalconFelt::new(3400), FalconFelt::new(2399), FalconFelt::new(5191), FalconFelt::new(9153), FalconFelt::new(9273), FalconFelt::new(243), FalconFelt::new(3000), FalconFelt::new(671), FalconFelt::new(3531), FalconFelt::new(11813), FalconFelt::new(3985), FalconFelt::new(7384), FalconFelt::new(10111), FalconFelt::new(10745), FalconFelt::new(6730), FalconFelt::new(11869), FalconFelt::new(9042), FalconFelt::new(2686), FalconFelt::new(2969), FalconFelt::new(3978), FalconFelt::new(8779), FalconFelt::new(6957), FalconFelt::new(9424), FalconFelt::new(2370), FalconFelt::new(8241), FalconFelt::new(10040), FalconFelt::new(9405), FalconFelt::new(11136), FalconFelt::new(3186), FalconFelt::new(5407), FalconFelt::new(10163), FalconFelt::new(1630), FalconFelt::new(3271), FalconFelt::new(8232), FalconFelt::new(10600), FalconFelt::new(8925), FalconFelt::new(4414), FalconFelt::new(2847), FalconFelt::new(10115), FalconFelt::new(4372), FalconFelt::new(9509), FalconFelt::new(5195), FalconFelt::new(7394), FalconFelt::new(10805), FalconFelt::new(9984), FalconFelt::new(7247), FalconFelt::new(4053), FalconFelt::new(9644), FalconFelt::new(12176), FalconFelt::new(4919), FalconFelt::new(2166), FalconFelt::new(8374), FalconFelt::new(12129), FalconFelt::new(9140), FalconFelt::new(7852), FalconFelt::new(3), FalconFelt::new(1426), FalconFelt::new(7635), FalconFelt::new(10512), FalconFelt::new(1663), FalconFelt::new(8653), FalconFelt::new(4938), FalconFelt::new(2704), FalconFelt::new(5291), FalconFelt::new(5277), FalconFelt::new(1168), FalconFelt::new(11082), FalconFelt::new(9041), FalconFelt::new(2143), FalconFelt::new(11224), FalconFelt::new(11885), FalconFelt::new(4645), FalconFelt::new(4096), FalconFelt::new(11796), FalconFelt::new(5444), FalconFelt::new(2381), FalconFelt::new(10911), FalconFelt::new(1912), FalconFelt::new(4337), FalconFelt::new(11854), FalconFelt::new(4976), FalconFelt::new(10682), FalconFelt::new(11414), FalconFelt::new(8509), FalconFelt::new(11287), FalconFelt::new(5011), FalconFelt::new(8005), FalconFelt::new(5088), FalconFelt::new(9852), FalconFelt::new(8643), FalconFelt::new(9302), FalconFelt::new(6267), FalconFelt::new(2422), FalconFelt::new(6039), FalconFelt::new(2187), FalconFelt::new(2566), FalconFelt::new(10849), FalconFelt::new(8526), FalconFelt::new(9223), FalconFelt::new(27), FalconFelt::new(7205), FalconFelt::new(1632), FalconFelt::new(7404), FalconFelt::new(1017), FalconFelt::new(4143), FalconFelt::new(7575), FalconFelt::new(12047), FalconFelt::new(10752), FalconFelt::new(8585), FalconFelt::new(2678), FalconFelt::new(7270), FalconFelt::new(11744), FalconFelt::new(3833), FalconFelt::new(3778), FalconFelt::new(11899), FalconFelt::new(773), FalconFelt::new(5101), FalconFelt::new(11222), FalconFelt::new(9888), FalconFelt::new(442), FalconFelt::new(9377), FalconFelt::new(6591), FalconFelt::new(354), FalconFelt::new(7428), FalconFelt::new(5012), FalconFelt::new(2481), FalconFelt::new(1045), FalconFelt::new(9430), FalconFelt::new(10302), FalconFelt::new(10587), FalconFelt::new(8724), FalconFelt::new(11635), FalconFelt::new(7083), FalconFelt::new(5529), FalconFelt::new(9090), FalconFelt::new(12233), FalconFelt::new(6152), FalconFelt::new(4948), FalconFelt::new(400), FalconFelt::new(1728), FalconFelt::new(6427), FalconFelt::new(6136), FalconFelt::new(6874), FalconFelt::new(3643), FalconFelt::new(10930), FalconFelt::new(5435), FalconFelt::new(1254), FalconFelt::new(11316), FalconFelt::new(10256), FalconFelt::new(3998), FalconFelt::new(10367), FalconFelt::new(8410), FalconFelt::new(11821), FalconFelt::new(8301), FalconFelt::new(11907), FalconFelt::new(316), FalconFelt::new(6950), FalconFelt::new(5446), FalconFelt::new(6093), FalconFelt::new(3710), FalconFelt::new(7822), FalconFelt::new(4789), FalconFelt::new(7540), FalconFelt::new(5537), FalconFelt::new(3789), FalconFelt::new(147), FalconFelt::new(5456), FalconFelt::new(7840), FalconFelt::new(11239), FalconFelt::new(7753), FalconFelt::new(5445), FalconFelt::new(3860), FalconFelt::new(9606), FalconFelt::new(1190), FalconFelt::new(8471), FalconFelt::new(6118), FalconFelt::new(5925), FalconFelt::new(1018), FalconFelt::new(8775), FalconFelt::new(1041), FalconFelt::new(1973), FalconFelt::new(5574), FalconFelt::new(11011), FalconFelt::new(2344), FalconFelt::new(4075), FalconFelt::new(5315), FalconFelt::new(4324), FalconFelt::new(4916), FalconFelt::new(10120), FalconFelt::new(11767), FalconFelt::new(7210), FalconFelt::new(9027), FalconFelt::new(6281), FalconFelt::new(11404), FalconFelt::new(7280), FalconFelt::new(1956), FalconFelt::new(11286), FalconFelt::new(3532), FalconFelt::new(12048), FalconFelt::new(12231), FalconFelt::new(1105), FalconFelt::new(12147), FalconFelt::new(5681), FalconFelt::new(8812), FalconFelt::new(8851), FalconFelt::new(2844), FalconFelt::new(975), FalconFelt::new(4212), FalconFelt::new(8687), FalconFelt::new(6068), FalconFelt::new(421), FalconFelt::new(8209), FalconFelt::new(3600), FalconFelt::new(3263), FalconFelt::new(7665), FalconFelt::new(6077), FalconFelt::new(4782), FalconFelt::new(6403), FalconFelt::new(9260), FalconFelt::new(5594), FalconFelt::new(8076), FalconFelt::new(11785), FalconFelt::new(605), FalconFelt::new(9987), FalconFelt::new(5468), FalconFelt::new(1010), FalconFelt::new(787), FalconFelt::new(8807), FalconFelt::new(5241), FalconFelt::new(9369), FalconFelt::new(9162), FalconFelt::new(8120), FalconFelt::new(5057), FalconFelt::new(7591), FalconFelt::new(3445), FalconFelt::new(7509), FalconFelt::new(2049), FalconFelt::new(7377), FalconFelt::new(10968), FalconFelt::new(192), FalconFelt::new(431), FalconFelt::new(10710), FalconFelt::new(2505), FalconFelt::new(5906), FalconFelt::new(12138), FalconFelt::new(10162), FalconFelt::new(8332), FalconFelt::new(9450), FalconFelt::new(6415), FalconFelt::new(677), FalconFelt::new(6234), FalconFelt::new(3336), FalconFelt::new(12237), FalconFelt::new(9115), FalconFelt::new(1323), FalconFelt::new(2766), FalconFelt::new(3150), FalconFelt::new(1319), FalconFelt::new(8243), FalconFelt::new(709), FalconFelt::new(8049), FalconFelt::new(8719), FalconFelt::new(11454), FalconFelt::new(6224), FalconFelt::new(922), FalconFelt::new(11848), FalconFelt::new(8210), FalconFelt::new(1058), FalconFelt::new(1958), FalconFelt::new(7967), FalconFelt::new(10211), FalconFelt::new(11177), FalconFelt::new(64), FalconFelt::new(8633), FalconFelt::new(11606), FalconFelt::new(9830), FalconFelt::new(6507), FalconFelt::new(1566), FalconFelt::new(2948), FalconFelt::new(9786), FalconFelt::new(6370), FalconFelt::new(7856), FalconFelt::new(3834), FalconFelt::new(5257), FalconFelt::new(10542), FalconFelt::new(9166), FalconFelt::new(9235), FalconFelt::new(5486), FalconFelt::new(1404), FalconFelt::new(11964), FalconFelt::new(1146), FalconFelt::new(11341), FalconFelt::new(3728), FalconFelt::new(8240), FalconFelt::new(6299), FalconFelt::new(1159), FalconFelt::new(6099), FalconFelt::new(295), FalconFelt::new(5766), FalconFelt::new(11637), FalconFelt::new(8527), FalconFelt::new(2919), FalconFelt::new(8273), FalconFelt::new(8212), FalconFelt::new(3329), FalconFelt::new(7991), FalconFelt::new(9597), FalconFelt::new(168), FalconFelt::new(10695), FalconFelt::new(1962), FalconFelt::new(5106), FalconFelt::new(6328), FalconFelt::new(5297), FalconFelt::new(6170), FalconFelt::new(3956), FalconFelt::new(1360), FalconFelt::new(11089), FalconFelt::new(7105), FalconFelt::new(9734), FalconFelt::new(6167), FalconFelt::new(9407), FalconFelt::new(1805), FalconFelt::new(1954), FalconFelt::new(2051), FalconFelt::new(6142), FalconFelt::new(2447), FalconFelt::new(3963), FalconFelt::new(11713), FalconFelt::new(8855), FalconFelt::new(8760), FalconFelt::new(9381), FalconFelt::new(218), FalconFelt::new(9928), FalconFelt::new(10446), FalconFelt::new(9259), FalconFelt::new(4115), FalconFelt::new(5333), FalconFelt::new(10258), FalconFelt::new(5876), FalconFelt::new(2281), FalconFelt::new(156), FalconFelt::new(9522), FalconFelt::new(8320), FalconFelt::new(3991), FalconFelt::new(453), FalconFelt::new(6381), FalconFelt::new(11871), FalconFelt::new(8517), FalconFelt::new(4774), FalconFelt::new(6860), FalconFelt::new(4737), FalconFelt::new(1293), FalconFelt::new(10232), FalconFelt::new(5369), FalconFelt::new(9087), FalconFelt::new(7796), FalconFelt::new(350), FalconFelt::new(1512), FalconFelt::new(10474), FalconFelt::new(6906), FalconFelt::new(1489), FalconFelt::new(2500), FalconFelt::new(1583), FalconFelt::new(6347), FalconFelt::new(11026), FalconFelt::new(12240), FalconFelt::new(6374), FalconFelt::new(1483), FalconFelt::new(3009), FalconFelt::new(1693), FalconFelt::new(723), FalconFelt::new(174), FalconFelt::new(2738), FalconFelt::new(6421), FalconFelt::new(2655), FalconFelt::new(6554), FalconFelt::new(10314), FalconFelt::new(3757), FalconFelt::new(9364), FalconFelt::new(11942), FalconFelt::new(7535), FalconFelt::new(10431), FalconFelt::new(426), FalconFelt::new(3315), ]; const FELT_BITREVERSED_POWERS_INVERSE: [FalconFelt; 512] = [ FalconFelt::new(1), FalconFelt::new(10810), FalconFelt::new(7143), FalconFelt::new(4043), FalconFelt::new(10984), FalconFelt::new(722), FalconFelt::new(5736), FalconFelt::new(8155), FalconFelt::new(8747), FalconFelt::new(3504), FalconFelt::new(2545), FalconFelt::new(8668), FalconFelt::new(1646), FalconFelt::new(11077), FalconFelt::new(9094), FalconFelt::new(6429), FalconFelt::new(9650), FalconFelt::new(7468), FalconFelt::new(949), FalconFelt::new(9664), FalconFelt::new(2975), FalconFelt::new(11726), FalconFelt::new(2744), FalconFelt::new(9283), FalconFelt::new(7698), FalconFelt::new(6561), FalconFelt::new(5828), FalconFelt::new(7266), FalconFelt::new(6512), FalconFelt::new(3328), FalconFelt::new(1351), FalconFelt::new(4978), FalconFelt::new(790), FalconFelt::new(11334), FalconFelt::new(2319), FalconFelt::new(11119), FalconFelt::new(1326), FalconFelt::new(5086), FalconFelt::new(9088), FalconFelt::new(3014), FalconFelt::new(3712), FalconFelt::new(3135), FalconFelt::new(7443), FalconFelt::new(2747), FalconFelt::new(9995), FalconFelt::new(1062), FalconFelt::new(7484), FalconFelt::new(3553), FalconFelt::new(4320), FalconFelt::new(1000), FalconFelt::new(81), FalconFelt::new(3091), FalconFelt::new(3051), FalconFelt::new(9923), FalconFelt::new(4896), FalconFelt::new(9326), FalconFelt::new(10654), FalconFelt::new(9521), FalconFelt::new(8034), FalconFelt::new(1177), FalconFelt::new(7678), FalconFelt::new(11563), FalconFelt::new(10436), FalconFelt::new(140), FalconFelt::new(1696), FalconFelt::new(10861), FalconFelt::new(9863), FalconFelt::new(11955), FalconFelt::new(11029), FalconFelt::new(7901), FalconFelt::new(7657), FalconFelt::new(5755), FalconFelt::new(2089), FalconFelt::new(7197), FalconFelt::new(2881), FalconFelt::new(3284), FalconFelt::new(2013), FalconFelt::new(9000), FalconFelt::new(729), FalconFelt::new(3241), FalconFelt::new(9741), FalconFelt::new(8058), FalconFelt::new(11934), FalconFelt::new(8907), FalconFelt::new(7110), FalconFelt::new(3694), FalconFelt::new(8582), FalconFelt::new(1759), FalconFelt::new(4890), FalconFelt::new(5911), FalconFelt::new(3932), FalconFelt::new(9558), FalconFelt::new(8830), FalconFelt::new(3637), FalconFelt::new(5542), FalconFelt::new(145), FalconFelt::new(339), FalconFelt::new(2468), FalconFelt::new(544), FalconFelt::new(6498), FalconFelt::new(9), FalconFelt::new(11267), FalconFelt::new(2842), FalconFelt::new(11809), FalconFelt::new(3584), FalconFelt::new(8112), FalconFelt::new(2525), FalconFelt::new(1381), FalconFelt::new(4989), FalconFelt::new(6958), FalconFelt::new(10616), FalconFelt::new(4278), FalconFelt::new(2476), FalconFelt::new(118), FalconFelt::new(2197), FalconFelt::new(7222), FalconFelt::new(827), FalconFelt::new(5767), FalconFelt::new(8541), FalconFelt::new(953), FalconFelt::new(4354), FalconFelt::new(12159), FalconFelt::new(9452), FalconFelt::new(5374), FalconFelt::new(7837), FalconFelt::new(9893), FalconFelt::new(3296), FalconFelt::new(3949), FalconFelt::new(2859), FalconFelt::new(11244), FalconFelt::new(9808), FalconFelt::new(7277), FalconFelt::new(4861), FalconFelt::new(11935), FalconFelt::new(5698), FalconFelt::new(2912), FalconFelt::new(11847), FalconFelt::new(2401), FalconFelt::new(1067), FalconFelt::new(7188), FalconFelt::new(11516), FalconFelt::new(390), FalconFelt::new(8511), FalconFelt::new(8456), FalconFelt::new(545), FalconFelt::new(5019), FalconFelt::new(9611), FalconFelt::new(3704), FalconFelt::new(1537), FalconFelt::new(242), FalconFelt::new(4714), FalconFelt::new(8146), FalconFelt::new(11272), FalconFelt::new(4885), FalconFelt::new(10657), FalconFelt::new(5084), FalconFelt::new(12262), FalconFelt::new(3066), FalconFelt::new(3763), FalconFelt::new(1440), FalconFelt::new(9723), FalconFelt::new(10102), FalconFelt::new(6250), FalconFelt::new(9867), FalconFelt::new(6022), FalconFelt::new(2987), FalconFelt::new(3646), FalconFelt::new(2437), FalconFelt::new(7201), FalconFelt::new(4284), FalconFelt::new(7278), FalconFelt::new(1002), FalconFelt::new(3780), FalconFelt::new(875), FalconFelt::new(1607), FalconFelt::new(7313), FalconFelt::new(435), FalconFelt::new(7952), FalconFelt::new(10377), FalconFelt::new(1378), FalconFelt::new(9908), FalconFelt::new(6845), FalconFelt::new(493), FalconFelt::new(8193), FalconFelt::new(7644), FalconFelt::new(404), FalconFelt::new(1065), FalconFelt::new(10146), FalconFelt::new(3248), FalconFelt::new(1207), FalconFelt::new(11121), FalconFelt::new(7012), FalconFelt::new(6998), FalconFelt::new(9585), FalconFelt::new(7351), FalconFelt::new(3636), FalconFelt::new(10626), FalconFelt::new(1777), FalconFelt::new(4654), FalconFelt::new(10863), FalconFelt::new(12286), FalconFelt::new(4437), FalconFelt::new(3149), FalconFelt::new(160), FalconFelt::new(3915), FalconFelt::new(10123), FalconFelt::new(7370), FalconFelt::new(113), FalconFelt::new(2645), FalconFelt::new(8236), FalconFelt::new(5042), FalconFelt::new(2305), FalconFelt::new(1484), FalconFelt::new(4895), FalconFelt::new(7094), FalconFelt::new(2780), FalconFelt::new(7917), FalconFelt::new(2174), FalconFelt::new(9442), FalconFelt::new(7875), FalconFelt::new(3364), FalconFelt::new(1689), FalconFelt::new(4057), FalconFelt::new(9018), FalconFelt::new(10659), FalconFelt::new(2126), FalconFelt::new(6882), FalconFelt::new(9103), FalconFelt::new(1153), FalconFelt::new(2884), FalconFelt::new(2249), FalconFelt::new(4048), FalconFelt::new(9919), FalconFelt::new(2865), FalconFelt::new(5332), FalconFelt::new(3510), FalconFelt::new(8311), FalconFelt::new(9320), FalconFelt::new(9603), FalconFelt::new(3247), FalconFelt::new(420), FalconFelt::new(5559), FalconFelt::new(1544), FalconFelt::new(2178), FalconFelt::new(4905), FalconFelt::new(8304), FalconFelt::new(476), FalconFelt::new(8758), FalconFelt::new(11618), FalconFelt::new(9289), FalconFelt::new(12046), FalconFelt::new(3016), FalconFelt::new(3136), FalconFelt::new(7098), FalconFelt::new(9890), FalconFelt::new(8889), FalconFelt::new(8974), FalconFelt::new(11863), FalconFelt::new(1858), FalconFelt::new(4754), FalconFelt::new(347), FalconFelt::new(2925), FalconFelt::new(8532), FalconFelt::new(1975), FalconFelt::new(5735), FalconFelt::new(9634), FalconFelt::new(5868), FalconFelt::new(9551), FalconFelt::new(12115), FalconFelt::new(11566), FalconFelt::new(10596), FalconFelt::new(9280), FalconFelt::new(10806), FalconFelt::new(5915), FalconFelt::new(49), FalconFelt::new(1263), FalconFelt::new(5942), FalconFelt::new(10706), FalconFelt::new(9789), FalconFelt::new(10800), FalconFelt::new(5383), FalconFelt::new(1815), FalconFelt::new(10777), FalconFelt::new(11939), FalconFelt::new(4493), FalconFelt::new(3202), FalconFelt::new(6920), FalconFelt::new(2057), FalconFelt::new(10996), FalconFelt::new(7552), FalconFelt::new(5429), FalconFelt::new(7515), FalconFelt::new(3772), FalconFelt::new(418), FalconFelt::new(5908), FalconFelt::new(11836), FalconFelt::new(8298), FalconFelt::new(3969), FalconFelt::new(2767), FalconFelt::new(12133), FalconFelt::new(10008), FalconFelt::new(6413), FalconFelt::new(2031), FalconFelt::new(6956), FalconFelt::new(8174), FalconFelt::new(3030), FalconFelt::new(1843), FalconFelt::new(2361), FalconFelt::new(12071), FalconFelt::new(2908), FalconFelt::new(3529), FalconFelt::new(3434), FalconFelt::new(576), FalconFelt::new(8326), FalconFelt::new(9842), FalconFelt::new(6147), FalconFelt::new(10238), FalconFelt::new(10335), FalconFelt::new(10484), FalconFelt::new(2882), FalconFelt::new(6122), FalconFelt::new(2555), FalconFelt::new(5184), FalconFelt::new(1200), FalconFelt::new(10929), FalconFelt::new(8333), FalconFelt::new(6119), FalconFelt::new(6992), FalconFelt::new(5961), FalconFelt::new(7183), FalconFelt::new(10327), FalconFelt::new(1594), FalconFelt::new(12121), FalconFelt::new(2692), FalconFelt::new(4298), FalconFelt::new(8960), FalconFelt::new(4077), FalconFelt::new(4016), FalconFelt::new(9370), FalconFelt::new(3762), FalconFelt::new(652), FalconFelt::new(6523), FalconFelt::new(11994), FalconFelt::new(6190), FalconFelt::new(11130), FalconFelt::new(5990), FalconFelt::new(4049), FalconFelt::new(8561), FalconFelt::new(948), FalconFelt::new(11143), FalconFelt::new(325), FalconFelt::new(10885), FalconFelt::new(6803), FalconFelt::new(3054), FalconFelt::new(3123), FalconFelt::new(1747), FalconFelt::new(7032), FalconFelt::new(8455), FalconFelt::new(4433), FalconFelt::new(5919), FalconFelt::new(2503), FalconFelt::new(9341), FalconFelt::new(10723), FalconFelt::new(5782), FalconFelt::new(2459), FalconFelt::new(683), FalconFelt::new(3656), FalconFelt::new(12225), FalconFelt::new(1112), FalconFelt::new(2078), FalconFelt::new(4322), FalconFelt::new(10331), FalconFelt::new(11231), FalconFelt::new(4079), FalconFelt::new(441), FalconFelt::new(11367), FalconFelt::new(6065), FalconFelt::new(835), FalconFelt::new(3570), FalconFelt::new(4240), FalconFelt::new(11580), FalconFelt::new(4046), FalconFelt::new(10970), FalconFelt::new(9139), FalconFelt::new(9523), FalconFelt::new(10966), FalconFelt::new(3174), FalconFelt::new(52), FalconFelt::new(8953), FalconFelt::new(6055), FalconFelt::new(11612), FalconFelt::new(5874), FalconFelt::new(2839), FalconFelt::new(3957), FalconFelt::new(2127), FalconFelt::new(151), FalconFelt::new(6383), FalconFelt::new(9784), FalconFelt::new(1579), FalconFelt::new(11858), FalconFelt::new(12097), FalconFelt::new(1321), FalconFelt::new(4912), FalconFelt::new(10240), FalconFelt::new(4780), FalconFelt::new(8844), FalconFelt::new(4698), FalconFelt::new(7232), FalconFelt::new(4169), FalconFelt::new(3127), FalconFelt::new(2920), FalconFelt::new(7048), FalconFelt::new(3482), FalconFelt::new(11502), FalconFelt::new(11279), FalconFelt::new(6821), FalconFelt::new(2302), FalconFelt::new(11684), FalconFelt::new(504), FalconFelt::new(4213), FalconFelt::new(6695), FalconFelt::new(3029), FalconFelt::new(5886), FalconFelt::new(7507), FalconFelt::new(6212), FalconFelt::new(4624), FalconFelt::new(9026), FalconFelt::new(8689), FalconFelt::new(4080), FalconFelt::new(11868), FalconFelt::new(6221), FalconFelt::new(3602), FalconFelt::new(8077), FalconFelt::new(11314), FalconFelt::new(9445), FalconFelt::new(3438), FalconFelt::new(3477), FalconFelt::new(6608), FalconFelt::new(142), FalconFelt::new(11184), FalconFelt::new(58), FalconFelt::new(241), FalconFelt::new(8757), FalconFelt::new(1003), FalconFelt::new(10333), FalconFelt::new(5009), FalconFelt::new(885), FalconFelt::new(6008), FalconFelt::new(3262), FalconFelt::new(5079), FalconFelt::new(522), FalconFelt::new(2169), FalconFelt::new(7373), FalconFelt::new(7965), FalconFelt::new(6974), FalconFelt::new(8214), FalconFelt::new(9945), FalconFelt::new(1278), FalconFelt::new(6715), FalconFelt::new(10316), FalconFelt::new(11248), FalconFelt::new(3514), FalconFelt::new(11271), FalconFelt::new(6364), FalconFelt::new(6171), FalconFelt::new(3818), FalconFelt::new(11099), FalconFelt::new(2683), FalconFelt::new(8429), FalconFelt::new(6844), FalconFelt::new(4536), FalconFelt::new(1050), FalconFelt::new(4449), FalconFelt::new(6833), FalconFelt::new(12142), FalconFelt::new(8500), FalconFelt::new(6752), FalconFelt::new(4749), FalconFelt::new(7500), FalconFelt::new(4467), FalconFelt::new(8579), FalconFelt::new(6196), FalconFelt::new(6843), FalconFelt::new(5339), FalconFelt::new(11973), FalconFelt::new(382), FalconFelt::new(3988), FalconFelt::new(468), FalconFelt::new(3879), FalconFelt::new(1922), FalconFelt::new(8291), FalconFelt::new(2033), FalconFelt::new(973), FalconFelt::new(11035), FalconFelt::new(6854), FalconFelt::new(1359), FalconFelt::new(8646), FalconFelt::new(5415), FalconFelt::new(6153), FalconFelt::new(5862), FalconFelt::new(10561), FalconFelt::new(11889), FalconFelt::new(7341), FalconFelt::new(6137), FalconFelt::new(56), FalconFelt::new(3199), FalconFelt::new(6760), FalconFelt::new(5206), FalconFelt::new(654), FalconFelt::new(3565), FalconFelt::new(1702), FalconFelt::new(1987), ]; const FELT_NINV_1: FalconFelt = FalconFelt::new(1); const FELT_NINV_2: FalconFelt = FalconFelt::new(6145); const FELT_NINV_4: FalconFelt = FalconFelt::new(9217); const FELT_NINV_8: FalconFelt = FalconFelt::new(10753); const FELT_NINV_16: FalconFelt = FalconFelt::new(11521); const FELT_NINV_32: FalconFelt = FalconFelt::new(11905); const FELT_NINV_64: FalconFelt = FalconFelt::new(12097); const FELT_NINV_128: FalconFelt = FalconFelt::new(12193); const FELT_NINV_256: FalconFelt = FalconFelt::new(12241); const FELT_NINV_512: FalconFelt = FalconFelt::new(12265);