Path: blob/master/Discrete-Logarithm-Problem/Algo-Pollard-Rho/pollardrho.py
1402 views
"""1Source: Handbook of Applied Cryptography chapter-32http://cacr.uwaterloo.ca/hac/about/chap3.pdf3"""4from Crypto.Util.number import *56def func_f(x_i, base, y, p):7"""8x_(i+1) = func_f(x_i)9"""10if x_i % 3 == 2:11return (y*x_i) % p12elif x_i % 3 == 0:13return pow(x_i, 2, p)14elif x_i % 3 == 1:15return base*x_i % p16else:17print "[-] Something's wrong!"18return -11920def func_g(a, n, p, x_i):21"""22a_(i+1) = func_g(a_i, x_i)23"""24if x_i % 3 == 2:25return a26elif x_i % 3 == 0:27return 2*a % n28elif x_i % 3 == 1:29return (a + 1) % n30else:31print "[-] Something's wrong!"32return -13334def func_h(b, n, p, x_i):35"""36b_(i+1) = func_g(b_i, x_i)37"""38if x_i % 3 == 2:39return (b + 1) % n40elif x_i % 3 == 0:41return 2*b % n42elif x_i % 3 == 1:43return b44else:45print "[-] Something's wrong!"46return -14748def pollardrho(base, y, p, n):49"""50Refer to section 3.6.3 of Handbook of Applied Cryptography5152Computes `x` = a mod n for the DLP base**x % p == y53in the Group G = {0, 1, 2, ..., n}54given that order `n` is a prime number.5556:parameters:57base : int/long58Generator of the group59y : int/long60Result of base**x % p61p : int/long62Group over which DLP is generated.63n : int/long64Order of the group generated by `base`.65Should be prime for this implementation66"""6768if not isPrime(n):69print "[-] Order of group must be prime for Pollard Rho"70return -17172x_i = 173x_2i = 17475a_i = 076b_i = 077a_2i = 078b_2i = 07980i = 181while i <= n:82# Single Step calculations83a_i = func_g(a_i, n, p, x_i)84b_i = func_h(b_i, n, p, x_i)85x_i = func_f(x_i, base, y, p)8687# Double Step calculations88a_2i = func_g(func_g(a_2i, n, p, x_2i), n, p, func_f(x_2i, base, y, p))89b_2i = func_h(func_h(b_2i, n, p, x_2i), n, p, func_f(x_2i, base, y, p))90x_2i = func_f(func_f(x_2i, base, y, p), base, y, p)9192if x_i == x_2i:93"""94If x_i == x_2i is True95==> (base^(a_i))*(y^(b_i)) = (base^(a_2i))*(y^(b_2i)) (mod p)96==> y^(b_i - b_2i) = base^(a_2i - a_i) (mod p)97==> base^((b_i - b_2i)*x) = base^(a_2i - a_i) (mod p)98==> (b_i - b_2i)*x = (a_2i - a_i) (mod n)99100r = (b_i - b_2i) % n101if GCD(r, n) == 1 then,102==> x = (r^(-1))*(a_2i - a_i) (mod n)103104"""105r = (b_i - b_2i) % n106if r == 0:107print "[-] b_i = b_2i, returning -1"108return -1109else:110assert GCD(r, n) == 1111"""112If `n` is not a prime number this algorithm will not be able to113solve the DLP, because GCD(r, n) != 1 then and one will have to114write an implementation to solve the equation:115(b_i - b_2i)*x = (a_2i - a_i) (mod n)116This equation will have multiple solutions out of which only one117will be the actual solution118"""119return (inverse(r, n)*(a_2i - a_i)) % n120else:121i += 1122continue123124if __name__ == "__main__":125import random126for i in range(100):127num = random.randint(3, 381)128y = pow(2, num, 383)129assert pow(2, pollardrho(2, y, 383, 191), 383) == y130131132