bgneal@51: .. m209 documentation master file, created by bgneal@51: sphinx-quickstart on Thu Jul 4 18:12:07 2013. bgneal@51: You can adapt this file completely to your liking, but it should at least bgneal@51: contain the root `toctree` directive. bgneal@51: bgneal@51: Welcome to m209's documentation! bgneal@51: ================================ bgneal@51: bgneal@52: :Author: Brian Neal bgneal@52: :Version: |release| bgneal@52: :Date: |today| bgneal@52: :Home Page: https://bitbucket.org/bgneal/m209/ bgneal@52: :License: MIT License (see LICENSE.txt) bgneal@52: :Documentation: http://m209.readthedocs.org/ bgneal@52: :Support: https://bitbucket.org/bgneal/m209/issues bgneal@52: bgneal@52: Introduction bgneal@52: ------------ bgneal@52: bgneal@52: ``m209`` is a complete `M-209`_ simulation library and command-line application bgneal@52: written in Python 3. ``m209`` is historically accurate, meaning that it can bgneal@52: exchange messages with an actual M-209 cipher machine. bgneal@52: bgneal@52: It is hoped that this library will be useful to M-209 enthusiasts, historians, bgneal@52: and students interested in cryptography. bgneal@52: bgneal@52: ``m209`` strives to be Pythonic, easy to use, and comes with both unit tests bgneal@52: and documentation. ``m209`` is a library for building applications for bgneal@52: encrypting and decrypting M-209 messages. ``m209`` also ships with a simple bgneal@52: command-line application that can encrypt & decrypt messages for scripting and bgneal@52: experimentation. bgneal@52: bgneal@54: Command-line Tutorial bgneal@54: --------------------- bgneal@52: bgneal@54: In order for two parties to exchange M-209 messages, each must set up their bgneal@54: device in exactly the same manner. This was accomplished by publishing key bgneal@54: lists in code books which were distributed to end users. A code book instructed bgneal@54: users on what key list to use on any given day in a given month. Each key list bgneal@54: detailed the numerous wheel pin and lug settings that needed to be made for bgneal@54: a given day. Because there are so many settings, the ``m209`` utility allows bgneal@54: users to store key lists in a key file for convenience. So let us first create bgneal@54: a key file that hold 30 key lists:: bgneal@54: bgneal@54: $ m209 keygen -n 30 bgneal@54: bgneal@54: This command randomly creates 30 key lists and stores them in a file called bgneal@54: ``m209keys.cfg`` by default. We did not specify a starting key list indicator, so bgneal@54: 30 random ones were chosen. The first 13 lines of our new key file are bgneal@54: displayed below:: bgneal@54: bgneal@54: $ head -n 13 m209keys.cfg bgneal@54: [AB] bgneal@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: wheel1 = BDFGIKRSTUWX bgneal@54: wheel2 = BCEJKLORSUX bgneal@54: wheel3 = CFHJKLMQSTU bgneal@54: wheel4 = ABCDHIJMOPRTU bgneal@54: wheel5 = BCEFINPS bgneal@54: wheel6 = ACDEHJN bgneal@54: check = GZWUU SFYQN NFAKK FXSEN FAFMF B bgneal@54: bgneal@54: [AK] bgneal@54: lugs = 0-4*2 0-5*9 0-6 1-0*3 1-2 1-5 1-6*2 3-0*8 bgneal@54: wheel1 = ABDEFHIJMQSUXZ bgneal@54: bgneal@54: .. NOTE:: bgneal@54: If you are following along at home, you'll probably get different bgneal@54: output than what is shown here. This is because the key lists are generated bgneal@54: at random, and it is very unlikely that your key list matches mine! bgneal@54: bgneal@54: Here we can see that the first key list in our file has the indicator ``AB`` bgneal@54: (shown in square brackets), and we can see the settings for the lugs and six bgneal@54: wheels. The notation is explained later. Also included is a so-called check bgneal@54: string. Because there are so many settings, it is quite error-prone to set up bgneal@54: an M-209. This check string allows the operator to verify their work. After bgneal@54: configuring the M-209 with the given settings, the operator can set the six key bgneal@54: wheels to ``AAAAAA``, then encipher the letter ``A`` 26 times. If the message bgneal@54: that appears on the paper tape matches the check string, the operator knows the bgneal@54: machine is set up correctly for the day. bgneal@54: bgneal@54: After the key list ``AB``, the key list ``AK`` starts, and so on for all 30 key bgneal@54: lists. bgneal@54: bgneal@54: Now that we have created a key file, we can encrypt our first message. The bgneal@54: ``m209`` utility has many options to let you have fine control over the various bgneal@54: encryption parameters. These are explained in detail later. If you omit these bgneal@54: parameters they are simply chosen at random. Here is the simplest example of bgneal@54: encryping a message:: bgneal@54: bgneal@54: $ m209 encrypt -t "THE PIZZA HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP" bgneal@54: IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB bgneal@54: bgneal@54: What just happened here? Since we did not specify a key file, the default bgneal@54: ``m209keys.cfg`` was used. Since we did not specify a key list indicator, one bgneal@54: was chosen randomly from the key file. Other encryption parameters, explained bgneal@54: later, were also randomly chosen. Next, the message given on the command-line bgneal@54: was encrypted using the standard US Army procedure described in the references. bgneal@54: This resulted in the encrypted message, which is displayed in 5-letter groups. bgneal@54: Notice that the first and last 2 groups are identical. These are special bgneal@54: indicators that tell the receiver how to decrypt the message. In particular bgneal@54: note that the last 2 letters in the second and last groups are ``MB``. This is bgneal@54: the key list indicator and tells the receiver what key list was used. The bgneal@54: remaining groups in the middle make up the encrypted message. bgneal@54: bgneal@54: Astute M-209 enthusiasts will note that our message included spaces. Actual bgneal@54: M-209 units only allow the input of the letters ``A`` through ``Z``. Whenever bgneal@54: a space was needed, the operator inserted the letter ``Z``. The ``m209`` bgneal@54: utility automatically performs this substitution for convenience. bgneal@54: bgneal@54: Let's suppose our message was then sent to our recipient, either by courier, bgneal@54: Morse code over radio, or in the modern age, email or even Twitter. In order bgneal@54: for our receiver to decrypt our message they must also have the identical key bgneal@54: list named ``MB``. We will assume for now that our key file, ``m209keys.cfg`` bgneal@54: was sent to our receiver earlier in some secure manner. The receiver then bgneal@54: issues this command:: bgneal@54: bgneal@54: $ m209 decrypt -t "IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB" bgneal@54: THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP bgneal@54: bgneal@54: Here again, since no key file was explicitly specified, the file bgneal@54: ``m209keys.cfg`` was used. The file was searched for the key list ``MB``. Then bgneal@54: the standard Army procedure was followed, making use of the indicator groups to bgneal@54: decrypt the message, which is displayed as output. bgneal@54: bgneal@54: But wait, what happened to our Pizza? Why are the ``Z``'s missing? This is how bgneal@54: an actual M-209 operates. Recall that an operator must substitute a letter bgneal@54: ``Z`` whenever a space is needed. The M-209 helpfully replaces the letter ``Z`` bgneal@54: in the decrypt output with a space as an aid to the operator. As a side effect, bgneal@54: legitimate uses of the letter ``Z`` are blanked out. But usually it is clear bgneal@54: from context what has happened, and the operator has to put them back into the bgneal@54: message before passing it up the chain of command. bgneal@54: bgneal@54: It may also happen that the original message did not fit perfectly into an even bgneal@54: number of 5-letter groups. In that case the encrypted message would be padded bgneal@54: with ``X`` characters according to procedure. Upon decrypt, these ``X`` bgneal@54: characters would appear as garbage characters on the end of the message. The bgneal@54: receiving operator would simply ignore these letters. Note that our message did bgneal@54: not exhibit this behavior. bgneal@54: bgneal@54: This is all you need to know to start creating your own M-209 messages! For bgneal@54: more details, consult the command-line ``m209`` documentation. bgneal@54: bgneal@54: Library Tutorial bgneal@54: ---------------- bgneal@52: bgneal@55: Here is one way to perform the encrypt and decrypt operations from the bgneal@55: command-line tutorial, above. In order to produce the same output, we explicity bgneal@55: specify the encryption parameters: the key list, the external message bgneal@55: indicator, and the system indicator. These parameters are explained in the bgneal@55: reference documentation. bgneal@55: bgneal@55: .. literalinclude:: ../examples/encrypt.py bgneal@55: bgneal@55: This program outputs:: bgneal@55: bgneal@55: IIPDU FHLMB LASGD KTLDO OSRMZ PWGEB HYMCB IKSPT IUEPF FUHEO NQTWI VTDPC GSPQX IIPDU FHLMB bgneal@55: bgneal@55: A decrypt is just a bit more complicated. After constructing a ``StdProcedure`` bgneal@55: object, you hand it the encrypted message to analyze. The procedure object bgneal@55: examines the groups in the message and extracts all the indicators. These are bgneal@55: returned as a ``DecryptParams`` named tuple which indicates, amongst other bgneal@55: things, what key list is required. It is then up to you to obtain this key list bgneal@55: somehow. Here we use the ``read_key_list()`` function to do so. After bgneal@55: installing the key list into the procedure object, you can finally call bgneal@55: ``decrypt()``: bgneal@55: bgneal@55: .. literalinclude:: ../examples/decrypt.py bgneal@55: bgneal@55: This program prints:: bgneal@55: bgneal@55: THE PI A HAS ARRIVED STOP NO SIGN OF ENEMY FORCES STOP bgneal@55: bgneal@55: bgneal@52: Requirements bgneal@52: ------------ bgneal@52: bgneal@52: ``m209`` is written in Python_, specifically Python 3.3. It has no other bgneal@52: requirements or dependencies. bgneal@52: bgneal@55: bgneal@52: Installation bgneal@52: ------------ bgneal@52: bgneal@52: ``m209`` is available on the `Python Package Index`_ (PyPI). You can install it bgneal@52: using pip_:: bgneal@52: bgneal@52: $ pip install m209 # install bgneal@52: $ pip install --upgrade m209 # upgrade bgneal@52: bgneal@55: You may also download a tarball or .zip file of the latest code by visiting the bgneal@55: Downloads tab on the `m209 Bitbucket page`_. Alternatively if you use bgneal@52: Mercurial_, you can clone the repository with the following command:: bgneal@52: bgneal@52: $ hg clone https://bitbucket.org/bgneal/m209 bgneal@52: bgneal@52: If you did not use pip, you can install with this command:: bgneal@52: bgneal@52: $ python setup.py install bgneal@52: bgneal@52: bgneal@52: Support & Source bgneal@52: ---------------- bgneal@52: bgneal@52: All support takes place at the `m209 Bitbucket page`_. Please enter any bgneal@52: feature requests or bugs into the `issue tracker`_. bgneal@52: bgneal@52: Next Steps bgneal@52: ---------- bgneal@52: bgneal@51: Contents: bgneal@51: bgneal@51: .. toctree:: bgneal@51: :maxdepth: 2 bgneal@51: bgneal@51: bgneal@51: bgneal@51: Indices and tables bgneal@51: ================== bgneal@51: bgneal@51: * :ref:`genindex` bgneal@51: * :ref:`modindex` bgneal@51: * :ref:`search` bgneal@51: bgneal@52: bgneal@52: .. _M-209: http://en.wikipedia.org/wiki/M-209 bgneal@52: .. _Python: http://www.python.org bgneal@52: .. _Python Package Index: http://pypi.python.org/pypi/m209/ bgneal@52: .. _m209 Bitbucket page: https://bitbucket.org/bgneal/m209 bgneal@52: .. _pip: http://www.pip-installer.org bgneal@52: .. _Mercurial: http://mercurial.selenic.com/ bgneal@52: .. _issue tracker: https://bitbucket.org/bgneal/m209/issues