#!/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):
    cyclic = Cyclic(gr, p, operation)
    generators = cyclic.getGenerators()
    print(f"All generators: {generators}")
    
    # Test with a no generator
    item = 2
    while item in generators: # we loop until we found an item which is not a generators of the group
        item = randint(1, p)
    return item

def computePublicKey(key, p, g):
    return (g ** key) % p

def computeEphemeralKey(public, secret, p):
    return (public ** secret) % p

gr = list()
# Public value
#p = getPrimeNumber(n = 8)
#p = 257
p = 19
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
g = getGenerator(gr, p)
#g = [3, 5, 6, 7, 10, 12, 14, 19, 20, 24, 27, 28, 33, 37, 38, 39, 40, 41, 43, 45, 47, 48, 51, 53, 54, 55, 56, 63, 65, 66, 69, 71, 74, 75, 76, 77, 78, 80, 82, 83, 85, 86, 87, 90, 91, 93, 94, 96, 97, 101, 102, 103, 105, 106, 107, 108, 109, 110, 112, 115, 119, 125, 126, 127, 130, 131, 132, 138, 142, 145, 147, 148, 149, 150, 151, 152, 154, 155, 156, 160, 161, 163, 164, 166, 167, 170, 171, 172, 174, 175, 177, 179, 180, 181, 182, 183, 186, 188, 191, 192, 194, 201, 202, 203, 204, 206, 209, 210, 212, 214, 216, 217, 218, 219, 220, 224, 229, 230, 233, 237, 238, 243, 245, 247, 250, 251, 252, 254]
g = 29 # Not 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}")

# Eve sniff the traffic and knows p, g and publicKeyA and B


# Generator need to be use, because that avoid to Eve to try to find a secret key of Alice or Bob ???
# Utiliser un generateur qui genere la tout le groupe, va permettre d'éviter à Eve de trouver la secret key de Alice ou Bob ????
# https://eitca.org/cybersecurity/eitc-is-acc-advanced-classical-cryptography/diffie-hellman-cryptosystem/diffie-hellman-key-exchange-and-the-discrete-log-problem/examination-review-diffie-hellman-key-exchange-and-the-discrete-log-problem/what-are-the-roles-of-the-prime-number-p-and-the-generator-alpha-in-the-diffie-hellman-key-exchange-process/
# https://www.perplexity.ai/search/why-generator-in-cyclic-group-QRYR6.rxSI218hs_x5CvnQ#0

# They exchange their public keys
ephemeralKeyA = computeEphemeralKey(publicKeyB, secretKeyA, p)
ephemeralKeyB = computeEphemeralKey(publicKeyA, secretKeyB, p)
print(f"Ephemeral key A: {ephemeralKeyA}")
print(f"Ephemeral key B: {ephemeralKeyB}")

# Test log10
#for i in range(1, 1000):
#    r = log10(i)
#    if isinstance(r, int):
#            print(f"{i} = {r}")
