def sieve_of_atkin(n): """ Returns the primes under a specified number with a segmented sieve of Atkin. Arguments: n (:int) - the number to list primes under Returns: the primes under 'n' in a list """ sqrt_n, u, r = int(math.sqrt(n)), n + 32, 17 B, lu = 60 * sqrt_n, math.log(u) primes = small_sieve(sqrt_n) ret = under60 + [0] * int(u/lu + u/(lu*lu) * 1.5 - r) for d in dAll: segs[d] = [0] * ((B >> 5) + 1) # Do computations in segments of size 60√n lim = n/60 + 1 for L in xrange(1, lim, B): for d in dAll: for k in xrange(len(segs[d])): segs[d][k] = 0 # Sieve off the primes (i.e. solutions to the various quadratic # Diophantine equations) lim2 = 60 * (L+B) for d,f,g in DFG1: enum1(d, f, g, L, B, segs) for d,f,g in DFG2: enum2(d, f, g, L, B, segs) for d,f,g in DFG3: enum3(d, f, g, L, B, segs) # Sieve off non-squarefree numbers for p in primes: p2 = p * p if p2 > lim2: break if p >= 7: b = -utils.xgcd(p2, 60) if b < 0: b += p2 for d in dAll: x = b * (60*L + d) % p2 while x < B: segs[d][x >> 5] &= ~(1 << (x & 31)) x += p2 # Compute primes for j in xrange((B >> 5) + 1): for x in xrange(32): k = 60 * (L + x + (j << 5)) for d in dAll: if k + d > n: return ret[:r] # If a_k = 1, 60k + d is a prime if ((segs[d][j] << 31 - x) & 0xFFFFFFFF) >= 0x80000000: ret[r] = 60*k + d r += 1
def ChineseRemainder(pairs): '''Retourne a tel que a == pairs[0] mod pairs[1] pour tout les élements de pairs et m la multiplication des modulo ''' (a, m) = pairs[0] for (b, p) in pairs[1:]: k = ((b - a) * xgcd(m, p)[1]) a = (a + m * k) % (m * p) m *= p return (a, m)
def getXModP(beta, alpha, p, q, r): ''' return (x, q**r) with (p-1)/q**r = k, 0 <= x < q**r, os beta^(x*k) = alpha^k mod p ''' oDiv = (p - 1) // q # first divided group order bCurrent = beta xFinal = 0 # returns x=x0+x1q+x2q^2+...+xiq^i with 0<=xi<q-1 alphaRaisedModp = pow(int(alpha), int(oDiv), p) qPow = 1 alphaInv = xgcd(alpha, p)[1] for i in range(0, r): betaRaisedModp = pow(int(bCurrent), int(oDiv), p) xCurrent = discreteLogModP(alphaRaisedModp, betaRaisedModp, p) xFinal += xCurrent * qPow #now we calculate the next beta, power of q, order factor bCurrent = bCurrent * pow(alphaInv, xCurrent * qPow, p) % p qPow *= q oDiv //= q return (xFinal, qPow)
def genKeyPair(klen): e = 3 # Choose some e that is relatively prime to phi(n) p = utils.genPrime(klen // 2, 40) q = utils.genPrime(klen // 2, 40) while (p % e == 1): p = utils.genPrime(klen // 2, 40) while (q % e == 1): q = utils.genPrime(klen // 2, 40) N = p * q phi = (p - 1) * (q - 1) print("phi: {}".format(phi)) result = utils.xgcd(e, phi) print(result) d = result[1] if d < 0: d += phi return (N, e, d)
def factor(num, b): """ factor using Pollard's p-1 method num: odd number to factor b: smoothness cap """ primeList = utils.primes(b) m = 1 for prime in primeList: exp = math.floor(math.log(b, prime)) m *= pow(prime, exp) a = 2 g = utils.xgcd(pow(a, m, num) - 1, num)[0] if (1 < g and g < num): return g elif (g == 1): # Increase B return -1 elif (g == num): # Decrease B return -2