Path: blob/master/Discrete-Logarithm-Problem/Algo-Pohlig-Hellman/ph_orderp2.py
1392 views
from Crypto.Util.number import *12def pohlig_hellman_p2(g, y, p, e):3"""4Computes `x` for the DLP y = g**x % p in the Group G = {0, 1, 2, ..., p-1},5given that order of the group `n` is a power of 2, ie. n = p-1 = 2**e.67Note that to solve the DLP using this code, `g` must be the generator.89:parameters:10g : int/long11Generator of the group12y : int/long13Result of g**x % p14p : int/long15Group over which DLP is generated. Commonly p is a prime number16e : int/long17Exponent of 2 in the group order: n = p-1 = 2**e18"""19try:20assert 2**e == p - 121except:22print "[-] Error! 2**e is not equal to order!"23return -12425k = e26# x is a `k` bit number, max value of x is (2**k - 1)27# x = (c_0 * 2**0) + (c_1 * 2**1) + (c_2 * 2**2) + ... + (c_(k-1) * 2**(k-1))28# where c_0, c_1, c_2, ..., c_(k-1) belong to {0, 1}29x = ""3031for i in range(1, k+1):32val = pow(y, 2**(k-i), p)33if val == 1:34# val == 1 ==> c_i == 0 (Euler's Theorem)35# digit = c_i36digit = 037x += "0"38# y = y*(g**(-c_i*(2**i)) % p) % p = y*(g**0 % p) % p = y % p39y = y40elif val == p-1:41# val == p-1 ==> c_i == 142# digit = c_i43digit = 144x += "1"45# We need to calculate y = y*(g**(-c_i*(2**i)) % p) % p46# Computed using Step-1 and Step-247# Step-1: multiplier = g**(2**(i-1)) % p48multiplier = pow(g, digit*(2**(i-1)), p)49# To calculate inverse of `multiplier` mod p, their GCD should be equal to 150if GCD(multiplier, p) != 1:51print "[-] GCD != 1, inverse cannot be calculated. Check your code!"52return -153# Step-2: y = y*(g**(-2**(i-1)) % p) % p54y = (y*inverse(multiplier, p)) % p55else:5657print "[-] Some error encountered! Check your code!"58return -159# Values of c_i are appended to `x` in reverse order60return int(x[::-1], 2)6162if __name__ == "__main__":63try:64assert pow(3, pohlig_hellman_p2(3, 188, 257, 8), 257) == 18865assert pow(3, pohlig_hellman_p2(3, 46777, 65537, 16), 65537) == 4677766except:67print "[-] Function implementation incorrect!"686970