2014-11-03 10:49:17 -05:00

65 lines
1.5 KiB
Python

import random
import sys
def ipow(a, b, n):
"""calculates (a**b) % n via binary exponentiation, yielding itermediate
results as Rabin-Miller requires"""
A = a = long(a % n)
yield A
t = 1L
while t <= b:
t <<= 1
# t = 2**k, and t > b
t >>= 2
while t:
A = (A * A) % n
if t & b:
A = (A * a) % n
yield A
t >>= 1
def rabin_miller_witness(test, possible):
"""Using Rabin-Miller witness test, will return True if possible is
definitely not prime (composite), False if it may be prime."""
return 1 not in ipow(test, possible-1, possible)
smallprimes = (2,3,5,7,11,13,17,19,23,29,31,37,41,43,
47,53,59,61,67,71,73,79,83,89,97)
def default_k(bits):
return max(64, 2 * bits)
def is_probably_prime(possible, k=None):
if possible == 1:
return True
if k is None:
k = default_k(possible.bit_length())
for i in smallprimes:
if possible == i:
return True
if possible % i == 0:
return False
for i in xrange(k):
test = random.randrange(2, possible - 1) | 1
if rabin_miller_witness(test, possible):
return False
return True
def generate_prime(bits, k=None):
# bits should be >= 8
k = k or default_k(bits)
while True:
possible = random.randrange(2 ** (bits-1) + 1, 2 ** bits) | 1
if is_probably_prime(possible, k):
return possible