First commit
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
from Cryptotools.Groups.cyclic import Cyclic
|
||||
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||
from random import randint, choice
|
||||
from math import log, log10
|
||||
|
||||
"""
|
||||
Here, we will try to understand why we need to have a generator when we encrypt data for Diffie-Hellman
|
||||
https://crypto.stackexchange.com/questions/25489/why-does-diffie-hellman-need-be-a-cyclic-group
|
||||
"""
|
||||
def operation(a, b, n):
|
||||
return (a ** b) % n
|
||||
|
||||
def getGenerator(gr, p):
|
||||
index = 1
|
||||
for g in range(2, p):
|
||||
z = list()
|
||||
for entry in range(1, p):
|
||||
res = operation(g, index, p)
|
||||
#if res not in z:
|
||||
z.append(res)
|
||||
index = index + 1
|
||||
print(f"{g}: {sorted(z)}")
|
||||
|
||||
def getGenerator2(gr, p, g):
|
||||
index = 1
|
||||
z = list()
|
||||
for entry in range(1, p):
|
||||
res = operation(g, index, p)
|
||||
if res not in z:
|
||||
z.append(res)
|
||||
index = index + 1
|
||||
return z
|
||||
|
||||
|
||||
def computePublicKey(key, p, g):
|
||||
return (g ** key) % p
|
||||
|
||||
def computeEphemeralKey(public, secret, p):
|
||||
return (public ** secret) % p
|
||||
|
||||
gr = list()
|
||||
# Public value
|
||||
p = 43
|
||||
g = 0
|
||||
for i in range(1, p):
|
||||
gr.append(i)
|
||||
|
||||
print(f"p = {p}")
|
||||
print(f"G = {gr}")
|
||||
# We try with a generator which is not in list
|
||||
cyclic = Cyclic(gr, p, operation)
|
||||
generators = cyclic.getGenerators()
|
||||
print(f"All generators: {generators}")
|
||||
|
||||
g = 3 # In the group
|
||||
print(f"g = {g}")
|
||||
|
||||
# We can compute with the secret key
|
||||
secretKeyA = 5
|
||||
secretKeyB = 10
|
||||
publicKeyA = computePublicKey(secretKeyA, p, g)
|
||||
publicKeyB = computePublicKey(secretKeyB, p, g)
|
||||
print(f"Public key A: {publicKeyA}")
|
||||
print(f"Public key B: {publicKeyB}\n")
|
||||
|
||||
# Here, g is in the generator, we need to compute all values until that match with publicKeyA
|
||||
for a in range(1, p):
|
||||
res = operation(g, a, p)
|
||||
if res == publicKeyA:
|
||||
print(f"Brute forced secret key of A: {a}")
|
||||
|
||||
for a in range(1, p):
|
||||
res = operation(g, a, p)
|
||||
if res == publicKeyB:
|
||||
print(f"Brute forced secret key of B: {a}")
|
||||
|
||||
print()
|
||||
|
||||
#for a in generators:
|
||||
# print(a)
|
||||
#
|
||||
#print()
|
||||
|
||||
# Here, we generate all key withthe same generator
|
||||
keys = list()
|
||||
for a in range(1, p):
|
||||
keys.append(operation(g, a, p))
|
||||
|
||||
print((keys))
|
||||
print(sorted(keys))
|
||||
|
||||
print()
|
||||
|
||||
print(f"Keys with g = 4: {sorted(getGenerator2(gr, p, 4))}")
|
||||
|
||||
# Do the same, but g is not a generator
|
||||
g = 4 # Not in the generator group
|
||||
publicKeyA = computePublicKey(secretKeyA, p, g)
|
||||
publicKeyB = computePublicKey(secretKeyB, p, g)
|
||||
print(f"Public key A: {publicKeyA}")
|
||||
print(f"Public key B: {publicKeyB}")
|
||||
|
||||
keys = list()
|
||||
for a in range(1, p):
|
||||
keys.append(operation(g, a, p))
|
||||
print(keys)
|
||||
|
||||
# Eve sniff the traffic and knows p, g and publicKeyA and B
|
||||
# Eve, knows p and g, because it's public
|
||||
# Eve need to guess the secretKey of A.
|
||||
# For doing that, we iterate all posibility until that match with the publicKeyA
|
||||
|
||||
#for a in range(1, 4):
|
||||
# res = operation(g, a, p)
|
||||
# print(res)
|
||||
Reference in New Issue
Block a user