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@71: a key file that holds 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@71: at random, and it is very unlikely that your key list will match 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@71: wheels. This notation is explained later (see :ref:`key-list-file-format-label`). bgneal@71: Also included is a so-called check string. Because there are so many settings, bgneal@71: it is quite error-prone to set up an M-209. This check string allows the bgneal@71: operator to verify their work. After configuring the M-209 with the given bgneal@71: settings, the operator can set the six key wheels to ``AAAAAA``, then encipher bgneal@71: the letter ``A`` 26 times. If the message that appears on the paper tape bgneal@71: matches the check string, the operator knows the machine is set up correctly bgneal@71: 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@71: encrypting 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@71: was encrypted using the standard US Army procedure described in bgneal@71: :ref:`references-label` (see [5] and [7]). This resulted in the encrypted bgneal@71: message, which is displayed in 5-letter groups. Notice that the first and last bgneal@71: 2 groups are identical. These are special indicators that tell the receiver how bgneal@71: to decrypt the message. In particular note that the last 2 letters in the bgneal@71: second and last groups are ``MB``. This is the key list indicator and tells bgneal@71: the receiver what key list was used. The remaining groups in the middle make bgneal@71: 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@71: legitimate uses of the letter ``Z`` are blanked out. Usually it is clear from bgneal@71: context what has happened, and the operator has to put the ``Z``'s back into bgneal@71: the 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@71: more details, consult the :doc:`commandline`. 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@71: command-line tutorial, above. In order to produce the same output, we explicitly bgneal@56: specify the encryption parameters: the key list, the external message bgneal@71: indicator, and the system indicator. These parameters are explained in bgneal@71: :ref:`references-label` [5] & [7]. 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@71: A decrypt is just a bit more complicated. After constructing bgneal@71: a :class:`~m209.procedure.StdProcedure` object, you hand it the encrypted bgneal@71: message to analyze. The procedure object examines the groups in the message and bgneal@71: extracts all the indicators. These are returned as a ``DecryptParams`` named bgneal@71: tuple which indicates, amongst other things, what key list is required. It is bgneal@71: then up to you to obtain this key list somehow. Here we use the bgneal@71: :func:`~m209.keylist.config.read_key_list` function to do so. After installing bgneal@71: the key list into the procedure object with :meth:`~.StdProcedure.set_key_list`, bgneal@71: you can finally call :meth:`~.StdProcedure.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