Last active
June 27, 2017 08:36
-
-
Save kaminomisosiru/e9fed373fa04f22cba5e842e921023a9 to your computer and use it in GitHub Desktop.
Cryptographic Algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import functools | |
def gcd(x, y): | |
''' | |
Euclidean Algorithm | |
return gcd(x, y) | |
''' | |
while y: | |
x, y = y, x % y | |
return x | |
def egcd(x, y): | |
''' | |
Extended Euclidean Algorithm | |
return a, b, gcd(x, y) such that ax + by = gcd(x, y) | |
''' | |
if y == 0: | |
return 1, 0, x | |
else: | |
q = x // y | |
r = x % y | |
b, a, g = egcd(y, r) | |
return a, b - x // y * a, g | |
def mod_inv(a, n): | |
''' | |
return b such that ab = 1 mod n | |
''' | |
inv, _, _ = egcd(a, n) | |
return inv % n | |
def chinese_remainder(eq1, eq2): | |
''' | |
Chinese remainder theorem | |
calculate x such that | |
x = a1 mod n1 | |
x = a2 mod n2 | |
@param eq1 = (a1, n1) | |
@param eq2 = (a2, n2) | |
@return x, mod(= n1*n2) | |
''' | |
a1, n1 = eq1 | |
a2, n2 = eq2 | |
p, q, g = egcd(n1, n2) | |
x = a1 + (a2 - a1)*p*n1 | |
mod = n1*n2 | |
return x % mod, mod | |
def baby_step_giant_step(g, y, p, q): | |
''' | |
baby-step giant-step algorithm | |
calculate x such that g^x(=y) mod p | |
@param g generator | |
@param y = g^x | |
@param p modulus(prime) | |
@param q order of g | |
@return x discrete logarithm | |
''' | |
table = {} | |
m = int(q ** 0.5 + 1) | |
# baby step | |
b = 1 | |
for j in range(m): | |
table[b] = j | |
b = b * g % p | |
gm = mod_inv(pow(g, m, p), p) | |
r = y | |
# giant step | |
for i in range(m): | |
if r in table: | |
x = i*m + table[r] | |
print("Found:", x) | |
return x | |
else: | |
r = r * gm % p | |
def pohlig_hellman(p, g, y, phi_p): | |
''' | |
pohlig hellman algorithm | |
''' | |
print(phi_p) | |
eqs = [] | |
for q in phi_p: | |
b = baby_step_giant_step(pow(g, (p-1)//q, p), pow(y, (p-1)//q, p), p, q) | |
eqs.append((b, q)) | |
x, mod = functools.reduce(chinese_remainder, eqs) | |
return x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment