-
galois.intt(X: ArrayLike, size: int | None =
None
, modulus: int | None =None
, scaled: bool =True
) FieldArray Computes the Inverse Number-Theoretic Transform (INTT) of
.- Parameters:¶
- X: ArrayLike¶
The input sequence of integers
.- size: int | None =
None
¶ The size
of the INTT transform, must be at least the length of . The default isNone
which corresponds tolen(X)
. Ifsize
is larger than the length of , is zero-padded.- modulus: int | None =
None
¶ The prime modulus
that defines the field . The prime modulus must satisfy and (i.e., the size of the transform must divide ). The default isNone
which corresponds to the smallest that satisfies the criteria. However, if is a array, thenNone
corresponds to from the specified field.- scaled: bool =
True
¶ Indicates to scale the INTT output by
. The default isTrue
. IfTrue
, . IfFalse
, .
- Returns:¶
The INTT
of the input , with length . The output is a array. It can be viewed as a normal NumPy array with.view(np.ndarray)
or converted to a Python list with.tolist()
.
See also
Notes¶
The Number-Theoretic Transform (NTT) is a specialized Discrete Fourier Transform (DFT) over a finite field
instead of over . The DFT uses the primitive -th root of unity , but the NTT uses a primitive -th root of unity in . These roots are such that and for .In
, where is prime, a primitive -th root of unity exists if divides . If that is true, then for some integer . This function finds by first finding a primitive -th root of unity in usingprimitive_root()
. From there is found from .The
-th value of the scaled -point INTT iswith all arithmetic performed in
. The scaled INTT has the property that .A radix-2 Cooley-Tukey FFT algorithm is implemented, which achieves
.References¶
https://cgyurgyik.github.io/posts/2021/04/brief-introduction-to-ntt/
https://www.nayuki.io/page/number-theoretic-transform-integer-dft
https://www.geeksforgeeks.org/python-number-theoretic-transformation/
Examples¶
The default modulus is the smallest
such that and . With the input and , the default modulus is .In [1]: galois.intt([0, 4, 3, 2]) Out[1]: GF([1, 2, 3, 4], order=5)
However, other moduli satisfy
and . For instance, and . Notice the INTT outputs are different with different moduli. So it is important to perform forward and reverse NTTs with the same modulus.In [2]: galois.intt([0, 4, 3, 2], modulus=13) Out[2]: GF([12, 5, 9, 0], order=13) In [3]: galois.intt([0, 4, 3, 2], modulus=17) Out[3]: GF([15, 14, 12, 10], order=17)
Instead of explicitly specifying the prime modulus, a
array may be explicitly passed in and the modulus is taken as .In [4]: GF = galois.GF(13) In [5]: X = GF([10, 8, 11, 1]); X Out[5]: GF([10, 8, 11, 1], order=13) In [6]: x = galois.intt(X); x Out[6]: GF([1, 2, 3, 4], order=13) In [7]: galois.ntt(x) Out[7]: GF([10, 8, 11, 1], order=13)
The forward NTT and scaled INTT are the identity transform, i.e.
.In [8]: GF = galois.GF(13) In [9]: x = GF([1, 2, 3, 4]); x Out[9]: GF([1, 2, 3, 4], order=13) In [10]: galois.intt(galois.ntt(x)) Out[10]: GF([1, 2, 3, 4], order=13)
This is also true in the reverse order, i.e.
.In [11]: galois.ntt(galois.intt(x)) Out[11]: GF([1, 2, 3, 4], order=13)
The
numpy.fft.ifft()
function may also be used to compute the inverse NTT over .In [12]: X = np.fft.fft(x); X Out[12]: GF([10, 8, 11, 1], order=13) In [13]: np.fft.ifft(X) Out[13]: GF([1, 2, 3, 4], order=13)