1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! Number Theoretic Transform (NTT) — exact integer FFT over prime fields.
//!
//! The NTT operates on integers modulo a prime `p`, providing exact arithmetic
//! (no floating-point rounding) for polynomial multiplication, cryptographic
//! applications, and large integer arithmetic.
//!
//! # Overview
//!
//! The NTT is the finite-field analogue of the discrete Fourier transform.
//! Where the DFT uses complex roots of unity (e^{2πi/n}), the NTT uses
//! primitive roots of unity in Z/pZ — integers `ω` such that `ω^n ≡ 1 (mod p)`
//! and no smaller power of `ω` equals 1.
//!
//! # NTT-Friendly Primes
//!
//! For an NTT of size `n = 2^k`, the prime `p` must satisfy `p ≡ 1 (mod n)`.
//! Primes of the form `p = c · 2^k + 1` are ideal because they support NTT
//! sizes up to `2^k`.
//!
//! This module provides three well-known NTT-friendly primes:
//! - [`NTT_PRIME_998244353`] = 119 · 2²³ + 1 (supports up to 2²³ = 8M elements)
//! - [`NTT_PRIME_MOD1`] = 7 · 2²⁶ + 1 (supports up to 2²⁶ = 64M elements)
//! - [`NTT_PRIME_MOD2`] = 5 · 2²⁵ + 1 (supports up to 2²⁵ = 32M elements)
//!
//! # Example
//!
//! ```
//! use oxifft::ntt::{ntt_convolve_default, NttPlan, NTT_PRIME_998244353};
//!
//! // Polynomial multiplication: (1 + 2x)(3 + 4x) = 3 + 10x + 8x²
//! let a = vec![1u64, 2];
//! let b = vec![3u64, 4];
//! let result = ntt_convolve_default(&a, &b).unwrap();
//! assert_eq!(result[0], 3);
//! assert_eq!(result[1], 10);
//! assert_eq!(result[2], 8);
//!
//! // Plan-based API for repeated transforms
//! let plan = NttPlan::new(4, NTT_PRIME_998244353).unwrap();
//! let mut data = vec![1u64, 2, 3, 4];
//! plan.forward(&mut data);
//! plan.inverse(&mut data);
//! assert_eq!(data, vec![1, 2, 3, 4]);
//! ```
pub use ;
pub use NttError;
pub use NttPlan;
use crate*;
// ============================================================================
// NTT-friendly primes: p = c * 2^k + 1
// ============================================================================
/// 998244353 = 119 · 2²³ + 1, primitive root = 3.
///
/// Supports NTT sizes up to 2²³ = 8,388,608 elements.
/// This is the most widely used NTT prime in competitive programming.
pub const NTT_PRIME_998244353: u64 = 998_244_353;
/// 469762049 = 7 · 2²⁶ + 1, primitive root = 3.
///
/// Supports NTT sizes up to 2²⁶ = 67,108,864 elements.
pub const NTT_PRIME_MOD1: u64 = 469_762_049;
/// 167772161 = 5 · 2²⁵ + 1, primitive root = 3.
///
/// Supports NTT sizes up to 2²⁵ = 33,554,432 elements.
pub const NTT_PRIME_MOD2: u64 = 167_772_161;
// ============================================================================
// Convenience functions
// ============================================================================
/// Perform a forward NTT in-place.
///
/// Creates a temporary [`NttPlan`] and applies the forward transform.
/// For repeated transforms of the same size, prefer creating a plan once.
///
/// # Errors
///
/// Returns [`NttError`] if the length is not a power of two, the modulus is
/// not prime, or the modulus does not support the requested size.
/// Perform an inverse NTT in-place (includes 1/n scaling).
///
/// # Errors
///
/// Returns [`NttError`] if the length is not a power of two, the modulus is
/// not prime, or the modulus does not support the requested size.
/// Exact polynomial multiplication via NTT convolution.
///
/// Computes the product of polynomials `a` and `b` over Z/pZ.
/// The result has length `len(a) + len(b) - 1` (trimmed of trailing zeros
/// from padding).
///
/// # Errors
///
/// Returns [`NttError`] if the required padded size exceeds the modulus capacity.
/// Exact polynomial multiplication using the default prime (998244353).
///
/// This is a convenience wrapper around [`ntt_convolve`] using
/// [`NTT_PRIME_998244353`]. Coefficients must be less than 998244353.
///
/// # Errors
///
/// Returns [`NttError`] if the required padded size exceeds 2²³.