15.4 rotor --- Chiffrement et déchiffrement de type Enigma

Ce module implémente un algorithme de chiffrement basé sur un rotor, écrit par Lance Ellinghouse. La conception est dérivée du dispositif Enigma, une machine utilisée pendant la 2ème guerre mondiale pour chiffrer les messages. Un rotor est simplement une permutation. Par exemple, si le caractère `A' est l'origine du rotor, alors un rotor donné pourrait associer `A' à `L', `B' à `Z', `C' à `G', et ainsi de suite. Pour chiffrer, nous choisissons différents rotors, et nous mettons l'origine de ces rotors à des positions connues; leur position initiale est la clé de chiffrement. Pour chiffrer un caractère, nous permutons le caractère d'origine avec le premier rotor, puis nous appliquons la permutation du deuxième rotor au résultat. Nous continuons jusqu'à avoir appliqué tous les rotors; le caractère résultant est notre texte chiffré. Nous décalons ensuite l'origine du dernier rotor d'une position, de `A' à `B'; si le dernier rotor a fait un tour complet, nous faisons tourner l'avant-dernier rotor d'une position, et appliquons la même procédure récursivement. En d'autres termes, après avoir chiffré un caractère, nous avançons les rotors de la même façon qu'un compteur kilométrique de voiture. Le déchiffrement fonctionne de la même façon, sauf que nous renversons les permutations et les appliquons dans l'ordre inverse

Les fonctions disponibles dans ce module sont :

newrotor(clef[, nombrerotors])
Retourne un objet rotor. clef est une chaîne de caractères contenant la clef de chiffrement pour cet objet; elle peut contenir des données binaires arbitraires. La clef sera utilisée pour générer aléatoirement les permutations des rotors et leurs positions initiales. nombrerotors est le nombre de permutations de rotors dans l'objet renvoyé ; s'il est omis, une valeur par défaut de 6 sera utilisée.

Les objets rotor possèdent les méthodes suivantes :

rotorsetkey(clef)
Affecte la valeur clef à la clef du rotor.

rotorencrypt(texteclair)
Remet l'objet rotor dans son état initial et chiffre texteclair, en retournant une chaîne de caractères contenant le texte chiffré. Le texte chiffré a toujours la même longueur que le texte en clair d'origine.

rotorencryptmore(texteclair)
Chiffre texteclair sans réinitialiser l'objet rotor, et retourne une chaîne de caractères contenant le texte chiffré.

rotordecrypt(textechiffre)
Remet l'objet rotor dans son état initial et déchiffre textechiffre, en retournant une chaîne de caractères contenant le texte en clair. Le texte en clair a toujours la même longueur que le texte chiffré.

rotordecryptmore(textechiffre)
Déchiffre textechiffre sans réinitialiser l'objet rotor, et retourne une chaîne de caractères contenant le texte en clair.

Exemple d'utilisation:

>>> import rotor
>>> rt = rotor.newrotor('clé', 12)
>>> rt.encrypt('bar')
'@\014P'
>>> rt.encryptmore('bar')
'\301\013\263'
>>> rt.encrypt('bar')
'@\014P'
>>> rt.decrypt('@\014P')
'bar'
>>> rt.decryptmore('\301\013\263')
'bar'
>>> rt.decrypt('\301\013\263')
')V\316'
>>> del rt

Le code du module n'est pas une simulation exacte du dispositif Enigma d'origine ; il implémente le procédé de chiffrement du rotor différemment de l'original. La différence la plus importante est que dans l'Enigma d'origine, il n'y avait que 5 ou 6 rotors différents en action, et qu'ils étaient appliqués deux fois à chaque caractère ; la clef de chiffrement était l'ordre dans lequel ils étaient placés dans la machine. Le module Python rotor utilise la clef fournie pour initialiser un générateur de nombres aléatoires ; les permutations des rotors et leurs positions initiales sont alors générées aléatoirement. Le dispositif d'origine ne chiffrait que les lettres de l'alphabet, alors que ce module peut traiter n'importe quelle donnée binaire sur 8 bits ; il produit aussi une sortie binaire. Ce module peut aussi travailler avec un nombre arbitraire de rotors.

Le code de l'Enigma d'origine fut cassé en 1944. La version implémentée ici est sans doute beaucoup plus difficile à craquer (surtout si vous utilisez beaucoup de rotors), mais il ne sera pas impossible à un attaquant vraiment habile et déterminé de casser le code. Aussi, si vous voulez éviter que le NSA ne vienne mettre son nez dans vos fichiers, le chiffrement par rotor peut ne pas être assez sûr ; mais pour décourager un fouineur occasionnel dans vos fichiers, il fera probablement très bien l'affaire, et ce doit être un peu plus sûr que d'utiliser la commande UNIX crypt.