[PYTHON-CRYPTO] aes library

Paul Rubin phr-pycrypt at nightsong.com
Thu Apr 4 07:36:43 CEST 2002


    [bram]
    It occurs to me that the counter mode API should really use
    position rather than counter - counter of x is the same as
    position 16 * x. If the API is based on counter you just wind up
    making something based on position on top of it.

Hmm, this makes more sense in an interface that encrypts byte streams
rather than strings.  It becomes somewhat removed from the AES CTR
definition, but I guess that's ok.

    Here's my latest stab at the API (hey, it can't hurt to have this as
    worked out as possible before we sit down and hack) -

    AES.__init__(key)

    key can be of length 16, 24, or 32.

    AES.ECB_encryt(str)
    AES.ECB_decryt(str)

    Those do what you'd expect.

I thought we weren't going to try to mix modes for a single key, i.e.
we'd have:

   a = AES.ECB(key)
   a.encrypt(str)
   a.decrypt(str)

And for CTR mode you'd use a separate constructor:

    a = AES.CTR(key, bigendian = 1, pos = 0)

initializes CTR key with internal position counter set to 0.

    a.encrypt(str)    # advances position counter by len(str)
    a.decrypt(str)    # likewise
    a.setpos(pos=0)   # reset internal counter, for random access
    a.getpos()        # return value of internal counter
    a.streamout(n)    # same as a.encrypt('\0'*n)

    [Bram]

    AES.CBC_encrypt(str, iv, padding = 1)
    AES.CBC_decrypt(str, iv, padding = 1)

    CBC_encrypt gets pissy if you give it padding = 0 and a str whose length
    isn't a multiple of 16. CBC_decrypt automatically strips padding. padding
    = 1 refers to pkcs5. padding values other than 0 and 1 are reserved for
    possible later use.

If padding==0 and len(str) is a multiple of 16, what happens to the IV?
Here's an alternate interface:

    a = AES.CBC(key, iv, direction='e')  # saves IV in aes object
    a.set_iv(iv)          # change internal IV
    a.get_iv()            # return old iv, don't change it

    a.update(str)         # encrypts str and returns ciphertext, buffering
                          # final partial input block and updating iv

    a.final(str)          # encrypts any buffered partial block with str,
                          # applying PKCS #5 padding

The terms 'update' and 'final' are consistent with the hashing modules.
For decryption you'd use direction='d' in the constructor.  Should the
IV be part of the ciphertext?

    [Bram]

    AES.CBC_encrypter(pos = 0, bigendian = 1)
    AES.CBC_decrypter(pos = 0, bigendian = 1)

    These are the same function. They return an object with the following
    methods -

    setpos(pos)
    getpos()
    encrypt(str)
    decrypt(str)

I don't understand what setpos and getpos are supposed to do for CBC mode.
I also don't see how the IV is supposed to fit into this.

    > You guys know about this, right?
    >
    >   http://sourceforge.net/projects/cryptkit/

    I don't like it's API, although it's got some working Python->C
    hooks for a what I believe is a fast AES implementation (unlike
    the one optimized for ease of dealing with which I'm using.)

I've been looking at it a little more.  It uses SWIG and we should fix
it sometime to use the standard Python C API, but it's a reasonable
starting point.  I'd forgotten about the SWIG thing because last time
I did anything with it, I didn't have SWIG and had to hack the
SWIG-generated wrapper file directly :-P.

    >     CryptKit is a small, fast cryptographic toolkit for
    >     python. It implements Rijndael(AES), SHA 256, Elliptic Curve
    >     PKI, Diffie-Hellman key exchange and Nyberg-Ruppel
    >     signature/verification. Comprehensive enough to provide a
    >     secure socket alternative to SSL.

    I don't think there's a need for DH and the like to be in the
    standard libs, since we have built-in modular exponentiation,
    which is all you need to build them in pure Python. Those modules
    probably are handy though.

Bleah, it looks like it has its own bignum library.  It uses Mike
Rosing's ECC code and I'd want to make sure that stuff was free to
copy before distributing it further.  I like having ECC but would
prefer characteristic p for some large p, rather than characteristic 2
even if it's slower.  I think there may be patents on optimal normal
base arithmetic as well :(.

I agree that for regular DH, pure Python is enough--I wrote a library
a while back that does it.  For characteristic p elliptic curves,
pure python might be ok.  For characteristic 2, C code is needed.

I don't understand what Nyberg-Ruppel signatures are.  I'd rather use
DSA and/or ECDSA.

Paul





More information about the python-crypto mailing list