bgneal@51
|
1 .. m209 documentation master file, created by
|
bgneal@51
|
2 sphinx-quickstart on Thu Jul 4 18:12:07 2013.
|
bgneal@51
|
3 You can adapt this file completely to your liking, but it should at least
|
bgneal@51
|
4 contain the root `toctree` directive.
|
bgneal@51
|
5
|
bgneal@51
|
6 Welcome to m209's documentation!
|
bgneal@51
|
7 ================================
|
bgneal@51
|
8
|
bgneal@52
|
9 :Author: Brian Neal <bgneal@gmail.com>
|
bgneal@52
|
10 :Version: |release|
|
bgneal@52
|
11 :Date: |today|
|
bgneal@52
|
12 :Home Page: https://bitbucket.org/bgneal/m209/
|
bgneal@52
|
13 :License: MIT License (see LICENSE.txt)
|
bgneal@52
|
14 :Documentation: http://m209.readthedocs.org/
|
bgneal@52
|
15 :Support: https://bitbucket.org/bgneal/m209/issues
|
bgneal@52
|
16
|
bgneal@52
|
17 Introduction
|
bgneal@52
|
18 ------------
|
bgneal@52
|
19
|
bgneal@52
|
20 ``m209`` is a complete `M-209`_ simulation library and command-line application
|
bgneal@52
|
21 written in Python 3. ``m209`` is historically accurate, meaning that it can
|
bgneal@52
|
22 exchange messages with an actual M-209 cipher machine.
|
bgneal@52
|
23
|
bgneal@52
|
24 It is hoped that this library will be useful to M-209 enthusiasts, historians,
|
bgneal@52
|
25 and students interested in cryptography.
|
bgneal@52
|
26
|
bgneal@52
|
27 ``m209`` strives to be Pythonic, easy to use, and comes with both unit tests
|
bgneal@52
|
28 and documentation. ``m209`` is a library for building applications for
|
bgneal@52
|
29 encrypting and decrypting M-209 messages. ``m209`` also ships with a simple
|
bgneal@52
|
30 command-line application that can encrypt & decrypt messages for scripting and
|
bgneal@52
|
31 experimentation.
|
bgneal@52
|
32
|
bgneal@54
|
33 Command-line Tutorial
|
bgneal@54
|
34 ---------------------
|
bgneal@52
|
35
|
bgneal@54
|
36 In order for two parties to exchange M-209 messages, each must set up their
|
bgneal@54
|
37 device in exactly the same manner. This was accomplished by publishing key
|
bgneal@54
|
38 lists in code books which were distributed to end users. A code book instructed
|
bgneal@54
|
39 users on what key list to use on any given day in a given month. Each key list
|
bgneal@54
|
40 detailed the numerous wheel pin and lug settings that needed to be made for
|
bgneal@54
|
41 a given day. Because there are so many settings, the ``m209`` utility allows
|
bgneal@54
|
42 users to store key lists in a key file for convenience. So let us first create
|
bgneal@54
|
43 a key file that hold 30 key lists::
|
bgneal@54
|
44
|
bgneal@54
|
45 $ m209 keygen -n 30
|
bgneal@54
|
46
|
bgneal@54
|
47 This command randomly creates 30 key lists and stores them in a file called
|
bgneal@54
|
48 ``m209keys.cfg`` by default. We did not specify a starting key list indicator, so
|
bgneal@54
|
49 30 random ones were chosen. The first 13 lines of our new key file are
|
bgneal@54
|
50 displayed below::
|
bgneal@54
|
51
|
bgneal@54
|
52 $ head -n 13 m209keys.cfg
|
bgneal@54
|
53 [AB]
|
bgneal@54
|
54 lugs = 0-4*4 0-5*6 1-0*10 2-0*2 3-0 3-5*2 3-6 4-5
|
bgneal@54
|
55 wheel1 = BDFGIKRSTUWX
|
bgneal@54
|
56 wheel2 = BCEJKLORSUX
|
bgneal@54
|
57 wheel3 = CFHJKLMQSTU
|
bgneal@54
|
58 wheel4 = ABCDHIJMOPRTU
|
bgneal@54
|
59 wheel5 = BCEFINPS
|
bgneal@54
|
60 wheel6 = ACDEHJN
|
bgneal@54
|
61 check = GZWUU SFYQN NFAKK FXSEN FAFMF B
|
bgneal@54
|
62
|
bgneal@54
|
63 [AK]
|
bgneal@54
|
64 lugs = 0-4*2 0-5*9 0-6 1-0*3 1-2 1-5 1-6*2 3-0*8
|
bgneal@54
|
65 wheel1 = ABDEFHIJMQSUXZ
|
bgneal@54
|
66
|
bgneal@54
|
67 .. NOTE::
|
bgneal@54
|
68 If you are following along at home, you'll probably get different
|
bgneal@54
|
69 output than what is shown here. This is because the key lists are generated
|
bgneal@54
|
70 at random, and it is very unlikely that your key list matches mine!
|
bgneal@54
|
71
|
bgneal@54
|
72 Here we can see that the first key list in our file has the indicator ``AB``
|
bgneal@54
|
73 (shown in square brackets), and we can see the settings for the lugs and six
|
bgneal@54
|
74 wheels. The notation is explained later. Also included is a so-called check
|
bgneal@54
|
75 string. Because there are so many settings, it is quite error-prone to set up
|
bgneal@54
|
76 an M-209. This check string allows the operator to verify their work. After
|
bgneal@54
|
77 configuring the M-209 with the given settings, the operator can set the six key
|
bgneal@54
|
78 wheels to ``AAAAAA``, then encipher the letter ``A`` 26 times. If the message
|
bgneal@54
|
79 that appears on the paper tape matches the check string, the operator knows the
|
bgneal@54
|
80 machine is set up correctly for the day.
|
bgneal@54
|
81
|
bgneal@54
|
82 After the key list ``AB``, the key list ``AK`` starts, and so on for all 30 key
|
bgneal@54
|
83 lists.
|
bgneal@54
|
84
|
bgneal@54
|
85 Now that we have created a key file, we can encrypt our first message. The
|
bgneal@54
|
86 ``m209`` utility has many options to let you have fine control over the various
|
bgneal@54
|
87 encryption parameters. These are explained in detail later. If you omit these
|
bgneal@54
|
88 parameters they are simply chosen at random. Here is the simplest example of
|
bgneal@54
|
89 encryping a message::
|
bgneal@54
|
90
|
bgneal@54
|
91 $ m209 encrypt -t "THE PIZZA HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP"
|
bgneal@54
|
92 IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB
|
bgneal@54
|
93
|
bgneal@54
|
94 What just happened here? Since we did not specify a key file, the default
|
bgneal@54
|
95 ``m209keys.cfg`` was used. Since we did not specify a key list indicator, one
|
bgneal@54
|
96 was chosen randomly from the key file. Other encryption parameters, explained
|
bgneal@54
|
97 later, were also randomly chosen. Next, the message given on the command-line
|
bgneal@54
|
98 was encrypted using the standard US Army procedure described in the references.
|
bgneal@54
|
99 This resulted in the encrypted message, which is displayed in 5-letter groups.
|
bgneal@54
|
100 Notice that the first and last 2 groups are identical. These are special
|
bgneal@54
|
101 indicators that tell the receiver how to decrypt the message. In particular
|
bgneal@54
|
102 note that the last 2 letters in the second and last groups are ``MB``. This is
|
bgneal@54
|
103 the key list indicator and tells the receiver what key list was used. The
|
bgneal@54
|
104 remaining groups in the middle make up the encrypted message.
|
bgneal@54
|
105
|
bgneal@54
|
106 Astute M-209 enthusiasts will note that our message included spaces. Actual
|
bgneal@54
|
107 M-209 units only allow the input of the letters ``A`` through ``Z``. Whenever
|
bgneal@54
|
108 a space was needed, the operator inserted the letter ``Z``. The ``m209``
|
bgneal@54
|
109 utility automatically performs this substitution for convenience.
|
bgneal@54
|
110
|
bgneal@54
|
111 Let's suppose our message was then sent to our recipient, either by courier,
|
bgneal@54
|
112 Morse code over radio, or in the modern age, email or even Twitter. In order
|
bgneal@54
|
113 for our receiver to decrypt our message they must also have the identical key
|
bgneal@54
|
114 list named ``MB``. We will assume for now that our key file, ``m209keys.cfg``
|
bgneal@54
|
115 was sent to our receiver earlier in some secure manner. The receiver then
|
bgneal@54
|
116 issues this command::
|
bgneal@54
|
117
|
bgneal@54
|
118 $ m209 decrypt -t "IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB"
|
bgneal@54
|
119 THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP
|
bgneal@54
|
120
|
bgneal@54
|
121 Here again, since no key file was explicitly specified, the file
|
bgneal@54
|
122 ``m209keys.cfg`` was used. The file was searched for the key list ``MB``. Then
|
bgneal@54
|
123 the standard Army procedure was followed, making use of the indicator groups to
|
bgneal@54
|
124 decrypt the message, which is displayed as output.
|
bgneal@54
|
125
|
bgneal@54
|
126 But wait, what happened to our Pizza? Why are the ``Z``'s missing? This is how
|
bgneal@54
|
127 an actual M-209 operates. Recall that an operator must substitute a letter
|
bgneal@54
|
128 ``Z`` whenever a space is needed. The M-209 helpfully replaces the letter ``Z``
|
bgneal@54
|
129 in the decrypt output with a space as an aid to the operator. As a side effect,
|
bgneal@54
|
130 legitimate uses of the letter ``Z`` are blanked out. But usually it is clear
|
bgneal@54
|
131 from context what has happened, and the operator has to put them back into the
|
bgneal@54
|
132 message before passing it up the chain of command.
|
bgneal@54
|
133
|
bgneal@54
|
134 It may also happen that the original message did not fit perfectly into an even
|
bgneal@54
|
135 number of 5-letter groups. In that case the encrypted message would be padded
|
bgneal@54
|
136 with ``X`` characters according to procedure. Upon decrypt, these ``X``
|
bgneal@54
|
137 characters would appear as garbage characters on the end of the message. The
|
bgneal@54
|
138 receiving operator would simply ignore these letters. Note that our message did
|
bgneal@54
|
139 not exhibit this behavior.
|
bgneal@54
|
140
|
bgneal@54
|
141 This is all you need to know to start creating your own M-209 messages! For
|
bgneal@54
|
142 more details, consult the command-line ``m209`` documentation.
|
bgneal@54
|
143
|
bgneal@54
|
144 Library Tutorial
|
bgneal@54
|
145 ----------------
|
bgneal@52
|
146
|
bgneal@55
|
147 Here is one way to perform the encrypt and decrypt operations from the
|
bgneal@55
|
148 command-line tutorial, above. In order to produce the same output, we explicity
|
bgneal@55
|
149 specify the encryption parameters: the key list, the external message
|
bgneal@55
|
150 indicator, and the system indicator. These parameters are explained in the
|
bgneal@55
|
151 reference documentation.
|
bgneal@55
|
152
|
bgneal@55
|
153 .. literalinclude:: ../examples/encrypt.py
|
bgneal@55
|
154
|
bgneal@55
|
155 This program outputs::
|
bgneal@55
|
156
|
bgneal@55
|
157 IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB
|
bgneal@55
|
158
|
bgneal@55
|
159 A decrypt is just a bit more complicated. After constructing a ``StdProcedure``
|
bgneal@55
|
160 object, you hand it the encrypted message to analyze. The procedure object
|
bgneal@55
|
161 examines the groups in the message and extracts all the indicators. These are
|
bgneal@55
|
162 returned as a ``DecryptParams`` named tuple which indicates, amongst other
|
bgneal@55
|
163 things, what key list is required. It is then up to you to obtain this key list
|
bgneal@55
|
164 somehow. Here we use the ``read_key_list()`` function to do so. After
|
bgneal@55
|
165 installing the key list into the procedure object, you can finally call
|
bgneal@55
|
166 ``decrypt()``:
|
bgneal@55
|
167
|
bgneal@55
|
168 .. literalinclude:: ../examples/decrypt.py
|
bgneal@55
|
169
|
bgneal@55
|
170 This program prints::
|
bgneal@55
|
171
|
bgneal@55
|
172 THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP
|
bgneal@55
|
173
|
bgneal@55
|
174
|
bgneal@52
|
175 Requirements
|
bgneal@52
|
176 ------------
|
bgneal@52
|
177
|
bgneal@52
|
178 ``m209`` is written in Python_, specifically Python 3.3. It has no other
|
bgneal@52
|
179 requirements or dependencies.
|
bgneal@52
|
180
|
bgneal@55
|
181
|
bgneal@52
|
182 Installation
|
bgneal@52
|
183 ------------
|
bgneal@52
|
184
|
bgneal@52
|
185 ``m209`` is available on the `Python Package Index`_ (PyPI). You can install it
|
bgneal@52
|
186 using pip_::
|
bgneal@52
|
187
|
bgneal@52
|
188 $ pip install m209 # install
|
bgneal@52
|
189 $ pip install --upgrade m209 # upgrade
|
bgneal@52
|
190
|
bgneal@55
|
191 You may also download a tarball or .zip file of the latest code by visiting the
|
bgneal@55
|
192 Downloads tab on the `m209 Bitbucket page`_. Alternatively if you use
|
bgneal@52
|
193 Mercurial_, you can clone the repository with the following command::
|
bgneal@52
|
194
|
bgneal@52
|
195 $ hg clone https://bitbucket.org/bgneal/m209
|
bgneal@52
|
196
|
bgneal@52
|
197 If you did not use pip, you can install with this command::
|
bgneal@52
|
198
|
bgneal@52
|
199 $ python setup.py install
|
bgneal@52
|
200
|
bgneal@52
|
201
|
bgneal@52
|
202 Support & Source
|
bgneal@52
|
203 ----------------
|
bgneal@52
|
204
|
bgneal@52
|
205 All support takes place at the `m209 Bitbucket page`_. Please enter any
|
bgneal@52
|
206 feature requests or bugs into the `issue tracker`_.
|
bgneal@52
|
207
|
bgneal@52
|
208 Next Steps
|
bgneal@52
|
209 ----------
|
bgneal@52
|
210
|
bgneal@51
|
211 Contents:
|
bgneal@51
|
212
|
bgneal@51
|
213 .. toctree::
|
bgneal@51
|
214 :maxdepth: 2
|
bgneal@51
|
215
|
bgneal@51
|
216
|
bgneal@51
|
217
|
bgneal@51
|
218 Indices and tables
|
bgneal@51
|
219 ==================
|
bgneal@51
|
220
|
bgneal@51
|
221 * :ref:`genindex`
|
bgneal@51
|
222 * :ref:`modindex`
|
bgneal@51
|
223 * :ref:`search`
|
bgneal@51
|
224
|
bgneal@52
|
225
|
bgneal@52
|
226 .. _M-209: http://en.wikipedia.org/wiki/M-209
|
bgneal@52
|
227 .. _Python: http://www.python.org
|
bgneal@52
|
228 .. _Python Package Index: http://pypi.python.org/pypi/m209/
|
bgneal@52
|
229 .. _m209 Bitbucket page: https://bitbucket.org/bgneal/m209
|
bgneal@52
|
230 .. _pip: http://www.pip-installer.org
|
bgneal@52
|
231 .. _Mercurial: http://mercurial.selenic.com/
|
bgneal@52
|
232 .. _issue tracker: https://bitbucket.org/bgneal/m209/issues
|