Skip to main content

Ntt32Context

Struct Ntt32Context 

Source
pub struct Ntt32Context {
    pub n: usize,
    pub log_n: u32,
    pub q: u32,
    pub two_q: u32,
    pub root_powers: Vec<u32>,
    pub root_powers_shoup: Vec<u32>,
    pub inv_root_powers: Vec<u32>,
    pub inv_root_powers_shoup: Vec<u32>,
    pub n_inv: u32,
    pub n_inv_shoup: u32,
}
Expand description

Pre-computed NTT context for a single 28-bit prime.

Stores twiddle factors (root powers) in Longa-Naehrig ordering along with their Shoup precomputed quotients for division-free multiplication.

§Usage

use vaea_ntt::ntt32::{Ntt32Context, generate_primes_28};

let primes = generate_primes_28(1024, 1);
let ctx = Ntt32Context::new(1024, primes[0]);

let mut data = vec![0u32; 1024];
data[0] = 42;
ctx.forward(&mut data);   // NTT forward
ctx.inverse(&mut data);   // NTT inverse (data restored)
assert_eq!(data[0], 42);

Fields§

§n: usize

Polynomial size (power of 2)

§log_n: u32

log2(n)

§q: u32

Prime < 2^28

§two_q: u32

2 · q — precomputed for Harvey lazy butterfly

§root_powers: Vec<u32>

Forward root powers (Longa-Naehrig ordering)

§root_powers_shoup: Vec<u32>

Shoup quotients for forward root powers: floor(root_powers[i] · 2^32 / q)

§inv_root_powers: Vec<u32>

Inverse root powers for INTT

§inv_root_powers_shoup: Vec<u32>

Shoup quotients for inverse root powers

§n_inv: u32

N^{-1} mod q — normalization factor for INTT

§n_inv_shoup: u32

Shoup quotient for n_inv

Implementations§

Source§

impl Ntt32Context

Source

pub fn try_new(n: usize, q: u32) -> Result<Self, NttError>

Fallible constructor for an NTT context for a 28-bit prime.

Validates all preconditions and returns an error instead of panicking.

§Arguments
  • n — polynomial size, must be a power of 2 ≥ 2
  • q — prime < 2^28, must satisfy q ≡ 1 (mod 2N)
§Errors
Source

pub fn new(n: usize, q: u32) -> Self

Creates a new NTT context for a 28-bit prime.

Computes primitive roots, twiddle factors (Longa-Naehrig ordering), and precomputes all Shoup quotients.

§Arguments
  • n — polynomial size, must be a power of 2 ≥ 2
  • q — prime < 2^28, must satisfy q ≡ 1 (mod 2N)
§Panics
  • If n is not a power of 2 ≥ 2
  • If q ≥ 2^28
  • If q is not prime
  • If (q - 1) is not divisible by 2N
Source

pub fn forward(&self, data: &mut [u32])

Applies the NTT forward transform in-place.

On aarch64, dispatches to the fully-vectorized NEON implementation. On other architectures, uses the scalar Shoup NTT.

Source

pub fn inverse(&self, data: &mut [u32])

Applies the NTT inverse transform in-place (with N⁻¹ normalization).

Output coefficients are fully normalized to [0, q). On aarch64, dispatches to the NEON implementation. On other architectures, uses the scalar Shoup NTT.

Source

pub fn inverse_lazy(&self, data: &mut [u32])

Applies the NTT inverse transform without N⁻¹ normalization.

Output coefficients are scaled by N relative to the true INTT. Use this when chaining operations where normalization can be deferred, or when matching libraries that don’t normalize (e.g., concrete-ntt).

Source

pub fn n_inv(&self) -> u32

Returns N⁻¹ mod q — useful for manual normalization after inverse_lazy().

Source

pub fn n_inv_shoup(&self) -> u32

Returns the Shoup quotient for N⁻¹ — for manual Shoup normalization.

Source

pub fn pointwise_mul(&self, a: &[u32], b: &[u32], result: &mut [u32])

Pointwise multiplication of two vectors in the NTT domain.

Computes result[i] = a[i] · b[i] mod q for each coefficient.

Source

pub fn negacyclic_mul(&self, a: &[u32], b: &[u32]) -> Vec<u32>

Negacyclic polynomial multiplication in Z_q[X]/(X^N + 1).

Computes result = a · b mod (X^N + 1) using forward NTT, pointwise multiplication, and inverse NTT.

§Returns

A new vector of length N containing the product.

Source

pub fn negacyclic_mul_into( &self, a_buf: &mut [u32], b_buf: &mut [u32], result: &mut [u32], )

Zero-allocation negacyclic multiplication.

The caller provides pre-allocated buffers:

  • a_buf / b_buf: input polynomials (overwritten with NTT-domain values)
  • result: output buffer for the product

All buffers must have length N. After the call, a_buf and b_buf contain NTT-domain data (destroyed); result contains the product in coefficient domain.

§Example
use vaea_ntt::ntt32::{Ntt32Context, generate_primes_28};

let primes = generate_primes_28(256, 1);
let ctx = Ntt32Context::new(256, primes[0]);

let mut a = vec![1u32; 256];
let mut b = vec![2u32; 256];
let mut result = vec![0u32; 256];

ctx.negacyclic_mul_into(&mut a, &mut b, &mut result);
// result now contains a·b mod (X^256 + 1)
// a and b are now in NTT domain (overwritten)

Trait Implementations§

Source§

impl Clone for Ntt32Context

Source§

fn clone(&self) -> Ntt32Context

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Ntt32Context

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.