You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

42 lines
1017 B

  1. # Primitive Root of Unity
  2. def get_primitive_root_of_unity(F, n):
  3. # using the method described by Thomas Pornin in
  4. # https://crypto.stackexchange.com/a/63616
  5. q = F.order()
  6. for k in range(q):
  7. if k==0:
  8. continue
  9. g = F(k)
  10. # g = F.random_element()
  11. if g==0:
  12. continue
  13. w = g ^ ((q-1)/n)
  14. if w^(n/2) != 1:
  15. return g, w
  16. # Roots of Unity
  17. def get_nth_roots_of_unity(n, primitive_w):
  18. w = [0]*n
  19. for i in range(n):
  20. w[i] = primitive_w^i
  21. return w
  22. # fft (Fast Fourier Transform) returns:
  23. # - nth roots of unity
  24. # - Vandermonde matrix for the nth roots of unity
  25. # - Inverse Vandermonde matrix
  26. def fft(F, n):
  27. g, primitive_w = get_primitive_root_of_unity(F, n)
  28. w = get_nth_roots_of_unity(n, primitive_w)
  29. ft = matrix(F, n)
  30. for j in range(n):
  31. row = []
  32. for k in range(n):
  33. row.append(primitive_w^(j*k))
  34. ft.set_row(j, row)
  35. ft_inv = ft^-1
  36. return w, ft, ft_inv