// ---
// tags: jali, rust
// crystal-type: source
// crystal-domain: comp
// ---
//! NTT domain transforms for negacyclic convolution.
//!
//! For R_q = F_p[x]/(x^n+1) we need the negacyclic NTT:
//! - Standard NTT works modulo x^n - 1
//! - Negacyclic NTT works modulo x^n + 1
//!
//! Implementation:
//! 1. Pre-multiply: coeffs[i] *= psi^i where psi is a primitive 2n-th root of unity
//! 2. Apply nebu's forward NTT
//! 3. For inverse: apply nebu's INTT, then post-multiply by psi^(-i)
use Goldilocks;
use P;
use crateRingElement;
/// Primitive root of F_p* (same as nebu's internal G=7).
const G: Goldilocks = new;
/// Compute a primitive 2n-th root of unity.
///
/// Since Goldilocks has multiplicative order p-1 = 2^32 * (2^32 - 1),
/// and 2n divides 2^32 for n <= 4096, a 2n-th root always exists.
/// We compute g^((p-1)/(2n)) where g=7 is a primitive root.
/// Forward negacyclic NTT on raw coefficient slice.
///
/// Transforms coefficients so that polynomial multiplication mod (x^n+1)
/// becomes pointwise multiplication.
/// Inverse negacyclic NTT on raw coefficient slice.
///
/// Recovers polynomial coefficients from NTT domain.
/// Convert a RingElement to NTT form (in-place).
/// Convert a RingElement from NTT form back to coefficient form (in-place).
jali/rs/src/ntt.rs
ฯ 0.0%