@@ -100,16 +100,85 @@ def randomized_primality_testing(n, k):
100100 return True
101101
102102
103+ def miller_rabin_primality_testing (n , k ):
104+ """Calculates whether n is composite (which is always correct) or prime
105+ (which theoretically is incorrect with error probability 4**-k), by
106+ applying Miller-Rabin primality testing.
107+
108+ For reference and implementation example, see:
109+ https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
110+
111+ :param n: Integer to be tested for primality.
112+ :type n: int
113+ :param k: Number of rounds (witnesses) of Miller-Rabin testing.
114+ :type k: int
115+ :return: False if the number is composite, True if it's probably prime.
116+ :rtype: bool
117+ """
118+
119+ # Decompose (n - 1) to write it as (2 ** r) * d
120+ # While d is even, divide it by 2 and increase the exponent.
121+ d = n - 1
122+ r = 0
123+ while not (d & 1 ):
124+ r += 1
125+ d >>= 1
126+
127+ # Test k witnesses.
128+ for _ in range (k ):
129+ # Generate random integer a, where 2 <= a <= (n - 2)
130+ a = 0
131+ while a < 2 :
132+ a = rsa .randnum .randint (n - 2 )
133+
134+ x = pow (a , d , n )
135+ if x == 1 or x == n - 1 :
136+ continue
137+
138+ for _ in range (r - 1 ):
139+ x = pow (x , 2 , n )
140+ if x == 1 :
141+ # n is composite.
142+ return False
143+ if x == n - 1 :
144+ # Exit inner loop and continue with next witness.
145+ break
146+ else :
147+ # If loop doesn't break, n is composite.
148+ return False
149+
150+ return True
151+
152+
103153def is_prime (number ):
104154 """Returns True if the number is prime, and False otherwise.
105155
156+ >>> is_prime(2)
157+ True
106158 >>> is_prime(42)
107159 False
108160 >>> is_prime(41)
109161 True
162+ >>> [x for x in range(901, 1000) if is_prime(x)]
163+ [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
110164 """
111165
112- return randomized_primality_testing (number , 6 )
166+ # Check for small numbers.
167+ if number < 10 :
168+ return number in [2 , 3 , 5 , 7 ]
169+
170+ # Check for even numbers.
171+ if not (number & 1 ):
172+ return False
173+
174+ # According to NIST FIPS 186-4, Appendix C, Table C.3, minimum number of
175+ # rounds of M-R testing, using an error probability of 2 ** (-100), for
176+ # different p, q bitsizes are:
177+ # * p, q bitsize: 512; rounds: 7
178+ # * p, q bitsize: 1024; rounds: 4
179+ # * p, q bitsize: 1536; rounds: 3
180+ # See: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
181+ return miller_rabin_primality_testing (number , 7 )
113182
114183
115184def getprime (nbits ):
0 commit comments