| 123456789101112131415161718192021222324252627282930313233 |
- import random
- def sample_random(fp, seed=None):
- rnd = random.Random(seed)
- # Range of the field is 0 ... p - 1
- return fp(rnd.randint(0, fp.p - 1))
- def is_power_of_two(n):
- # Power of two number is represented by a single digit
- # followed by zeroes.
- return n & (n - 1) == 0
- #| ## Choosing roots of unity
- def get_omega(fp, n, seed=None):
- """
- Given a field, this method returns an n^th root of unity.
- If the seed is not None then this method will return the
- same n'th root of unity for every run with the same seed
- This only makes sense if n is a power of 2.
- """
- assert is_power_of_two(n)
- # https://crypto.stackexchange.com/questions/63614/finding-the-n-th-root-of-unity-in-a-finite-field
- while True:
- # Sample random x != 0
- x = sample_random(fp, seed)
- # Compute g = x^{(q - 1)/n}
- y = pow(x, (fp.p - 1) // n)
- # If g^{n/2} != 1 then g is a primitive root
- if y != 1 and pow(y, n // 2) != 1:
- assert pow(y, n) == 1, "omega must be 2nd root of unity"
- return y
|