import datetime
import hashlib
import codecs
# + DANE WEJSCIOWE PRZYPADKU TESTOWEGO:
g = 2
p = 826 * (2^256 + 297) + 1
A = 42463453489046421827996953285270976791039960776773031565373820328717752373085105
B = 74431962970322258898740862853418488921843421761336220388456850850534859078805104
INTERVAL_BEG = datetime.datetime(2020, 4, 2, 8, 0, 0)
INTERVAL_END = datetime.datetime(2020, 4, 2, 16, 0, 1)
# + funkcja od niego, nic ciekawego
def Alice_secret_gen(rand):
h = hashlib.sha256()
h.update(bin(rand).encode("UTF-8"))
_digest = h.digest()
secret = int(codecs.encode(_digest, 'hex'), 16)
return secret
# 1
EPOCH = datetime.datetime(1970, 1, 1)
# + _datetime zawiera jedną z tych dat co chcemy sprawdzić a epoch datę początku epoki więc żeby obliczyć
# + czas jaki minał od epoki do danej daty można, wykorzystując format datetime odjąć je od siebie.
# + Efekt tego otrzymujemy okres czasu. Aby z tego okresu wyciągnąć liczbę sekund, możemy użyć funkcji dla datetime
# + jaką jest .total_seconds(). Zwraca ona float (1585814400.0) a jako że to jest liczba całkowita to nie potrzebujemy jej w float
# + stąd konwersja na całkowite poprzez int().
def seconds_since_epoch(_datetime):
return int((_datetime - EPOCH).total_seconds())
# zakres poszukiwanych wartości RAND
beg = seconds_since_epoch(INTERVAL_BEG)
end = seconds_since_epoch(INTERVAL_END)
# 2
# Wejście:
# - g – generator ciała
# - prime - liczba pierwsza definiująca ciało
# - secret – tajny klucz
# + Proste, podnosimy g^secret w ciele prime, wykorzystując funkcję którą tam pod koniec zadania podał
def public_component(g, prime, secret):
return pow(g, secret, prime)
# Wejście:
# - rcv – otrzymany component publiczny
# - prime - liczba pierwsza definiująca ciało
# - secret – tajny klucz
# Wyjście:
# wspólny klucz kryptograficzny
# + Jak wyżej, klucz wspólny w Diffie-Hellman'ie to podniesienie klucza publicznego drugiej osoby do swojego sekretu
def common_key(rcv, prime, secret):
return pow(rcv, secret, prime)
# 3
# sprawdzanie, czy i jest źródłem losowości
# tj. czy Alice_secret_gen(i) jest sekretną wartością Alicji
# + Niewiadomą jest sekret alicji, ale mamy podany jej klucz publiczny (pod A) i wszystko inne więc
# + wystarczy dla każdego możliwego i sprawdzać czy wygenerowany przy jego pomocy klucz publiczny się zgadza.
# + Jak już na taki trafimy to wykorzystujemy napisane wcześniej funkcje żeby policzyć co chce, wypisać mu to ładnie
# + i dodałem też potwierdzenie że te klucze publiczne się zgadzają
for i in range(beg, end):
if public_component(g, p, Alice_secret_gen(i)) == A:
k = common_key(B, p, i)
s = Alice_secret_gen(i)
kp = public_component(g, p, s)
print("s =", s)
print("k =", k)
print("i =", i)
print("Klucz publiczny Alice (wykorzystując s) = ", kp)
if kp == A:
print("Klucze publiczne się zgadzają")