Skip to content

Commit 66fdb1f

Browse files
committed
Increase testing for primality
1 parent 4994e3d commit 66fdb1f

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

lib/Crypto/Math/Primality.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ def miller_rabin_test(candidate, iterations, randfunc=None):
6363
if not isinstance(candidate, Integer):
6464
candidate = Integer(candidate)
6565

66+
if candidate in (1, 2, 3, 5):
67+
return PROBABLY_PRIME
68+
6669
if candidate.is_even():
6770
return COMPOSITE
6871

@@ -129,6 +132,8 @@ def lucas_test(candidate):
129132
candidate = Integer(candidate)
130133

131134
# Step 1
135+
if candidate in (1, 2, 3, 5):
136+
return PROBABLY_PRIME
132137
if candidate.is_even() or candidate.is_perfect_square():
133138
return COMPOSITE
134139

@@ -144,6 +149,8 @@ def alternate():
144149
value = -value
145150

146151
for D in alternate():
152+
if candidate in (D, -D):
153+
continue
147154
js = Integer.jacobi_symbol(D, candidate)
148155
if js == 0:
149156
return COMPOSITE
@@ -206,7 +213,7 @@ def alternate():
206213
from Crypto.Util.number import sieve_base as _sieve_base
207214
## The optimal number of small primes to use for the sieve
208215
## is probably dependent on the platform and the candidate size
209-
_sieve_base = _sieve_base[:100]
216+
_sieve_base = set(_sieve_base[:100])
210217

211218

212219
def test_probable_prime(candidate, randfunc=None):
@@ -237,11 +244,13 @@ def test_probable_prime(candidate, randfunc=None):
237244
if not isinstance(candidate, Integer):
238245
candidate = Integer(candidate)
239246

240-
# First, check trial division by the smallest primes
247+
# First, check trial division by the smallest primes
248+
if int(candidate) in _sieve_base:
249+
return PROBABLY_PRIME
241250
try:
242251
map(candidate.fail_if_divisible_by, _sieve_base)
243252
except ValueError:
244-
return False
253+
return COMPOSITE
245254

246255
# These are the number of Miller-Rabin iterations s.t. p(k, t) < 1E-30,
247256
# with p(k, t) being the probability that a randomly chosen k-bit number

lib/Crypto/SelfTest/Math/test_Primality.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,24 @@
5151

5252
class TestPrimality(unittest.TestCase):
5353

54-
primes = (13, 17, 19, 23, 2**127-1, 175637383534939453397801320455508570374088202376942372758907369518414308188137781042871856139027160010343454418881888953150175357127346872102307696660678617989191485418582475696230580407111841072614783095326672517315988762029036079794994990250662362650625650262324085116467511357592728695033227611029693067539)
55-
composites = (12, 7*23, (2**19-1)*(2**67-1), 9746347772161,)
54+
primes = (1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 2**127-1, 175637383534939453397801320455508570374088202376942372758907369518414308188137781042871856139027160010343454418881888953150175357127346872102307696660678617989191485418582475696230580407111841072614783095326672517315988762029036079794994990250662362650625650262324085116467511357592728695033227611029693067539)
55+
composites = (0, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 7*23, (2**19-1)*(2**67-1), 9746347772161,)
5656

5757
def test_miller_rabin(self):
5858
for prime in self.primes:
5959
self.assertEqual(miller_rabin_test(prime, 3), PROBABLY_PRIME)
6060
for composite in self.composites:
6161
self.assertEqual(miller_rabin_test(composite, 3), COMPOSITE)
62+
self.assertRaises(ValueError, miller_rabin_test, -1, 3)
6263

6364
def test_lucas(self):
6465
for prime in self.primes:
65-
self.assertEqual(lucas_test(prime), PROBABLY_PRIME)
66+
res = lucas_test(prime)
67+
self.assertEqual(res, PROBABLY_PRIME)
6668
for composite in self.composites:
67-
self.assertEqual(lucas_test(composite), COMPOSITE)
69+
res = lucas_test(composite)
70+
self.assertEqual(res, COMPOSITE)
71+
self.assertRaises(ValueError, lucas_test, -1)
6872

6973
def test_is_prime(self):
7074
primes = (170141183460469231731687303715884105727,
@@ -82,6 +86,11 @@ def test_is_prime(self):
8286
for np in not_primes:
8387
self.assertEqual(test_probable_prime(np), COMPOSITE)
8488

89+
from Crypto.Util.number import sieve_base
90+
for p in sieve_base[:100]:
91+
res = test_probable_prime(p)
92+
self.assertEqual(res, PROBABLY_PRIME)
93+
8594
def test_generate_prime_bit_size(self):
8695
p = generate_probable_prime(exact_bits=512)
8796
self.assertEqual(p.size_in_bits(), 512)

0 commit comments

Comments
 (0)