[PYTHON-CRYPTO] aes library

Paul Rubin phr-pycrypt at nightsong.com
Thu Apr 4 02:08:37 CEST 2002


[Note: if you reply to the list, please don't cc me your reply--I don't
need to get two copies.  Thanks.]

    [Zooko]
    > Do you really need CTR?  Is there a good reason BitTorrent
    > doesn't use CBC?

    I need CTR for a project I'm working on, not only for performance
    but for the technical reason that encryption and decryption are
    the same operation.

This is also true of OFB and sort of true of CFB.

    [Bram]
    Yes. CBC has the property that you need an even block size to do an
    encryption/decryption step, which makes it *awful* for operating on
    streams. As a general rule, if you're encrypting files, you use CBC, if
    you're encrypting streams, you use counter.

Traditionally for streams, you'd use CFB, which is self-resynchronizing
and doesn't need to be re-keyed so much.  CTR wasn't used much with DES.
It may be better with AES because of the larger block length.

Anyway, it sounds like there's desire to keep CTR, so fine, let's keep it.

    We can have a discard() method in addition to the read() method to
    avoid unnecessary allocs when doing CBC MAC.

This fancy OO interface doesn't seem like the right thing for a C
extension module.  Something like the SHA module interface (as we
discussed before) could be ok.  Each update operation would produce
ciphertext output (possibly 0 bytes) and keep up to one partial
plaintext block buffered, and the final() call would flush any
buffered partial block.  That way there's no magic buffer in the
crypto object getting dynamically resized on each operation.

    enc.write(part1)
    enc.write(part2)
    ciphertext = enc.read()

    Aside from being generally nicer to use, there will be very big
    performance improvements from this approach under some circumstances -
    many network applications spend most of their time doing string copies,
    and this approach reduces the number of those you have to do by 1.

I think the encryption and Python function calls will be much slower
than any string copies.  We could support Python buffer objects, but
we're probably better off keeping things simple.

    We can do that by naming the classes AES_whatever and
    3DES_whatever. I can see the advantage of being able to say 'all
    the cryptographic stuff goes here'. Although sha and sha256 are
    already in their own modules... I could go either way.

I don't think there's a standard sha256 module, but SHA and MD5 do
currently have separate modules.  So I could go either way too (see
below, though).

The advantage of putting AES and DES in the same module is that the
same code can implement the modes of operation without creating
dependencies between modules.  The other possible organization is
three modules, a modes-of-operation module callable from python, and
AES and DES modules that implement the raw block ciphers that the
modes-of-operation module can use.

    > Ultimately, whatever code gets implemented will only find wider
    > distribution if it's accompanied by (comprehensive and)
    > comprehensible documentation, which is what I find is usually
    > missing with crypto software.

    I'll happily provide usable sample code for all the common cases. That
    should be easy to do with CBC and counter modes, since their motivating
    cases are very common.

We get wide distribution if we can get the Python maintainers to put
AES into the standard Python release, which is one reason to put everything
in one module--it may be easier to get one module accepted than several.

As for documentation, rather than try to turn the poor app developer
into a cryptographer by explaining CBC mode and so forth, I think the
most important thing is to have an extremely simple interface for the
most obvious case, e.g.

   ciphertext = aes.encrypt(plaintext, key)
   plaintext = aes.decrypt(ciphertext, key)

where key and plaintext are arbitrary strings.  This however means the
"encrypt" function should take care of all padding and IV generation,
which means it needs good random numbers, which makes the encryption
module depend on a CPRNG whether the CPRNG is in the same module or a
separate one.

Anyway, I think we're somewhat going around in circles at this point
and we should implement something and see how we like it.  Anyone want
to meet up with me (San Francisco area) and start coding?





More information about the python-crypto mailing list