Blame | Last modification | View Log | Download | RSS feed
import mathdef 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_ = 0t = 1s_ = 1s = 0q = a//br = a - q * b# print("%d\t= %d * %d + %d" % (a, q, b, r))while r > 0:temp = t_ - q * tt_ = tt = temptemp = s_ - q * ss_ = ss = tempa = bb = rq = a//br = a - q * b# print("%d\t= %d * %d + %d" % (a, q, b, r))r = breturn (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] + belse:inv = ret[1]return invdef 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 L1L1 = dict()for i in range(m):L1[i] = d**i % nprint('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 L2L2 = dict()for i in range(m):L2[i] = b * Inverse(a**i, n) % nprint('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 coordinatesfor e in L1:for f in L2:if e[1] == f[1]:j = e[0]k = f[0]break;return m * j + k % nif __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 = 2b = 19n = 4481d = Shanks(n, a, b)print(d)