bgneal@56: Tutorials bgneal@56: ========= bgneal@56: bgneal@56: Command-line Tutorial bgneal@56: --------------------- bgneal@56: bgneal@56: In order for two parties to exchange M-209 messages, each must set up their bgneal@56: device in exactly the same manner. This was accomplished by publishing key bgneal@56: lists in code books which were distributed to end users. A code book instructed bgneal@56: users on what key list to use on any given day in a given month. Each key list bgneal@56: detailed the numerous wheel pin and lug settings that needed to be made for bgneal@56: a given day. Because there are so many settings, the ``m209`` utility allows bgneal@56: users to store key lists in a key file for convenience. So let us first create bgneal@56: a key file that hold 30 key lists:: bgneal@56: bgneal@56: $ m209 keygen -n 30 bgneal@56: bgneal@56: This command randomly creates 30 key lists and stores them in a file called bgneal@56: ``m209keys.cfg`` by default. We did not specify a starting key list indicator, so bgneal@56: 30 random ones were chosen. The first 13 lines of our new key file are bgneal@56: displayed below:: bgneal@56: bgneal@56: $ head -n 13 m209keys.cfg bgneal@56: [AB] bgneal@56: lugs = 0-4*4 0-5*6 1-0*10 2-0*2 3-0 3-5*2 3-6 4-5 bgneal@56: wheel1 = BDFGIKRSTUWX bgneal@56: wheel2 = BCEJKLORSUX bgneal@56: wheel3 = CFHJKLMQSTU bgneal@56: wheel4 = ABCDHIJMOPRTU bgneal@56: wheel5 = BCEFINPS bgneal@56: wheel6 = ACDEHJN bgneal@56: check = GZWUU SFYQN NFAKK FXSEN FAFMF B bgneal@56: bgneal@56: [AK] bgneal@56: lugs = 0-4*2 0-5*9 0-6 1-0*3 1-2 1-5 1-6*2 3-0*8 bgneal@56: wheel1 = ABDEFHIJMQSUXZ bgneal@56: bgneal@56: .. NOTE:: bgneal@56: If you are following along at home, you'll probably get different bgneal@56: output than what is shown here. This is because the key lists are generated bgneal@56: at random, and it is very unlikely that your key list matches mine! bgneal@56: bgneal@56: Here we can see that the first key list in our file has the indicator ``AB`` bgneal@56: (shown in square brackets), and we can see the settings for the lugs and six bgneal@56: wheels. The notation is explained later. Also included is a so-called check bgneal@56: string. Because there are so many settings, it is quite error-prone to set up bgneal@56: an M-209. This check string allows the operator to verify their work. After bgneal@56: configuring the M-209 with the given settings, the operator can set the six key bgneal@56: wheels to ``AAAAAA``, then encipher the letter ``A`` 26 times. If the message bgneal@56: that appears on the paper tape matches the check string, the operator knows the bgneal@56: machine is set up correctly for the day. bgneal@56: bgneal@56: After the key list ``AB``, the key list ``AK`` starts, and so on for all 30 key bgneal@56: lists. bgneal@56: bgneal@56: Now that we have created a key file, we can encrypt our first message. The bgneal@56: ``m209`` utility has many options to let you have fine control over the various bgneal@56: encryption parameters. These are explained in detail later. If you omit these bgneal@56: parameters they are simply chosen at random. Here is the simplest example of bgneal@56: encryping a message:: bgneal@56: bgneal@56: $ m209 encrypt -t "THE PIZZA HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP" bgneal@56: IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB bgneal@56: bgneal@56: What just happened here? Since we did not specify a key file, the default bgneal@56: ``m209keys.cfg`` was used. Since we did not specify a key list indicator, one bgneal@56: was chosen randomly from the key file. Other encryption parameters, explained bgneal@56: later, were also randomly chosen. Next, the message given on the command-line bgneal@56: was encrypted using the standard US Army procedure described in the references. bgneal@56: This resulted in the encrypted message, which is displayed in 5-letter groups. bgneal@56: Notice that the first and last 2 groups are identical. These are special bgneal@56: indicators that tell the receiver how to decrypt the message. In particular bgneal@56: note that the last 2 letters in the second and last groups are ``MB``. This is bgneal@56: the key list indicator and tells the receiver what key list was used. The bgneal@56: remaining groups in the middle make up the encrypted message. bgneal@56: bgneal@56: Astute M-209 enthusiasts will note that our message included spaces. Actual bgneal@56: M-209 units only allow the input of the letters ``A`` through ``Z``. Whenever bgneal@56: a space was needed, the operator inserted the letter ``Z``. The ``m209`` bgneal@56: utility automatically performs this substitution for convenience. bgneal@56: bgneal@56: Let's suppose our message was then sent to our recipient, either by courier, bgneal@56: Morse code over radio, or in the modern age, email or even Twitter. In order bgneal@56: for our receiver to decrypt our message they must also have the identical key bgneal@56: list named ``MB``. We will assume for now that our key file, ``m209keys.cfg`` bgneal@56: was sent to our receiver earlier in some secure manner. The receiver then bgneal@56: issues this command:: bgneal@56: bgneal@56: $ m209 decrypt -t "IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB" bgneal@56: THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP bgneal@56: bgneal@56: Here again, since no key file was explicitly specified, the file bgneal@56: ``m209keys.cfg`` was used. The file was searched for the key list ``MB``. Then bgneal@56: the standard Army procedure was followed, making use of the indicator groups to bgneal@56: decrypt the message, which is displayed as output. bgneal@56: bgneal@56: But wait, what happened to our Pizza? Why are the ``Z``'s missing? This is how bgneal@56: an actual M-209 operates. Recall that an operator must substitute a letter bgneal@56: ``Z`` whenever a space is needed. The M-209 helpfully replaces the letter ``Z`` bgneal@56: in the decrypt output with a space as an aid to the operator. As a side effect, bgneal@56: legitimate uses of the letter ``Z`` are blanked out. But usually it is clear bgneal@56: from context what has happened, and the operator has to put them back into the bgneal@56: message before passing it up the chain of command. bgneal@56: bgneal@56: It may also happen that the original message did not fit perfectly into an even bgneal@56: number of 5-letter groups. In that case the encrypted message would be padded bgneal@56: with ``X`` characters according to procedure. Upon decrypt, these ``X`` bgneal@56: characters would appear as garbage characters on the end of the message. The bgneal@56: receiving operator would simply ignore these letters. Note that our message did bgneal@56: not exhibit this behavior. bgneal@56: bgneal@56: This is all you need to know to start creating your own M-209 messages! For bgneal@56: more details, consult the command-line ``m209`` documentation. bgneal@56: bgneal@56: Library Tutorial bgneal@56: ---------------- bgneal@56: bgneal@56: Here is one way to perform the encrypt and decrypt operations from the bgneal@56: command-line tutorial, above. In order to produce the same output, we explicity bgneal@56: specify the encryption parameters: the key list, the external message bgneal@56: indicator, and the system indicator. These parameters are explained in the bgneal@56: reference documentation. bgneal@56: bgneal@56: .. literalinclude:: ../examples/encrypt.py bgneal@56: bgneal@56: This program outputs:: bgneal@56: bgneal@56: IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB bgneal@56: bgneal@56: A decrypt is just a bit more complicated. After constructing a ``StdProcedure`` bgneal@56: object, you hand it the encrypted message to analyze. The procedure object bgneal@56: examines the groups in the message and extracts all the indicators. These are bgneal@56: returned as a ``DecryptParams`` named tuple which indicates, amongst other bgneal@56: things, what key list is required. It is then up to you to obtain this key list bgneal@56: somehow. Here we use the ``read_key_list()`` function to do so. After bgneal@56: installing the key list into the procedure object, you can finally call bgneal@56: ``decrypt()``: bgneal@56: bgneal@56: .. literalinclude:: ../examples/decrypt.py bgneal@56: bgneal@56: This program prints:: bgneal@56: bgneal@56: THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP