Python - Number Theoretic Transformation


The Number Theoretic Transformation (NTT) is a key component in many computational applications in the field of number theory. It is essential in areas like encryption, signal processing, error-correcting codes, and more because it makes large-number multiplication and convolution processes efficient. The NTT is a fast method for computing polynomial multiplications modulo a prime integer and is closely connected to the Fast Fourier Transform (FFT).

We will examine two different methods for implementing the Number Theoretic Transformation in Python in this article. We will look into the Cooley-Tukey algorithm, one of the most popular methods for putting the Fast Fourier Transform into practice. By dividing a large problem into smaller subproblems and combining the solutions, the Cooley-Tukey algorithm applies the divide-and-conquer strategy to arrive at the final converted output.

By outlining their algorithms, code samples, and output examples, we hope to provide a grasp of these two methods. Readers will have a strong foundation to implement the Number Theoretic Transformation effectively and utilize its power in their computing tasks by the end of this article.

Approaches

To perform number theoretic transformation in Python, we can follow the two methods −

  • Cooley-Tukey Algorithm with Complex Numbers.

  • Cooley-Tukey Algorithm with Integers.

Let us look into both approaches −

Approach - 1: Cooley-Tukey Algorithm With Complex Numbers

A well-known way for quickly computing the Discrete Fourier Transform (DFT) employing the Fast Fourier Transform (FFT) method is the Cooley-Tukey algorithm. This algorithm can be adapted to carry out the NTT.

Algorithm

The algorithm to perform number theoretic transformation in Python is given below −

  • Step 1 − Import cmath module.

  • Step 2 − Build a function that takes an array as a parameter.

  • Step 3 − In variable N compute and store the length of an array.

  • Step 4 − Compute recursively both the parts.

  • Step 5 − Compute twiddle factors “T” for each index k for the range “N/2”

  • Step 6 − Add the even-indexed elements to their corresponding twiddle factors and subtract the even-indexed elements from those twiddle factors to determine the transformed values.

  • Step 7 − By adding the even-indexed elements with their respective twiddle factors and removing the even-indexed elements from their corresponding twiddle factors, the converted values are calculated. The result is returned when the computed transformed values have been concatenated.

  • Step 8 − Call the function by passing the array as a parameter and display the result.

Example

#Import cmath module 
import cmath
#A Function is created that takes an array as a parameter
def ftt_cooley_tukey(x):
   #Compute the length of an array
   N = len(x)
   #For if the length is equal to 1 return the original array
   if N == 1:
      return x
   # Take even part 
   evenPart = ftt_cooley_tukey(x[::2])
   # Take odd part 
   oddPart = ftt_cooley_tukey(x[1::2])
   #The twiddle factors for T for each index k are computed
   T = [cmath.exp(-2j * cmath.pi * k / N) * oddPart[k] for k in range(N // 2)]
   #Return the transformed value
   return [evenPart[k] + T[k] for k in range(N // 2)] + [evenPart[k] - T[k] for k in range(N // 2)]

#An instance of the input array 
example_array = [1, 2, 3, 4]
output = ftt_cooley_tukey(example_array)
print("Approach 1 - Cooley-Tukey FFT Algorithm with Complex Numbers:")
print("Output Array:", output)

Output

Approach 1 - Cooley-Tukey FFT Algorithm with Complex Numbers:
Output Array: [(10+0j), (-2+2j), (-2+0j), (-1.9999999999999998-2j)]

Approach - 2: Cooley-Tukey Algorithm With Integers

The NTT algorithm has been altered by the Cooley-Tukey algorithm for integers to operate on a finite field with modular arithmetic. When dealing with applications of number theory and cryptography, where calculations are made modulo a prime integer, this method is especially helpful.

Algorithm

The algorithm to perform number theoretic transformation in Python is given below −

  • Step 1 − Import the numpy module.

  • Step 2 − Create a function that takes an array, primitive root, and prime value.

  • Step 3 − Compute the even and odd part recursively.

  • Step 4 − The variable g_squared_mod_p produces and stores the twiddle factor g raised to the power of 2 modulo p.

  • Step 5 − Traverse the array and calculate (factor * odd[i])%p and store the result in the term. Then calculate (even[i] + term)% p's first component and assign it to result[i]. Then calculate (even[i] - term)% p's second component and add it to result[i + N // 2]. Multiply the factor by g_squared_mod_p to update it.

  • Step 6 − Return the result.

  • Step 7 − Call the function by passing the desired parameters, and display the result.

Example

#Import numpy module
import numpy as np

#Create a function that takes an array, primitive root, and prime.
def ntt_cooley_tukey(x, p, g):
   N = len(x)
   if N == 1:
      return x
   # Compute odd and even part 
   evenPart = ntt_cooley_tukey(x[::2], p, (g * g) % p)
   oddPart = ntt_cooley_tukey(x[1::2], p, (g * g) % p)

   g_squared_mod_p = (g * g) % p
   factor = 1
   result = np.zeros(N, dtype=int)
   # for the N/2 range 
   for i in range(N // 2):
      term = (factor * oddPart[i]) % p
      #Compute the first part of the result
      result[i] = (evenPart[i] + term) % p
      # Compute the second part of the result
      result[i + N // 2] = (evenPart[i] - term) % p
      # Update the factor by multiplying with g_squared_mod_p.
      factor = (factor * g_squared_mod_p) % p

   return result

# An array with some values is created 
input_array = np.array([1, 2, 3, 4])
prime = 5
primitive_root = 2  # The primitive root for prime 5
output = ntt_cooley_tukey(input_array, prime, primitive_root)
print("Approach 2 - Cooley-Tukey Algorithm with Integers:")
print("Output Array:", output)

Output

Approach 2 - Cooley-Tukey Algorithm with Integers:
Output Array: [0 0 3 1]

Conclusion

We looked at two methods for putting the Number Theoretic Transformation (NTT) algorithm into practice in Python. In the first method, complex numbers were transformed using the Cooley-Tukey Fast Fourier Transform (FFT), while in the second method, integers modulo a prime were used. Depending on the needs of the current challenge, either strategy may be utilized because it has advantages over the other. Complex numbers and the FFT-based method offer a simple and elegant solution that enables quick calculations. The integer-based technique, on the other hand, has the advantage of operating in a finite field, which is particularly advantageous in applications related to number theory and cryptography.

Updated on: 18-Oct-2023

181 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements