def PROU(ROU,n,Prime): f = open('ROU_table.txt','w') if((n%2) == 0): for i in range(n): tmp = Mod.ExpMod(ROU,i,Prime) print(i,"-th: ",tmp) ch = str(tmp) f.write(ch) f.write("\n") if tmp == 1 and i != 0: print("it is not primitive root of unity") else: for i in range(n): tmp = Mod.ExpMod(ROU,i,Prime) ch = str(tmp) f.write(ch) f.write("\n") if tmp==1 and i != 0: print("it is not primitve root of unity") return 0
def NTT(x,ROU,prime,n,inverse): #output is a numpy array IN = Mod.InvMod(n,prime) # calculate inverse multiplication of n x = x % prime y_list = [] for i in range(n): acm = 0 #accumlation for j in range(n): exp = Mod.MulMod(i,j,n) #calculates power of i*j tmp = Mod.ExpMod(ROU,exp,prime) #calculates w^(i*j) tmp = Mod.MulMod(x[j],tmp,prime) #calculate x[j]w^(ij) acm = Mod.AddMod(acm,tmp,prime) y_list.append(acm) y = np.array(y_list) if(inverse == 1): y = y * IN y = y % prime return y
def FFT(Array, P, root, N, inverse): #radix-2 FFT # If inverse = 1, doing IFFT. # automatically compute inverse ROU. # root : foward root of unity # N : array length # P :Prime S = math.ceil(math.log2(N)) #Stage bias = N A_t = np.zeros((1, bias), dtype=int) #if inverse = 1,compute inverse ROU if (inverse == 1): root = Mod.InvMod(root, P) # DIT for i in range(S): nc = N // bias #number of class ne = bias #number of elements (in a class) A_t = np.reshape(A_t, (nc, ne)) # reshape array bias = bias >> 1 # each stage right shift one bit for j in range(nc): for jj in range(ne): index_tmp = j * ne + jj A_t[j][jj] = Array[0][index_tmp] if (i == 0): factor = root else: factor = Mod.MulMod(factor, factor, P) for s in range(nc): for ss in range(ne // 2): tmp = BU(A_t[s][ss], A_t[s][ss + bias], P) factor_t = Mod.ExpMod(factor, ss, P) A_t[s][ss] = tmp[0][0] A_t[s][ss + bias] = tmp[0][1] A_t[s][ss + bias] = Mod.MulMod(A_t[s][ss + bias], factor_t, P) for x in range(nc): for y in range(ne): Array[0][x * ne + y] = A_t[x][y] #data relocation #bitreverse for i in range(N): p_tmp = i exchange_position = 0 for ls in range(S): bit = p_tmp % 2 bit_weight = 1 << ((S - 1) - ls) if (bit == 1): exchange_position = exchange_position + bit_weight else: exchange_position = exchange_position p_tmp = p_tmp >> 1 if (exchange_position > i): tmp = Array[0][i] Array[0][i] = Array[0][exchange_position] Array[0][exchange_position] = tmp #inverse FFT need to multiply each element by 1/n if (inverse == 1): IN = Mod.InvMod(N, P) Array = Array * IN Array = Array % P return Array
def n_ROU(Prime,comprime,n): if((Prime % n) != 1): print("ERROR!!,n is not factor of (Prime-1) ") i = (Prime - 1)//n ##integer quotient ROU = Mod.ExpMod(comprime,i,Prime) return ROU