# HG changeset patch # User Brian Neal # Date 1374433435 18000 # Node ID 30aa114bb746b958e7d6bf99c6438ce15917f490 # Parent a2647b9fe107a388ed581aa41c8ff63844ea9461 Added docs for StdProcedure and exceptions. diff -r a2647b9fe107 -r 30aa114bb746 docs/exceptions.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/exceptions.rst Sun Jul 21 14:03:55 2013 -0500 @@ -0,0 +1,30 @@ +Exceptions +========== + +The ``m209`` library defines an exception hierarchy, rooted at the +``M209Error`` class. These exceptions are briefly described below. + +.. class:: m209.M209Error() + + The base exception in the hierarchy. It inherits from the built in + Python ``Exception`` class. + +.. class:: m209.drum.DrumError() + + Inherits from :class:`~m209.M209Error`. This is an internal exception, used + to report drum related errors. + +.. class:: m209.key_wheel.KeyWheelError() + + Inherits from :class:`~m209.M209Error`. This is an internal exception, used + to report key wheel related errors. + +.. class:: m209.keylist.generate.KeyListGenError() + + Inherits from :class:`~m209.M209Error`. This is public exception, used + to report errors during the key list generation process. + +.. class:: m209.procedure.ProcedureError() + + Inherits from :class:`~m209.M209Error`. This is public exception, used + to report errors during :class:`~m209.procedure.StdProcedure` operations. diff -r a2647b9fe107 -r 30aa114bb746 docs/index.rst --- a/docs/index.rst Sat Jul 20 19:13:41 2013 -0500 +++ b/docs/index.rst Sun Jul 21 14:03:55 2013 -0500 @@ -80,6 +80,8 @@ All support takes place at the `m209 Bitbucket page`_. Please enter any feature requests or bugs into the `issue tracker`_. +.. _references-label: + References ---------- diff -r a2647b9fe107 -r 30aa114bb746 docs/library.rst --- a/docs/library.rst Sat Jul 20 19:13:41 2013 -0500 +++ b/docs/library.rst Sun Jul 21 14:03:55 2013 -0500 @@ -8,5 +8,7 @@ .. toctree:: :maxdepth: 3 + exceptions keylist m209 + procedure diff -r a2647b9fe107 -r 30aa114bb746 docs/procedure.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/procedure.rst Sun Jul 21 14:03:55 2013 -0500 @@ -0,0 +1,143 @@ +StdProcedure Class +================== + +The ``StdProcedure`` class encapsulates the encrypting and decrypting +procedures outlined in :ref:`references-label`. In particular, see +references [5] and [7]. This class takes care of the high level details of +inserted various message indicators into an encrypted message, and stripping +them off during decrypt. These message indicators tell the recipient what key +list and initial key wheel settings to use when configuring their M-209 for +decrypt. + +.. class:: m209.procedure.StdProcedure([m_209=None[, key_list=None]]) + + :param m_209: an instance of a :class:`~m209.converter.M209` can optionally be + provided to the procedure object. If ``None`` the procedure object + will create one for internal use. + :param key_list: an instance of a :class:`~m209.keylist.KeyList` can be + provided if known ahead of time. Before an encrypt or decrypt operation + can be performed, a key list must be provided. This can be done after + object creation via :meth:`set_key_list`. Note that the ``letter_check`` + attribute of the :class:`~m209.keylist.KeyList` is not accessed by the + procedure object, and can be ``None`` if not known. + +Before an :meth:`encrypt` operation can be performed, a valid key list must be +installed, either during procedure object construction, or by the +:meth:`set_key_list` method. + +Decrypt operations are performed in a 3-step process. + +#. First, a call to the :meth:`set_decrypt_message` method passes the message + to be decrypted to the procedure and establishes the parameters to be used + for the actual :meth:`decrypt` operation. These decrypt parameters are + returned to the caller. + +#. The caller can examine the decrypt parameters to determine which key list + must be installed before a successful :meth:`decrypt` operation can be + carried out. The caller may call :meth:`get_key_list` to examine the + currently installed key list. It is up to the caller to obtain the required + key list and install it with :meth:`set_key_list`, if necessary. This is + done by ensuring the installed key list indicator matches the + ``key_list_ind`` field of the decrypt parameters. + +#. Finally :meth:`decrypt` can be called. If the procedure does not have the + key list necessary to decrypt the message, a ``ProcedureError`` is + raised. + +``StdProcedure`` objects have the following methods: + + .. method:: get_key_list() + + :returns: the currently installed :class:`~m209.keylist.KeyList` object + or ``None`` if one has not been set + + .. method:: set_key_list(key_list) + + Establishes the :class:`~m209.keylist.KeyList` to be used for future + :meth:`encrypt` and :meth:`decrypt` operations + + :param key_list: the new :class:`~m209.keylist.KeyList` to use + + .. method:: encrypt(plaintext[, spaces=True[, ext_msg_ind=None[, sys_ind=None]]]) + :noindex: + + Encrypts a plaintext message using the installed + :class:`~m209.keylist.KeyList` and by following the standard procedure. + The encrypted text with the required message indicators are returned as + a string. + + :param plaintext: the input string to be encrypted + :param spaces: if ``True``, space characters in the input plaintext are + allowed and will be replaced with ``Z`` characters before encrypting + :param ext_msg_ind: this is the external message indicator, which, if + supplied, must be a valid 6-letter string of key wheel settings. If not + supplied, one will be generated randomly. + :param sys_ind: this is the system indicator, which must be a string of length + 1 in the range ``A`` - ``Z``, inclusive. If ``None``, one is chosen at random. + :returns: the encrypted text with the required message indicators + :raises ProcedureError: if the procedure does not have + a :class:`~m209.keylist.KeyList` or the input indicators are invalid + + .. method:: set_decrypt_message(msg) + + Prepare to decrypt the supplied message. + + :param msg: the messsage to decrypt. The message can be grouped into + 5-letter groups separated by spaces or accepted without spaces. + :returns: a ``DecryptParams`` named tuple to the caller (see below) + + The ``DecryptParams`` named tuple has the following attributes: + + * ``sys_ind`` - the system indicator + * ``ext_msg_ind`` - the external message indicator + * ``key_list_ind`` - the key list indicator + * ``ciphertext`` - the cipher text with all indicators removed + + The caller should ensure the procedure instance has the required + :class:`~m209.keylist.KeyList` before calling :meth:`decrypt`. The + ``key_list_ind`` attribute of the returned ``DecryptParams`` named tuple + identifies the key list that should be installed with + :meth:`set_key_list`. + + .. method:: decrypt() + :noindex: + + Decrypt the message set in a previous :meth:`set_decrypt_message` call. The + resulting plaintext is returned as a string. + + :returns: the decrypted plaintext as a string + :raises ProcedureError: if the procedure instance has not been + previously configured with the required :class:`~m209.keylist.KeyList` + via :meth:`set_key_list` + +Here is a simple interactive example of performing an encrypt operation. Here +we choose a random key list from our key list file, and use random indicators: + +>>> from m209.keylist.config import read_key_list +>>> from m209.procedure import StdProcedure +>>> +>>> key_list = read_key_list('m209keys.cfg') +>>> proc = StdProcedure(key_list=key_list) +>>> ct = proc.encrypt('ORDER THE PIZZA AT TWELVE HUNDRED HOURS') +>>> ct +'YYGBM ENNHT VBMTJ PEEFV JWLUU PAFTS VOHEA QEPEQ OKVUA XDAUX YYGBM ENNHT' +>>> + +The first and last two groups of this message contain the indicators. Here we +can see the system indicator was ``Y``, the external message indicator is +``GBMENN``, and the key list indicator is ``HT``. + +An example session for decrypting the above message might look like: + +>>> proc = StdProcedure() +>>> ct = 'YYGBM ENNHT VBMTJ PEEFV JWLUU PAFTS VOHEA QEPEQ OKVUA XDAUX YYGBM ENNHT' +>>> params = proc.set_decrypt_message(ct) +>>> params +DecryptParams(sys_ind='Y', ext_msg_ind='GBMENN', key_list_ind='HT', ciphertext='VBMTJ PEEFV JWLUU PAFTS VOHEA QEPEQ OKVUA XDAUX') +>>> key_list = read_key_list('m209keys.cfg', params.key_list_ind) +>>> proc.set_key_list(key_list) +>>> pt = proc.decrypt() +>>> pt +'ORDER THE PI A AT TWELVE HUNDRED HOURS ' +>>> +