def generateKeys(): """Generate keys for DSA""" # La génération de nombre premiers n'est fiable qu'avec des nombres plus # petits que 2^64 à cause de la fonction isprime(). Cette fonction, d'après # la documentation, assure un nombre premier jusqu'à 2^64 puis n'en fait # plus qu'assumer leurs primalités pour des nombres plus gros. p = getPrime(18446744073708551616, 18446744073709551616) q, z = getQandZinDSA(p) # On recherche h entre 1 et p-1, tel que h^z mod p > 1 h = random.randint(0, p) while fastModularExp(h, z, p) == 1: h = random.randint(0, p) g = fastModularExp(h, z, p) x = random.randint(0, q) # Private key y = fastModularExp(g, x, p) # Public key print("\nPublic key : \n") print("y : " + str(y)) print("\nPublic key components : \n") print("p : " + str(p)) print("q : " + str(q)) print("g : " + str(g)) print("\nPrivate key : \n") print("x : " + str(x)) print("\nPrivate key components : \n") print("z : " + str(z)) print("h : " + str(h)) return (p, q, g, x, y)
def verification(M, p, q, g, y, r, s): """Verify DSA signature""" w = extendedEuclide(s, q) % q print("w : " + str(w)) u1 = (M * w) % q print("u1 : " + str(u1)) u2 = (r * w) % q print("u2 : " + str(u2)) v = ((fastModularExp(y, u2, p) * fastModularExp(g, u1, p)) % p) % q print("v : " + str(v)) if (v == r): return True return False
def signMessage(M, p, q, g, x): """Sign message with DSA""" k = random.randint(2, q) # Random and never reused uK = extendedEuclide(k, q) % q print("uK : " + str(uK)) print("\nSignature : \n") r = fastModularExp(g, k, p) % q print("r : " + str(r)) s = (M + x * r) * uK % q print("s : " + str(s)) # Ici, la signature est faite sur le message, mais elle devrait être faite # sur le hachage de celui-ci : nous conserverions ainsi l'intégrité et # l'authenticité des données. return (r, s)
def decrypt(C, K, k, p): """Decrypt cyphermessage C with private key k and sender public key K and prime p""" return fastModularExp(C * fastModularExp(K, p - 1 - k, p), 1, p)
def encrypt(M, S, p): """Encrypt message M with shared key S and prime p""" return fastModularExp(M * S, 1, p)
def generateKeys(p, g): """Generate new random Diffie-Helmann Keys from prime p and primitive root g""" k = random.randint(0, p) # Secret key K = fastModularExp(g, k, p) # Public key return (k, K)
"""Encrypt message M with shared key S and prime p""" return fastModularExp(M * S, 1, p) def decrypt(C, K, k, p): """Decrypt cyphermessage C with private key k and sender public key K and prime p""" return fastModularExp(C * fastModularExp(K, p - 1 - k, p), 1, p) if __name__ == '__main__': print("Diffie-Helmann starting...") p = getPrime(100000000000, 55000000000000) g = getFirstPrimitiveRoot(p) a, A = generateKeys(p, g) b, B = generateKeys(p, g) S = fastModularExp(A, b, p) # Shared key M = 78 # Message C = encrypt(M, S, p) M2 = decrypt(C, B, a, p) print("\n=== Key Generation ===\n") print("\nGlobal keys : ") print(" p : " + str(p)) print(" g : " + str(g)) print("\nPublic keys : ") print(" for Alice A : " + str(A)) print(" for Bob B : " + str(B)) print("\nPrivate keys : ")