def factorize(x): r""" >>> factorize(a) [3, 41] >>> factorize(b) [2, 2, 2, 3, 19] >>> """ savex = x prime = 2 x = _g.mpz(x) factors = [] while x >= prime: newx, mult = _g.remove(x, prime) if mult: factors.extend([int(prime)] * mult) x = newx prime = _g.next_prime(prime) for factor in factors: assert _g.is_prime(factor) from operator import mul from functools import reduce assert reduce(mul, factors) == savex return factors
def square_modulo_root(a, p): if (p - 3) % 4 == 0: x = a**((p - 3) // 4 + 1) % p return x, p - x elif (p - 5) % 8 == 0: k = (p - 5) // 8 if a**(2 * k + 1) % p == 1: x = a**(k + 1) % p return x, p - x else: x = a**(k + 1) * 2**(2 * k + 1) % p return x, p - x else: k = (p - 1) // 8 d, s = gmpy2.remove(p - 1, 2) for num in PRIMES: if gmpy2.legendre(num, p) == -1: b = num break ta, tb = (p - 1) // 2, 0 for r in range(s - 1): ta //= 2 tb //= 2 if a**ta * b**tb % p == p - 1: tb += (p - 1) // 2 x = a**((d + 1) // 2) * b**(tb // 2) % p return x, p - x
def get_power(x): """Returns p | i ** p == x[i], or None""" x = tuple(x) if len(x) > 2 and x[0] == 0 and x[1] == 1: f, power = gmpy2.remove(x[2], 2) if f != 1: return for i, xi in enumerate(x): if i**power != xi: return return power
def isqrt_modp(n, p): """ Compute an integer s such that s*s = n in Z/pZ or return None if there is no such integer Implements Tonelli-Shanks algorithm ``` assert isqrt_modp(5, 41) == 28 p = None while p is None: p = rand_prime(3, 1000000) for x in range(p): s = isqrt_modp(x, p) if s is not None: assert gmpy2.powmod(s, 2, p) == x ``` """ if not is_quadratic_residue(n, p): return None Q, S = gmpy2.remove(p - 1, 2) for z in range(3, p): if not is_quadratic_residue(z, p): break M = S c = gmpy2.powmod(z, Q, p) t = gmpy2.powmod(n, Q, p) R = gmpy2.powmod(n, (Q + 1) // 2, p) for its in range(10000): if t == 0: return 0 if t == 1: return R for i in range(1, M): if t == 1: break t = gmpy2.powmod(t, 2, p) b = gmpy2.powmod(c, gmpy2.powmod(2, M - i - 1, p), p) M = i b2 = gmpy2.powmod(b, 2, p) c = b2 t = gmpy2.f_mod(t * b2, p) R = gmpy2.f_mod(R * b, p)
def factorize(x): r''' >>> factorize(a) [3, 41] >>> factorize(b) [2, 2, 2, 3, 19] >>> ''' import gmpy2 as _g savex=x prime=2 x=_g.mpz(x) factors=[] while x>=prime: newx,mult=_g.remove(x,prime) if mult: factors.extend([int(prime)]*mult) x=newx prime=_g.next_prime(prime) for factor in factors: assert _g.is_prime(factor) from operator import mul assert reduce(mul, factors)==savex return factors