blob: e1db8eff06d356ea3177886e093659d11e54f210 [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
Guido van Rossum5fdeeea1994-01-02 01:22:07 +00007
Guido van Rossum16d6e711994-08-08 12:30:22 +00008This module implements a rotor-based encryption algorithm, contributed by
Fred Drakefc576191998-04-04 07:15:02 +00009Lance Ellinghouse\index{Ellinghouse, Lance}. The design is derived
10from the Enigma device\indexii{Enigma}{device}, a machine
Guido van Rossum16d6e711994-08-08 12:30:22 +000011used during World War II to encipher messages. A rotor is simply a
12permutation. For example, if the character `A' is the origin of the rotor,
13then a given rotor might map `A' to `L', `B' to `Z', `C' to `G', and so on.
14To encrypt, we choose several different rotors, and set the origins of the
15rotors to known positions; their initial position is the ciphering key. To
16encipher a character, we permute the original character by the first rotor,
17and then apply the second rotor's permutation to the result. We continue
18until we've applied all the rotors; the resulting character is our
19ciphertext. We then change the origin of the final rotor by one position,
20from `A' to `B'; if the final rotor has made a complete revolution, then we
21rotate the next-to-last rotor by one position, and apply the same procedure
22recursively. In other words, after enciphering one character, we advance
23the rotors in the same fashion as a car's odometer. Decoding works in the
24same way, except we reverse the permutations and apply them in the opposite
25order.
Guido van Rossum16d6e711994-08-08 12:30:22 +000026\indexii{Enigma}{cipher}
27
28The available functions in this module are:
29
Fred Drakecce10901998-03-17 06:33:25 +000030\begin{funcdesc}{newrotor}{key\optional{, numrotors}}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000031Return a rotor object. \var{key} is a string containing the encryption key
Guido van Rossum16d6e711994-08-08 12:30:22 +000032for the object; it can contain arbitrary binary data. The key will be used
33to randomly generate the rotor permutations and their initial positions.
34\var{numrotors} is the number of rotor permutations in the returned object;
35if it is omitted, a default value of 6 will be used.
36\end{funcdesc}
37
38Rotor objects have the following methods:
39
Fred Drakefc576191998-04-04 07:15:02 +000040\begin{methoddesc}[rotor]{setkey}{key}
Barry Warsaw67170301997-01-02 19:48:00 +000041Sets the rotor's key to \var{key}.
Fred Drakefc576191998-04-04 07:15:02 +000042\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000043
Fred Drakefc576191998-04-04 07:15:02 +000044\begin{methoddesc}[rotor]{encrypt}{plaintext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000045Reset the rotor object to its initial state and encrypt \var{plaintext},
Guido van Rossum16d6e711994-08-08 12:30:22 +000046returning a string containing the ciphertext. The ciphertext is always the
47same length as the original plaintext.
Fred Drakefc576191998-04-04 07:15:02 +000048\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000049
Fred Drakefc576191998-04-04 07:15:02 +000050\begin{methoddesc}[rotor]{encryptmore}{plaintext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000051Encrypt \var{plaintext} without resetting the rotor object, and return a
Guido van Rossum16d6e711994-08-08 12:30:22 +000052string containing the ciphertext.
Fred Drakefc576191998-04-04 07:15:02 +000053\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000054
Fred Drakefc576191998-04-04 07:15:02 +000055\begin{methoddesc}[rotor]{decrypt}{ciphertext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000056Reset the rotor object to its initial state and decrypt \var{ciphertext},
Tim Petersa3100de2000-11-14 21:43:01 +000057returning a string containing the plaintext. The plaintext string will
Guido van Rossum16d6e711994-08-08 12:30:22 +000058always be the same length as the ciphertext.
Fred Drakefc576191998-04-04 07:15:02 +000059\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000060
Fred Drakefc576191998-04-04 07:15:02 +000061\begin{methoddesc}[rotor]{decryptmore}{ciphertext}
Guido van Rossum6bb1adc1995-03-13 10:03:32 +000062Decrypt \var{ciphertext} without resetting the rotor object, and return a
Tim Petersa3100de2000-11-14 21:43:01 +000063string containing the plaintext.
Fred Drakefc576191998-04-04 07:15:02 +000064\end{methoddesc}
Guido van Rossum16d6e711994-08-08 12:30:22 +000065
66An example usage:
Fred Drake19479911998-02-13 06:58:54 +000067\begin{verbatim}
Guido van Rossum16d6e711994-08-08 12:30:22 +000068>>> import rotor
69>>> rt = rotor.newrotor('key', 12)
70>>> rt.encrypt('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000071'\xab4\xf3'
Guido van Rossum16d6e711994-08-08 12:30:22 +000072>>> rt.encryptmore('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000073'\xef\xfd$'
Guido van Rossum16d6e711994-08-08 12:30:22 +000074>>> rt.encrypt('bar')
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000075'\xab4\xf3'
76>>> rt.decrypt('\xab4\xf3')
Guido van Rossum16d6e711994-08-08 12:30:22 +000077'bar'
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000078>>> rt.decryptmore('\xef\xfd$')
Guido van Rossum16d6e711994-08-08 12:30:22 +000079'bar'
Ka-Ping Yeefa004ad2001-01-24 17:19:08 +000080>>> rt.decrypt('\xef\xfd$')
81'l(\xcd'
Guido van Rossum16d6e711994-08-08 12:30:22 +000082>>> del rt
Fred Drake19479911998-02-13 06:58:54 +000083\end{verbatim}
Fred Drakefc576191998-04-04 07:15:02 +000084
85The module's code is not an exact simulation of the original Enigma
86device; it implements the rotor encryption scheme differently from the
87original. The most important difference is that in the original
88Enigma, there were only 5 or 6 different rotors in existence, and they
89were applied twice to each character; the cipher key was the order in
90which they were placed in the machine. The Python \module{rotor}
91module uses the supplied key to initialize a random number generator;
92the rotor permutations and their initial positions are then randomly
93generated. The original device only enciphered the letters of the
94alphabet, while this module can handle any 8-bit binary data; it also
95produces binary output. This module can also operate with an
Guido van Rossum16d6e711994-08-08 12:30:22 +000096arbitrary number of rotors.
97
98The original Enigma cipher was broken in 1944. % XXX: Is this right?
99The version implemented here is probably a good deal more difficult to crack
100(especially if you use many rotors), but it won't be impossible for
Thomas Woutersf8316632000-07-16 19:01:10 +0000101a truly skillful and determined attacker to break the cipher. So if you want
Guido van Rossum16d6e711994-08-08 12:30:22 +0000102to keep the NSA out of your files, this rotor cipher may well be unsafe, but
103for discouraging casual snooping through your files, it will probably be
Fred Drake75fc0451998-02-16 21:36:57 +0000104just fine, and may be somewhat safer than using the \UNIX{} \program{crypt}
Guido van Rossum16d6e711994-08-08 12:30:22 +0000105command.
Fred Drake75fc0451998-02-16 21:36:57 +0000106\index{NSA}
Fred Drakefc576191998-04-04 07:15:02 +0000107\index{National Security Agency}