misc.py 1.1 KB

123456789101112131415161718192021222324252627282930313233
  1. import random
  2. def sample_random(fp, seed):
  3. rnd = random.Random(seed)
  4. # Range of the field is 0 ... p - 1
  5. return fp(rnd.randint(0, fp.p - 1))
  6. def is_power_of_two(n):
  7. # Power of two number is represented by a single digit
  8. # followed by zeroes.
  9. return n & (n - 1) == 0
  10. #| ## Choosing roots of unity
  11. def get_omega(fp, n, seed=None):
  12. """
  13. Given a field, this method returns an n^th root of unity.
  14. If the seed is not None then this method will return the
  15. same n'th root of unity for every run with the same seed
  16. This only makes sense if n is a power of 2.
  17. """
  18. assert is_power_of_two(n)
  19. # https://crypto.stackexchange.com/questions/63614/finding-the-n-th-root-of-unity-in-a-finite-field
  20. while True:
  21. # Sample random x != 0
  22. x = sample_random(fp, seed)
  23. # Compute g = x^{(q - 1)/n}
  24. y = pow(x, (fp.p - 1) // n)
  25. # If g^{n/2} != 1 then g is a primitive root
  26. if y != 1 and pow(y, n // 2) != 1:
  27. assert pow(y, n) == 1, "omega must be 2nd root of unity"
  28. return y