Blame | Last modification | View Log | RSS feed
import math
def Extended_Euclidian(a, b):
''' Takes values a and b and returns a tuple (r,s,t) in the following format:
r = s * a + t * b where r is the GCD and s and t are the inverses of a and b'''
t_ = 0
t = 1
s_ = 1
s = 0
q = a//b
r = a - q * b
# print("%d\t= %d * %d + %d" % (a, q, b, r))
while r > 0:
temp = t_ - q * t
t_ = t
t = temp
temp = s_ - q * s
s_ = s
s = temp
a = b
b = r
q = a//b
r = a - q * b
# print("%d\t= %d * %d + %d" % (a, q, b, r))
r = b
return (r, s, t)
def Inverse(a, b):
'''Returns the multiplicative inverse of a mod b'''
ret = Extended_Euclidian(a,b)
if (ret[1] < 0):
inv = ret[1] + b
else:
inv = ret[1]
return inv
def Shanks(n,a,b):
''' Implements the Shanks algorithm for solving the Discrete Logarithm Problem'''
m = math.ceil(math.sqrt(n))
d = a**m % n
# Generate and sort list L1
L1 = dict()
for i in range(m):
L1[i] = d**i % n
print('L1: (unsorted)')
for i in range(m):
print("%d\t:\t%d" % (i, L1[i]))
L1 = sorted(L1.items(), key=lambda x: x[1])
# Generate and sort list L2
L2 = dict()
for i in range(m):
L2[i] = b * Inverse(a**i, n) % n
print('L2: (unsorted)')
for i in range(m):
print("%d\t:\t%d" % (i, L2[i]))
L2 = sorted(L2.items(), key=lambda x: x[1])
# Search for a pair with identical second coordinates
for e in L1:
for f in L2:
if e[1] == f[1]:
j = e[0]
k = f[0]
break;
return m * j + k % n
if __name__ == '__main__':
# a = 2
# b = 767
# n = 526483
# d = Shanks(n, a, b)
# print(d)
# a = 2
# b = 48
# n = 101
# d = Shanks(n, a, b)
# print(d)
# a = 2
# b = (48**27)*(27**33)
# n = 101
# d = Shanks(n, a, b)
# print(d)
a = 2
b = 19
n = 4481
d = Shanks(n, a, b)
print(d)