# protocole d'échange de clé de Diffie-Hellman-Merkle
# 
# A noter que dans la "vraie vie", il faudrait qu'Alice et Bob:
# - génèrent d'abord N et M ensmemble
# - puis que chacun de leur côté, ils génèrent A1 et B1, et calculent A2 et B2
# - puis qu'Alice communique A2 à Bob, et que Bob communique B2 à Alice
# - puis qu'Alice calcule A3 de son côté, et que Bob calcule B3 de son côté

def diffie_hellman_merkle(n):
    N = randint(26**(n-1),26**n-1)
    M = randint(2,N-1)
    A1 = randint(2,N-1)
    B1 = randint(2,N-1)
    A2 = pow(M,A1,N)
    B2 = pow(M,B1,N)
    A3 = pow(B2,A1,N)
    B3 = pow(A2,B1,N)
    if A3 != B3:
        print("erreur",A3,"!=",B3)
        exit()
    else:
        return(A3)


def one_time_pad(mode,cle,message):
    message_numerique = [ord(lettre) - 65 for lettre in message]

    a = 1 - 2 * (mode == 'D')
    
    nouveau_message = ""
    for i in range(len(message)):
        nombre = message_numerique[i]
        if 0 <= nombre <= 25:
            nombre = (nombre + a * cle[i]) % 26
        nouveau_message += chr(nombre + 65)
    return(nouveau_message)


from random import *

message_origine = input("Message: ")
n = len(message_origine)
# K = randint(26**(n-1),26**n-1)  # clé aléatoire
K = diffie_hellman_merkle(n)
print("Clé:",K)
cle = []
while K>0:
    cle += [K%26]
    K = K//26

message_chiffre = one_time_pad('E',cle,message_origine)
print("Message chiffré:",message_chiffre)

message_dechiffre = one_time_pad('D',cle,message_chiffre)
print("Message déchiffré:",message_dechiffre)
