Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ashutosh1206
GitHub Repository: ashutosh1206/crypton
Path: blob/master/Discrete-Logarithm-Problem/Algo-Pohlig-Hellman/ph_orderp2.py
1392 views
1
from Crypto.Util.number import *
2
3
def pohlig_hellman_p2(g, y, p, e):
4
"""
5
Computes `x` for the DLP y = g**x % p in the Group G = {0, 1, 2, ..., p-1},
6
given that order of the group `n` is a power of 2, ie. n = p-1 = 2**e.
7
8
Note that to solve the DLP using this code, `g` must be the generator.
9
10
:parameters:
11
g : int/long
12
Generator of the group
13
y : int/long
14
Result of g**x % p
15
p : int/long
16
Group over which DLP is generated. Commonly p is a prime number
17
e : int/long
18
Exponent of 2 in the group order: n = p-1 = 2**e
19
"""
20
try:
21
assert 2**e == p - 1
22
except:
23
print "[-] Error! 2**e is not equal to order!"
24
return -1
25
26
k = e
27
# x is a `k` bit number, max value of x is (2**k - 1)
28
# x = (c_0 * 2**0) + (c_1 * 2**1) + (c_2 * 2**2) + ... + (c_(k-1) * 2**(k-1))
29
# where c_0, c_1, c_2, ..., c_(k-1) belong to {0, 1}
30
x = ""
31
32
for i in range(1, k+1):
33
val = pow(y, 2**(k-i), p)
34
if val == 1:
35
# val == 1 ==> c_i == 0 (Euler's Theorem)
36
# digit = c_i
37
digit = 0
38
x += "0"
39
# y = y*(g**(-c_i*(2**i)) % p) % p = y*(g**0 % p) % p = y % p
40
y = y
41
elif val == p-1:
42
# val == p-1 ==> c_i == 1
43
# digit = c_i
44
digit = 1
45
x += "1"
46
# We need to calculate y = y*(g**(-c_i*(2**i)) % p) % p
47
# Computed using Step-1 and Step-2
48
# Step-1: multiplier = g**(2**(i-1)) % p
49
multiplier = pow(g, digit*(2**(i-1)), p)
50
# To calculate inverse of `multiplier` mod p, their GCD should be equal to 1
51
if GCD(multiplier, p) != 1:
52
print "[-] GCD != 1, inverse cannot be calculated. Check your code!"
53
return -1
54
# Step-2: y = y*(g**(-2**(i-1)) % p) % p
55
y = (y*inverse(multiplier, p)) % p
56
else:
57
58
print "[-] Some error encountered! Check your code!"
59
return -1
60
# Values of c_i are appended to `x` in reverse order
61
return int(x[::-1], 2)
62
63
if __name__ == "__main__":
64
try:
65
assert pow(3, pohlig_hellman_p2(3, 188, 257, 8), 257) == 188
66
assert pow(3, pohlig_hellman_p2(3, 46777, 65537, 16), 65537) == 46777
67
except:
68
print "[-] Function implementation incorrect!"
69
70