blob: 0f848e08d3df151f25dcf8b7761f759c394ad3df [file] [log] [blame]
Fred Drake295da241998-08-10 19:42:37 +00001\section{\module{rotor} ---
Fred Drakef8ca7d82000-10-10 17:03:45 +00002 Enigma-like encryption and decryption}
Fred Drakeb91e9341998-07-23 17:59:49 +00003
Fred Drakef8ca7d82000-10-10 17:03:45 +00004\declaremodule{builtin}{rotor}
Fred Drakeb91e9341998-07-23 17:59:49 +00005\modulesynopsis{Enigma-like encryption and decryption.}
6
Andrew M. Kuchlingbbb9a552003-04-24 13:19:09 +00007\deprecated{2.3}{The encryption algorithm is insecure.}
8
Guido van Rossum5fdeeea1994-01-02 01:22:07 +00009
Guido van Rossum16d6e711994-08-08 12:30:22 +000010This module implements a rotor-based encryption algorithm, contributed by
Fred Drakefc576191998-04-04 07:15:02 +000011Lance Ellinghouse\index{Ellinghouse, Lance}. The design is derived
12from the Enigma device\indexii{Enigma}{device}, a machine
Guido van Rossum16d6e711994-08-08 12:30:22 +000013used during World War II to encipher messages. A rotor is simply a
14permutation. For example, if the character `A' is the origin of the rotor,
15then a given rotor might map `A' to `L', `B' to `Z', `C' to `G', and so on.
16To encrypt, we choose several different rotors, and set the origins of the
17rotors to known positions; their initial position is the ciphering key. To
18encipher a character, we permute the original character by the first rotor,
19and then apply the second rotor's permutation to the result. We continue
20until we've applied all the rotors; the resulting character is our
21ciphertext. We then change the origin of the final rotor by one position,
22from `A' to `B'; if the final rotor has made a complete revolution, then we
23rotate the next-to-last rotor by one position, and apply the same procedure
24recursively. In other words, after enciphering one character, we advance
25the rotors in the same fashion as a car's odometer. Decoding works in the
26same way, except we reverse the permutations and apply them in the opposite
27order.
Guido van Rossum16d6e711994-08-08 12:30:22 +000028\indexii{Enigma}{cipher}
29
30The available functions in this module are:
31
Fred Drakecce10901998-03-17 06:33:25 +000032\begin{funcdesc}{newrotor}{key\optional{, numrotors}}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000033Return a rotor object. \var{key} is a string containing the encryption key
Guido van Rossuma861d552002-06-10 19:42:43 +000034for the object; it can contain arbitrary binary data but not null bytes.
35The key will be used
Guido van Rossum16d6e711994-08-08 12:30:22 +000036to randomly generate the rotor permutations and their initial positions.
37\var{numrotors} is the number of rotor permutations in the returned object;
38if it is omitted, a default value of 6 will be used.
39\end{funcdesc}
40
41Rotor objects have the following methods:
42
Fred Drakefc576191998-04-04 07:15:02 +000043\begin{methoddesc}[rotor]{setkey}{key}
Guido van Rossuma861d552002-06-10 19:42:43 +000044Sets the rotor's key to \var{key}. The key should not contain null bytes.
Fred Drakefc576191998-04-04 07:15:02 +000045\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000046
Fred Drakefc576191998-04-04 07:15:02 +000047\begin{methoddesc}[rotor]{encrypt}{plaintext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000048Reset the rotor object to its initial state and encrypt \var{plaintext},
Guido van Rossum16d6e711994-08-08 12:30:22 +000049returning a string containing the ciphertext. The ciphertext is always the
50same length as the original plaintext.
Fred Drakefc576191998-04-04 07:15:02 +000051\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000052
Fred Drakefc576191998-04-04 07:15:02 +000053\begin{methoddesc}[rotor]{encryptmore}{plaintext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000054Encrypt \var{plaintext} without resetting the rotor object, and return a
Guido van Rossum16d6e711994-08-08 12:30:22 +000055string containing the ciphertext.
Fred Drakefc576191998-04-04 07:15:02 +000056\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000057
Fred Drakefc576191998-04-04 07:15:02 +000058\begin{methoddesc}[rotor]{decrypt}{ciphertext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000059Reset the rotor object to its initial state and decrypt \var{ciphertext},
Tim Petersa3100de2000-11-14 21:43:01 +000060returning a string containing the plaintext. The plaintext string will
Guido van Rossum16d6e711994-08-08 12:30:22 +000061always be the same length as the ciphertext.
Fred Drakefc576191998-04-04 07:15:02 +000062\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000063
Fred Drakefc576191998-04-04 07:15:02 +000064\begin{methoddesc}[rotor]{decryptmore}{ciphertext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000065Decrypt \var{ciphertext} without resetting the rotor object, and return a
Tim Petersa3100de2000-11-14 21:43:01 +000066string containing the plaintext.
Fred Drakefc576191998-04-04 07:15:02 +000067\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000068
69An example usage:
Fred Drake19479911998-02-13 06:58:54 +000070\begin{verbatim}
Guido van Rossum16d6e711994-08-08 12:30:22 +000071>>> import rotor
72>>> rt = rotor.newrotor('key', 12)
73>>> rt.encrypt('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000074'\xab4\xf3'
Guido van Rossum16d6e711994-08-08 12:30:22 +000075>>> rt.encryptmore('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000076'\xef\xfd$'
Guido van Rossum16d6e711994-08-08 12:30:22 +000077>>> rt.encrypt('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000078'\xab4\xf3'
79>>> rt.decrypt('\xab4\xf3')
Guido van Rossum16d6e711994-08-08 12:30:22 +000080'bar'
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000081>>> rt.decryptmore('\xef\xfd$')
Guido van Rossum16d6e711994-08-08 12:30:22 +000082'bar'
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000083>>> rt.decrypt('\xef\xfd$')
84'l(\xcd'
Guido van Rossum16d6e711994-08-08 12:30:22 +000085>>> del rt
Fred Drake19479911998-02-13 06:58:54 +000086\end{verbatim}
Fred Drakefc576191998-04-04 07:15:02 +000087
88The module's code is not an exact simulation of the original Enigma
89device; it implements the rotor encryption scheme differently from the
90original. The most important difference is that in the original
91Enigma, there were only 5 or 6 different rotors in existence, and they
92were applied twice to each character; the cipher key was the order in
93which they were placed in the machine. The Python \module{rotor}
94module uses the supplied key to initialize a random number generator;
95the rotor permutations and their initial positions are then randomly
96generated. The original device only enciphered the letters of the
97alphabet, while this module can handle any 8-bit binary data; it also
98produces binary output. This module can also operate with an
Guido van Rossum16d6e711994-08-08 12:30:22 +000099arbitrary number of rotors.
100
101The original Enigma cipher was broken in 1944. % XXX: Is this right?
102The version implemented here is probably a good deal more difficult to crack
103(especially if you use many rotors), but it won't be impossible for
Thomas Woutersf8316632000-07-16 19:01:10 +0000104a truly skillful and determined attacker to break the cipher. So if you want
Guido van Rossum16d6e711994-08-08 12:30:22 +0000105to keep the NSA out of your files, this rotor cipher may well be unsafe, but
106for discouraging casual snooping through your files, it will probably be
Fred Drake75fc0451998-02-16 21:36:57 +0000107just fine, and may be somewhat safer than using the \UNIX{} \program{crypt}
Guido van Rossum16d6e711994-08-08 12:30:22 +0000108command.
Fred Drake75fc0451998-02-16 21:36:57 +0000109\index{NSA}
Fred Drakefc576191998-04-04 07:15:02 +0000110\index{National Security Agency}