46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
import random
|
|
from mod_inverse import modinv
|
|
|
|
def test_basic():
|
|
assert modinv(3, 11) == 4
|
|
assert modinv(10, 17) == 12
|
|
assert modinv(1, 5) == 1
|
|
|
|
def test_none():
|
|
assert modinv(2, 4) is None
|
|
assert modinv(6, 9) is None
|
|
assert modinv(0, 5) is None
|
|
|
|
def test_negative_a():
|
|
assert modinv(-1, 7) == 6
|
|
assert ( (-1)*modinv(-1,7) ) % 7 == 1 % 7
|
|
|
|
def test_brute():
|
|
for m in range(2, 200):
|
|
for a in range(0, m):
|
|
x = modinv(a, m)
|
|
g = None
|
|
# compute gcd
|
|
import math
|
|
if math.gcd(a % m, m) != 1:
|
|
assert x is None, (a, m, x)
|
|
else:
|
|
assert x is not None and 0 <= x < m
|
|
assert (a * x) % m == 1
|
|
|
|
def test_random_large():
|
|
random.seed(1)
|
|
for _ in range(2000):
|
|
m = random.randint(2, 10**6)
|
|
a = random.randint(0, m-1)
|
|
x = modinv(a, m)
|
|
import math
|
|
if math.gcd(a, m) != 1:
|
|
assert x is None
|
|
else:
|
|
assert x is not None and (a*x)%m == 1
|
|
|
|
if __name__ == "__main__":
|
|
test_basic(); test_none(); test_negative_a(); test_brute(); test_random_large()
|
|
print("ALL PASS")
|