annotate README.txt @ 31:cdfb52a36b38 tip

Added tag v0.1.0 for changeset a58f91ead4ba
author Brian Neal <bgneal@gmail.com>
date Wed, 19 Feb 2014 18:59:39 -0600
parents a58f91ead4ba
children
rev   line source
bgneal@24 1 ======
bgneal@24 2 Purple
bgneal@24 3 ======
bgneal@24 4
bgneal@24 5 A historically accurate PURPLE simulator written in Python 3
bgneal@24 6 ------------------------------------------------------------
bgneal@24 7
bgneal@24 8 :Author: Brian Neal <bgneal@gmail.com>
bgneal@24 9 :Version: 0.1
bgneal@24 10 :Date: February 17, 2013
bgneal@24 11 :Home Page: https://bitbucket.org/bgneal/purple/
bgneal@24 12 :License: MIT License (see LICENSE.txt)
bgneal@24 13 :Documentation: This file
bgneal@24 14 :Support: https://bitbucket.org/bgneal/purple/issues
bgneal@24 15
bgneal@26 16 ``Purple`` is a Python library and command-line utility for simulating the
bgneal@26 17 `PURPLE Machine`_, a cipher machine used by the Japanese Foreign Office before
bgneal@26 18 and during the Second World War. PURPLE was the code name given to the machine
bgneal@26 19 by U.S. cryptanalysts. The Japanese called the machine *97-shiki ōbun inji-ki*
bgneal@26 20 (System 97 Printing Machine for European Characters), and *Angōki B-kata* (Type
bgneal@26 21 B Cipher Machine). The machine was used for secure diplomatic communications
bgneal@26 22 and was implemented as an electromechanical stepping-switch device.
bgneal@24 23
bgneal@24 24 This project is a Python 3 library and command-line utility for encrypting and
bgneal@24 25 decrypting text by simulating the operation of an actual PURPLE machine.
bgneal@24 26
bgneal@26 27 If you are brand new to the ``Purple`` cipher machine, please skip down to the
bgneal@26 28 references section and familiarize yourself with the device. This will help you
bgneal@26 29 understand the terminology used in the documentation, below.
bgneal@26 30
bgneal@24 31
bgneal@24 32 Requirements
bgneal@24 33 ############
bgneal@24 34
bgneal@24 35 ``Purple`` was written in Python_ 3, specifically 3.3.2, and has no other external
bgneal@24 36 dependencies.
bgneal@24 37
bgneal@24 38
bgneal@24 39 Installation
bgneal@24 40 ############
bgneal@24 41
bgneal@24 42 ``Purple`` is available on the `Python Package Index`_ (PyPI). There are
bgneal@24 43 a number of ways to install to ``Purple``, detailed below. The author
bgneal@24 44 recommends you install into a virtualenv_. Setting up a virtualenv is not hard,
bgneal@24 45 but describing it is out of scope for this document. Please see the virtualenv_
bgneal@24 46 documentation for more information.
bgneal@24 47
bgneal@24 48 You can install it using pip_::
bgneal@24 49
bgneal@24 50 $ pip install purple # install
bgneal@24 51 $ pip install --upgrade purple # upgrade
bgneal@24 52
bgneal@24 53 You can also visit the the `Purple Bitbucket page`_ and download an archive
bgneal@24 54 file of the latest code. Alternatively, if you use Mercurial_, you can clone
bgneal@24 55 the repository with the following command::
bgneal@24 56
bgneal@24 57 $ hg clone https://bitbucket.org/bgneal/purple
bgneal@24 58
bgneal@24 59 If you did not use pip_ (you downloaded or cloned the code yourself), you can
bgneal@24 60 install with::
bgneal@24 61
bgneal@24 62 $ cd where-you-extracted-purple
bgneal@24 63 $ python setup.py install
bgneal@24 64
bgneal@24 65 To run the unit tests::
bgneal@24 66
bgneal@24 67 $ cd where-you-extracted-purple
bgneal@24 68 $ python -m unittest discover
bgneal@24 69
bgneal@24 70
bgneal@26 71 Initial Settings Syntax
bgneal@26 72 #######################
bgneal@26 73
bgneal@26 74 In order to exchange messages, each message recipient must use the same initial
bgneal@26 75 machine settings. For the ``Purple`` machine, these settings are the initial
bgneal@26 76 switch positions for the "sixes" and three "twenties" stepping switches, the
bgneal@26 77 switch motion order (which twenties switch is the fast switch, which is the
bgneal@26 78 middle switch, and which is the slow switch), and finally the plugboard
bgneal@26 79 alphabet mapping.
bgneal@26 80
bgneal@26 81 The ``Purple`` simulation uses the following syntax in both its command-line
bgneal@26 82 application and library code.
bgneal@26 83
bgneal@26 84 For the switches, we borrow the notation used by U.S. cryptanalysts, for
bgneal@26 85 example::
bgneal@26 86
bgneal@26 87 9-1,24,6-23
bgneal@26 88
bgneal@26 89 Here the first number before leading dash, 9, indicates the starting position
bgneal@26 90 of the sixes switch. The next three numbers are the starting positions for the
bgneal@26 91 three twenties switches numbered 1, 2, and 3. Each switch position is a number
bgneal@26 92 from 1 through 25, inclusive. Finally, after the last dash are two digits which
bgneal@26 93 indicate the switch stepping motion. The first number, in this case 2,
bgneal@26 94 indicates that the twenties switch #2 is the fast switch. The second number, 3,
bgneal@26 95 indicates twenties switch #3 is the middle switch. Thus the slow switch, which
bgneal@26 96 is never listed, is in this case twenties switch #1. When using this syntax, do
bgneal@26 97 not insert space characters.
bgneal@26 98
bgneal@26 99 The plugboard alphabet setting describes how the input typewriters are wired to
bgneal@26 100 the plugboard. We represent this setting as a string of the 26 uppercase
bgneal@26 101 alphabet letters where the first six letters are the wiring to the sixes
bgneal@26 102 switch, and the remaining 20 are wired to the first stage of the twenties
bgneal@26 103 switches. For example::
bgneal@26 104
bgneal@26 105 AEIOUYBCDFGHJKLMNPQRSTVWXZ
bgneal@26 106
bgneal@26 107 For the alphabet setting to be valid, do not insert spaces, and ensure all 26
bgneal@26 108 letters are used exactly once.
bgneal@26 109
bgneal@26 110
bgneal@24 111 Command-line Usage
bgneal@24 112 ##################
bgneal@24 113
bgneal@24 114 To get help on the command-line ``Purple`` utility, execute the ``purple``
bgneal@24 115 command with the ``--help`` option::
bgneal@24 116
bgneal@24 117 $ purple --help
bgneal@24 118 usage: purple [-h] [-e] [-d] [-f] [-s SWITCHES] [-a ALPHABET] [-t TEXT]
bgneal@24 119 [-i FILE] [-g N] [-w N]
bgneal@24 120
bgneal@24 121 PURPLE cipher machine simulator
bgneal@24 122
bgneal@24 123 optional arguments:
bgneal@24 124 -h, --help show this help message and exit
bgneal@24 125 -e, --encrypt perform an encrypt operation
bgneal@24 126 -d, --decrypt perform a decrypt operation
bgneal@24 127 -f, --filter filter plaintext and provide useful substitutions
bgneal@24 128 -s SWITCHES, --switches SWITCHES
bgneal@24 129 switch settings, e.g. 9-1,24,6-23
bgneal@24 130 -a ALPHABET, --alphabet ALPHABET
bgneal@24 131 plugboard wiring string, 26-letters; e.g.
bgneal@24 132 AEIOUYBCDFGHJKLMNPQRSTVWXZ
bgneal@24 133 -t TEXT, --text TEXT input text to encrypt/decrypt
bgneal@24 134 -i FILE, --input FILE
bgneal@24 135 file to read input text from, - for stdin
bgneal@24 136 -g N, --group N if non-zero, group output in N-letter groups [default:
bgneal@24 137 5]
bgneal@24 138 -w N, --width N wrap output text to N letters; a value of 0 means do
bgneal@24 139 not wrap [default: 70]
bgneal@24 140
bgneal@24 141 Supply either -e or -d, but not both, to perform either an encrypt or decrypt.
bgneal@24 142 If the -s option is not supplied, the value of the environment variable
bgneal@24 143 PURPLE97_SWITCHES will be used. If the -a option is not supplied, the value of
bgneal@24 144 the environment variable PURPLE97_ALPHABET will be used. Input text is
bgneal@24 145 supplied either by the -t or by the -f options, but not both.
bgneal@24 146
bgneal@26 147 The ``purple`` command operates in two modes, either encrypt (specified with
bgneal@26 148 ``-e`` or ``--encrypt``) or decrypt (``-d`` or ``--decrypt``). Input text can
bgneal@26 149 be specified on the command-line with the ``-t`` or ``--text`` option, or
bgneal@26 150 a read from a file (``-i`` or ``--input``).
bgneal@26 151
bgneal@26 152 The ``-s`` (or ``--switches``) and ``-a`` (or ``--alphabet``) settings
bgneal@26 153 determine the initial machine settings. They use the syntax described above in
bgneal@26 154 the Initial Settings Syntax section.
bgneal@24 155
bgneal@24 156 If you are going to be working with the same initial switch settings and
bgneal@26 157 plugboard alphabet over many command invocations it may be more convenient to
bgneal@26 158 specify them as environment variables instead of repeatedly using the
bgneal@26 159 command-line arguments. The examples below assume these statements have been
bgneal@26 160 executed::
bgneal@24 161
bgneal@24 162 $ export PURPLE97_SWITCHES=9-1,24,6-23
bgneal@24 163 $ export PURPLE97_ALPHABET=NOKTYUXEQLHBRMPDICJASVWGZF
bgneal@24 164
bgneal@26 165 If you do not specify initial settings, the ``purple`` machine will attempt to
bgneal@26 166 read them from these two environment variables. Failing that, ``purple`` will
bgneal@26 167 use the following initial settings:
bgneal@26 168
bgneal@26 169 * default switch settings: 1-1,1,1-12
bgneal@26 170 * default alphabet: AEIOUYBCDFGHJKLMNPQRSTVWXZ
bgneal@24 171
bgneal@24 172 When encrypting text, the ``purple`` machine only accepts the letters A-Z, but
bgneal@24 173 also allows for "garble" letters to be indicated by using the ``-`` (dash)
bgneal@24 174 character. This means all punctuation and spaces must be either be omitted or
bgneal@24 175 input via some other convention. The ``-f`` or ``--filter`` flag, when present,
bgneal@24 176 relaxes these restrictions a bit. When this flag is on, all lowercase letters
bgneal@24 177 will be converted to uppercase, digits will be converted to words (e.g.
bgneal@24 178 5 becomes FIVE), and all other characters will be ignored.
bgneal@24 179
bgneal@24 180 A simple encrypt example using the ``-f`` flag is given below::
bgneal@24 181
bgneal@26 182 $ purple --encrypt -t "The PURPLE machine is now online" -f
bgneal@24 183 OGIVT SIAAH MWMHT VIBYY JUOJF UE
bgneal@24 184
bgneal@24 185 By default ``purple`` prints the output in 5-letter groups. This can be
bgneal@24 186 disabled or customized with the ``--group`` and ``--width`` options.
bgneal@24 187
bgneal@24 188 To decrypt this message::
bgneal@24 189
bgneal@26 190 $ purple --decrypt -t "OGIVT SIAAH MWMHT VIBYY JUOJF UE"
bgneal@24 191 THEPU RPLEM ACHIN EISNO WONLI NE
bgneal@24 192
bgneal@24 193 Note that spaces are ignored on input. Again the output is produced in 5-letter
bgneal@24 194 groups and wrapped at 70 letters per line. Here is the output again with
bgneal@24 195 grouping disabled::
bgneal@24 196
bgneal@24 197 $ purple -d -t "OGIVT SIAAH MWMHT VIBYY JUOJF UE" -g 0
bgneal@24 198 THEPURPLEMACHINEISNOWONLINE
bgneal@24 199
bgneal@26 200 You can use file redirection to capture output in a file::
bgneal@24 201
bgneal@24 202 $ purple -e -t "The PURPLE machine is now online" -f > secret.txt
bgneal@24 203 $ purple -d -i secret.txt
bgneal@24 204 THEPU RPLEM ACHIN EISNO WONLI NE
bgneal@24 205
bgneal@24 206
bgneal@24 207 Library Usage
bgneal@24 208 #############
bgneal@24 209
bgneal@26 210 To use ``Purple`` from within Python code you must first construct
bgneal@26 211 a ``Purple97`` object, which represents a single PURPLE cipher machine. The
bgneal@26 212 constructor is given below::
bgneal@26 213
bgneal@26 214 class Purple97(switches_pos=None, fast_switch=1, middle_switch=2,
bgneal@26 215 alphabet=None)
bgneal@26 216
bgneal@26 217 The ``switches_pos`` argument, when not ``None``, must be a 4-tuple or list of
bgneal@26 218 4 integers that describe the initial switch positions. Element 0 is the sixes
bgneal@26 219 initial position, and the remaining elements are the initial positions of the
bgneal@26 220 three twenties switches. These values must be in the range 0-24, inclusive.
bgneal@26 221 If ``None`` then switch positions of all zeroes is assumed.
bgneal@26 222
bgneal@26 223 The ``fast_switch`` argument indicates which twenties switch (numbered 1-3) is
bgneal@26 224 the fast switch. Likewise, ``middle_switch`` indicates which switch is the
bgneal@26 225 middle switch. The slow switch is inferred. It is an error to give the
bgneal@26 226 ``fast_switch`` and ``middle_switch`` arguments the same value.
bgneal@26 227
bgneal@26 228 The ``alphabet`` argument is the plugboard alphabet mapping. It is expected to
bgneal@26 229 be a 26-letter uppercase string. If ``None``, a mapping of
bgneal@26 230 ``AEIOUYBCDFGHJKLMNPQRSTVWXZ`` is assumed.
bgneal@26 231
bgneal@26 232 For convenience, another constructor is provided that allows you to specify
bgneal@26 233 initial settings in the syntax described above::
bgneal@26 234
bgneal@26 235 classmethod Purple97.from_key_sheet(switches, alphabet=None)
bgneal@26 236
bgneal@26 237 Here ``switches`` is a string in the syntax described above, e.g.
bgneal@26 238 ``'9-1,24,6-23'``.
bgneal@26 239
bgneal@26 240 The ``alphabet`` argument is as described in the first constructor.
bgneal@26 241
bgneal@26 242 Once constructed, you can use the ``Purple97`` object to perform encrypt and
bgneal@26 243 decrypt operations. For example::
bgneal@26 244
bgneal@26 245 from purple.machine import Purple97
bgneal@26 246
bgneal@26 247 purple = Purple97.from_key_sheet(
bgneal@26 248 switches='9-1,24,6-23',
bgneal@26 249 alphabet='NOKTYUXEQLHBRMPDICJASVWGZF')
bgneal@26 250
bgneal@26 251 ciphertext = purple.encrypt('THEPURPLEMACHINEISONLINE')
bgneal@26 252
bgneal@26 253 purple = Purple97([8, 0, 23, 5], fast_switch=2, middle_switch=3,
bgneal@26 254 alphabet='NOKTYUXEQLHBRMPDICJASVWGZF')
bgneal@26 255
bgneal@26 256 plaintext = purple.decrypt(ciphertext)
bgneal@26 257
bgneal@26 258 For more information, please review the docstrings in the code.
bgneal@26 259
bgneal@24 260
bgneal@24 261 Support
bgneal@24 262 #######
bgneal@24 263
bgneal@26 264 To report a bug or suggest a feature, please use the issue tracker at the
bgneal@29 265 `Purple Bitbucket page`_. You can also email the author using the address at
bgneal@29 266 the top of this file.
bgneal@26 267
bgneal@24 268
bgneal@24 269 References
bgneal@24 270 ##########
bgneal@24 271
bgneal@26 272 #. *PURPLE Revealed: Simulation and Computer-aided Cryptanalysis of Angooki
bgneal@26 273 Taipu B*, by Wes Freeman, Geoff Sullivan, and Frode Weierud. This paper
bgneal@26 274 was published in Cryptologia, Volume 27, Issue 1, January, 2003, pp. 1-43.
bgneal@26 275 #. Frode Weierud's CryptoCellar page: `The PURPLE Machine`_
bgneal@26 276 #. Wikipedia Article: `PURPLE Machine`_
bgneal@26 277
bgneal@26 278 The paper in reference 1 is also available here:
bgneal@26 279 http://cryptocellar.web.cern.ch/cryptocellar/pubs/PurpleRevealed.pdf
bgneal@26 280
bgneal@26 281 This simulator would not have been possible without Frode Weierud's
bgneal@26 282 CryptoCellar page and the detailed explanations and analysis found in reference
bgneal@26 283 1. The author is also deeply grateful for email discussions with Frode Weierud
bgneal@26 284 and Geoff Sullivan who provided me with plaintext, advice, and encouragement.
bgneal@26 285
bgneal@26 286 The ``Purple`` simulator's operation was checked against the simulator found in
bgneal@26 287 reference 2.
bgneal@26 288
bgneal@24 289
bgneal@24 290 .. _PURPLE Machine: http://en.wikipedia.org/wiki/Purple_(cipher_machine)
bgneal@24 291 .. _Python: http://www.python.org
bgneal@26 292 .. _Python Package Index: http://pypi.python.org/pypi/purple/
bgneal@24 293 .. _virtualenv: http://www.virtualenv.org/
bgneal@24 294 .. _pip: http://www.pip-installer.org
bgneal@24 295 .. _Purple Bitbucket page: https://bitbucket.org/bgneal/purple/
bgneal@24 296 .. _Mercurial: http://mercurial.selenic.com/
bgneal@26 297 .. _The PURPLE Machine: http://cryptocellar.web.cern.ch/cryptocellar/simula/purple/