-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnumber_theory_miller_rabin.py
38 lines (36 loc) · 1.06 KB
/
number_theory_miller_rabin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Checks if p is probably prime
# exclude 2 from the check since it's obvious
# use pow instead of powmod to remove dependency
from random import randint
def miller_rabin(p):
if p % 2 == 0: return 0
if p == 3: return 1
d, s = p-1, 0
while d % 2 == 0: d //= 2; s += 1
for _ in range(3):
x = pow(randint(2, p-2), d, p)
for _ in range(s):
y = x**2 % p
if y == 1 and x != 1 and x != p-1: return 0
x = y
if y != 1: return 0
return 1
# Another variant
from random import randint
def miller_rabin(p):
if p % 2 == 0: return 0
if p == 3: return 1
d, s = p-1, 0
while d % 2 == 0: d //= 2; s += 1
for _ in range(3):
x = pow(randint(2, p-2), d, p)
if x == 1 or x == p-1: continue
ok = 0
for _ in range(s):
x = x*x%p
if x == 1: return 0
if x == p-1: ok = 1; break
if not ok: return 0
return 1
print(miller_rabin(10**9+7)) # prime
print(miller_rabin(10**9+3)) # not a prime