Abstract network of nodes and connections

A Gentle Introduction to the Number Theoretic Transform (NTT)

Chuck Chen
 · 
Categories: Cryptography

As we stand on the brink of the quantum computing era, the race is on to develop new cryptographic methods that can withstand attacks from both classical and quantum computers. At the heart of many of these next-generation, post-quantum cryptographic (PQC) schemes lies a powerful mathematical tool: the Number Theoretic Transform (NTT).

If you’re familiar with signal processing, you might have heard of the Fast Fourier Transform (FFT), an algorithm famous for its ability to efficiently analyze frequencies in signals. The NTT is essentially the FFT’s cousin, but adapted to work with integers in finite fields—a perfect fit for the world of cryptography.

The Problem with FFT in Cryptography

The standard Fast Fourier Transform is a brilliant algorithm for multiplying large polynomials quickly. It works by converting polynomials into a point-value representation, multiplying the points, and then converting back. However, it has a critical flaw for cryptographic applications: it relies on complex numbers, which are represented as floating-point numbers in computers.

Floating-point arithmetic involves rounding, leading to small precision errors. In cryptography, there is no room for error; a single bit difference can cascade into a completely invalid result. We need absolute precision.

Enter NTT: The Integer-Based Solution

The Number Theoretic Transform (NTT) solves the precision problem by swapping the world of complex numbers for the world of modular arithmetic. Instead of operating on an infinite field of complex numbers, the NTT operates on a finite field of integers modulo a prime number p.

This has two key advantages:

  1. No Floating-Point Errors: All calculations are done with integers, ensuring perfect precision.
  2. Efficiency: The calculations remain incredibly fast, inheriting the O(n log n) speed of the FFT algorithm.

The magic ingredient that makes this work is finding an integer equivalent of the “primitive root of unity” used in the FFT. In the NTT, we find a special integer ω (omega) in our finite field that behaves just like its complex counterpart, allowing us to perform the transform and its inverse.

A Simple Example

Let’s see a very simple NTT in action. To multiply two polynomials, we can use the NTT to transform them, perform a simple element-wise multiplication, and then use the Inverse NTT (INTT) to get our result.

Consider the task of multiplying $A(x) = 2x + 1$ and $B(x) = 3x + 4$.

  1. Setup: We choose a small prime modulus, say $p = 17$. Our polynomials can be represented by their coefficient vectors: $a = [1, 2]$ and $b = [4, 3]$.

  2. Forward NTT: We apply the NTT to both vectors. The exact calculation is a bit involved, but conceptually, it’s like evaluating the polynomials at specific points (the roots of unity). Let’s say the results are: $NTT(a) = [3, 16]$ $NTT(b) = [7, 1]$

  3. Point-wise Multiplication: Now, we multiply the transformed vectors element by element, all modulo 17. $c_{ntt} = [3 \cdot 7, 16 \cdot 1] \pmod{17}$ $c_{ntt} = [21, 16] \pmod{17}$ $c_{ntt} = [4, 16]$

  4. Inverse NTT: Finally, we apply the Inverse NTT to $c_{ntt}$ to get the coefficients of the resulting polynomial. $c = \text{INTT}([4, 16]) = [4, 11, 6]$

The resulting vector $[4, 11, 6]$ represents the polynomial $6x^2 + 11x + 4$. If you multiply $(2x + 1)(3x + 4)$ with traditional algebra, you get the exact same result! The NTT allowed us to get there through a different, more efficient path for large polynomials.

The NTT and INTT Algorithms

For those who want a deeper look, let’s examine the forward and inverse transforms. The NTT takes a polynomial’s coefficient vector $a$ and transforms it into a point-value representation $A$. The INTT reverses this process.

The forward NTT is defined as: $$ A_k = \sum_{j=0}^{n-1} a_j \omega^{jk} \pmod{N} $$

And the Inverse NTT is defined as: $$ a_j = (n^{-1}) \sum_{k=0}^{n-1} A_k \omega^{-jk} \pmod{N} $$

Where:

  • $a$ is the input vector of coefficients.
  • $A$ is the transformed output vector.
  • $N$ is the prime modulus.
  • $n$ is the transform size (and a power of 2).
  • $\omega$ is a primitive $n$-th root of unity modulo $N$.
  • $n^{-1}$ is the modular multiplicative inverse of $n$ modulo $N$.

Here is an illustrative Python implementation of the NTT, which is analogous to the Cooley-Tukey FFT algorithm.

def ntt(a, N, w, n):
    """Number Theoretic Transform"""
    # 1. Bit-reversal permutation
    A = list(a)
    for i in range(n):
        rev_i = int(f'{i:0{n.bit_length()-1}b}'[::-1], 2)
        if i < rev_i:
            A[i], A[rev_i] = A[rev_i], A[i]

    # 2. Butterfly operations
    s = 1
    while (m := 2**s) <= n:
        w_m = pow(w, n // m, N)
        for k in range(0, n, m):
            w_pow = 1
            for j in range(m // 2):
                u = A[k + j]
                t = (A[k + j + m // 2] * w_pow) % N
                A[k + j] = (u + t) % N
                A[k + j + m // 2] = (u - t + N) % N
                w_pow = (w_pow * w_m) % N
        s += 1
    return A

And here is the Python code for the Inverse NTT. Notice it’s nearly identical, just using the inverse root of unity and scaling the final result.

def intt(A, N, w_inv, n):
    """Inverse Number Theoretic Transform"""
    # The INTT algorithm is the same as NTT, just with the inverse root
    a = ntt(A, N, w_inv, n)

    # Scale the result by n_inv
    n_inv = pow(n, N - 2, N)
    for i in range(n):
        a[i] = (a[i] * n_inv) % N
    return a

The bit-reversal step is a pre-processing permutation that reorders the input array to be in the correct order for the iterative butterfly operations that follow. This reordering is what allows the algorithm to be so efficient.

Why is NTT a Game-Changer for Cryptography?

The primary application of NTT in cryptography is to perform fast polynomial multiplication. Many modern cryptographic schemes, especially those based on lattices, are built on operations involving very large polynomials.

Doing this multiplication naively would be too slow to be practical. The NTT provides a massive speedup, making these advanced cryptographic schemes feasible.

You can find NTTs at the core of the algorithms selected by NIST for post-quantum standardization, including:

  • CRYSTALS-Kyber: A key-exchange mechanism designed to replace methods like Diffie-Hellman.
  • CRYSTALS-Dilithium: A digital signature algorithm designed to replace methods like RSA and ECDSA.

Conclusion

The Number Theoretic Transform is a cornerstone of modern cryptography, providing the speed and precision necessary to build the secure systems of tomorrow. While it operates deep under the hood, this elegant mathematical tool is what makes it possible to create cryptographic systems that are not only safe from today’s computers but also from the quantum threats of the future. It’s a perfect example of how abstract mathematics finds powerful, practical applications in securing our digital world.