[PYTHON-CRYPTO] PEP 272 version 2

Paul Rubin phr-pycrypt at nightsong.com
Thu Apr 18 12:44:47 CEST 2002


    For good or ill, here's another revision of PEP 272 making minor
    changes to address some of the comments made in the previous round of
    discussion.  I have resisted the temptation to increase the PEP's
    scope by adding padding, or random number generation, or public-key
    cryptography, because I think those should be separate PEPs.

I don't think any of them should be PEP's--did we have a discussion
of that already?  Here's the reasoning:

  I think PEP 272 shouldn't exist, because it aims to solve a
  non-existent problem, which is providing a standard API for multiple
  block cipher modules that plug interchangeably into applications.
  There's just no need for that.  PEP 272 seems to be written from a
  1980's point of view when we were afraid of the NSA's influence on
  DES and everyone had their favorite alternative block cipher that
  they wanted to use instead.  But that situation has sorted itself
  out now.  DES/3DES has been a standard for 25 years with no
  surprising problems.  Its paranoia-inspiring design mysteries were
  unravelled and published in the 90's so no one is afraid of it any
  more; and the current AES standard has better performance for new
  applications while supporting all the operations DES supports.

  So a new application should use AES and stick with it.  A program to
  interoperate with a legacy app (say with old versions of PGP that
  need the IDEA cipher) has to use whatever cipher the legacy app
  needs--again, it doesn't need pluggable ciphers since it has no
  choice what cipher to use.  PEP 272 might be a good starting point
  for the AES/DES cipher module documentation, but it doesn't seem
  useful as a spec for further such modules.  It would be like having
  a PEP for the API of trig functions in the math library.  If someone
  wants to add a hyperbolic haversine function, they should just
  implement and document it--a PEP for the API just isn't that useful.

  So I think PEP 272 should be withdrawn, and its text massaged into
  documentation for a DES/AES module submitted to the standard library.

  Note that AES and DES will share code to implement the modes of operation.
  If someone wants to implement another cipher, they may want to share
  that same code--it will be obvious how to do that, but it's a matter
  of low-level C interfaces, which this PEP so far says nothing about.

Anyway though, I'll remark on the contents again:

    The 'Changes' section reads as follows:

        2002-04: Removed references to stream ciphers; retitled PEP;
        prefixed feedback mode constants with MODE_; removed PGP feedback
        mode; added CTR and OFB feedback modes; clarified where numbers
        are measured in bytes and where in bits.

These are fine, PGP feedback mode can be restored too, but these
things should be optional per-implementation.

        The following table lists keyword arguments defined by this PEP:

          Keyword                 Meaning
        counter               Callable object that returns counter blocks
                              (see below; CTR mode only)

What's the purpose of this?  I thought we were just going to pass in
an integer, not a callable object.  Let's try to keep things simple.

        rounds                Number of rounds of encryption to use

I don't remember this in the last version.  IMO it should definitely
be removed.  There are no ciphers I know of where the number of rounds
is a user parameter.  In DES, the # of rounds is intimately related to
the sequents of rotations in the key schedule and if you mess with it
in the slightest way, you weaken the cipher.  In AES, the # of rounds
is determined by the key length.  In IDEA, Skipjack, and GOST, it's
fixed.  OK, it's sort of a parameter in RC5, but this is a rarity.
Anyway, the PEP shouldn't specify this.

    The Counter feedback mode requires a sequence of input blocks,

CTR mode is not a feedback mode.

    When 'mode' is MODE_CTR, the 'counter' keyword argument must be
    provided, and its value must be a callable object, such as a
    function or method.  Successive calls to this callable object must
    return a sequence of strings that are of the length 'block_size'
    and that never repeats.

IMO this is a poor idea since it complicates the implementation and
slows it down a lot if the callable function is written in Python.
It means the cipher module has to make back-calls into the interpreter.
I think we should leave it the way we discussed on the list earlier.

    The CFB mode operates on segments of the plaintext and ciphertext
    that are 'segment_size' bits long....
    Implementors are allowed to constrain 'segment_size' to be a
    multiple of 8 for simplicity, but they're encouraged to support
    arbitrary values for generality.

I don't understand why 8-bit CFB should be required if 1-bit CFB isn't
required.  I say don't require anything.  Don't require CFB to be
supported at all, but if it's supported, it's ok if the only segment
size supported is the same as the block size.

    Secret-key encryption modules should define two variables:

    block_size

        An integer value; the size of the blocks encrypted by this
        module, measured in bytes.  For all feedback modes, the length
        of strings passed to the encrypt() and decrypt() must be a
        multiple of the block size.

For RC5, this is variable.  So if anything, this parameter should be
in the cipher object and maybe a keyword parameter to the constructor,
not something the module itself defines.

    key_size

        An integer value; the size of the keys required by this
        module, measured in bytes.  If key_size is None, then the
        algorithm accepts arbitrary-length keys.  You cannot pass a
        key of length 0 (that is, the null string '') as such a
        variable-length key.

For AES, this is 128, 192, or 256 bits; it's not a single integer and
not arbitrary.

Really though, I think this amount of parametrization is excessive.
The application should know what cipher it's trying to use, and know
the characteristics of that cipher.  The cipher object constructor
should just throw an exception if you pass in a key length that the
cipher doesn't support.

    IV

        Contains the initial value which will be used to start a
        cipher feedback mode;

It's used for modes other than CFB as well--different wording is needed.
IV - contains the initialization vector used by CBC, CFB, and OFB modes.

    Cipher objects require the following methods:

    decrypt(string)

        Decrypts 'string', using the key-dependent data in the object
        ...

This really needs to understand the padding mode.  I don't think it's
sensible for a block cipher API spec to go into such detail about
feedback modes and say nothing about padding modes.

Over the past couple of weeks, we've had long discussions on the list
about the API of the AES module that Bram and I are hoping to write
tomorrow.  That API departed somewhat from PEP 272 but I thought we'd
reached consensus about it, at least til we have some code to try out.

Now the PEP has made another appearance and it's mostly the same as
before--what's the story?

I'd like it very much if this PEP was withdrawn and we weren't
constrained by it.  Let's write an implementation, bang it around for
a while, and then if necessary rewrite the PEP based on what we've
found the implementation needs to do.  This is the internet way--rough
consensus, running code, write the RFC afterwards.





More information about the python-crypto mailing list