Le chiffrement de ElGamal est une technique cryptographique asymétrique voisine de la technique RSA vue en Terminale NSI, mais plus simple.
Cette technique, comme RSA, basée sur des propriétés arithmétiques – mathématiques des nombres entiers – fait un grand usage des puissances et des modulos.
Vous pouvez donc consulter l'intérêt des modulos en cryptographie
Vous devrez aussi passer voir ces deux exercices avant :
Vous aurez besoin des fonctions puissance_rapide_mod et inverse_modulaire implémentées dans ces deux exercices.
Je noterai ci-dessous $\cdots\overset{p}{\equiv}\cdots$ pour $\cdots = \cdots \mod p$.
Comme dit précédemment, il s'agit d'un chiffre asymétrique. Il y aura donc une clé publique Kpu pour le chiffrement et une clé privée Kpr pour le déchiffrement.
Voici comment Bob va créer ces clés :
La clé publique de Bob est composé du triplet $(p, d, h)$. Il peut la transmettre en clair.
L'idée est que $s$ sera utile au calcul de déchiffrement et que $s$ est difficile à trouver quand on ne connaît que $(p, d, h)$. Vous pouvez consulter cette page pour comprendre mieux pourquoi.
Alice veut transmettre un nombre $m$, c'est son message. Elle a reçu les trois morceaux de la clé de Bob.
Bob reçoit $(r, t)$, il peut utiliser $s$ qu'il est seul à connaître,
Un mot d'explication :
Comme vous le voyez, le déchiffrement exploite le fait que calculer $a^b \mod p$ est très rapide. Connaissant $s$, les calculs à faire pour déchiffrer sont rapides.
En connaissant la clé publique $(p, d, h)$, on pourrait trouver la valeur de $s$ mais cela nécessiterait beaucoup de calculs et donc beaucoup de temps. En gros il faudrait essayer toutes les valeurs entre 1 et $p$ ce qui serait long pour un $p$ très grand.
Vous disposes déjà des fonctions :
puissance_rapide_mod(a,b,q) vue dans Exponentiation modulaireinverse_modulaire(a,p) vue dans Inverse modulaire
Pour le choix de a lors du chiffrement, vous pouvez générer un entier aléatoire par exemple avec randrange du module random.
Écrire de plus les fonctions suivantes :
calculer_cle_publique(Kpr) qui reçoit Kpr = (p, d, s) et renvoie Kpu = (p, d, h)chiffrer(m, Kpu) qui reçoit le message m et la clé publique Kpu et renvoie la paire mc = (r, t) du message chiffrédechiffrer(mc, Kpr) qui reçoit le message chiffré et la clé privée et renvoie le message déchiffré..
Faire le test en choisissant Kpr(7639, 59, 13), m = 253.