-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathntt.py
67 lines (47 loc) · 1.52 KB
/
ntt.py
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
import math
from helper import *
# --- NTT functions ---
# Iterative NTT (Forward and Inverse)
# arrayIn = input polynomial
# P = modulus
# W = nth root of unity
# inv = 0: forward NTT / 1: inverse NTT
# Input: Standard order/Output: Standard order
def NTT(A, W_table, q):
# print("DEBUG q:{}".format(q))
n = len(A)
B = [x for x in A]
v = int(math.log(n, 2))
for i in range(0, v):
for j in range(0, (2 ** i)):
for k in range(0, (2 ** (v - i - 1))):
s = j * (2 ** (v - i)) + k
t = s + (2 ** (v - i - 1))
# w = (W ** ((2 ** i) * k)) % q
w = W_table[((2 ** i) * k)]
as_temp = B[s]
at_temp = B[t]
B[s] = (as_temp + at_temp) % q
B[t] = ((as_temp - at_temp) * w) % q
B = indexReverse(B, v)
return B
def INTT(A, W_table, q):
n = len(A)
B = [x for x in A]
v = int(math.log(n, 2))
for i in range(0, v):
for j in range(0, (2 ** i)):
for k in range(0, (2 ** (v - i - 1))):
s = j * (2 ** (v - i)) + k
t = s + (2 ** (v - i - 1))
# w = (W ** ((2 ** i) * k)) % q
w = W_table[((2 ** i) * k)]
as_temp = B[s]
at_temp = B[t]
B[s] = (as_temp + at_temp) % q
B[t] = ((as_temp - at_temp) * w) % q
B = indexReverse(B, v)
n_inv = modinv(n, q)
for i in range(n):
B[i] = (B[i] * n_inv) % q
return B