[PYTHON-CRYPTO] Python rijndael implementation

Andrew Archibald aarchiba at YAHOO.COM
Tue Apr 24 16:11:31 CEST 2001


On Mon, Apr 23, 2001 at 09:30:00PM -0700, Bram Cohen wrote:
> On Mon, 23 Apr 2001, Rich Salz wrote:
>
> > > It appears that a Python mode implementation using C versions
> > > of these would spend most of it's time in the underlying C calls.
> >
> > The thing that kills you is (needless) buffer copies.  In C it's pretty
> > easy to declare a couple of buffers (often, on the stack) and use them
> > repeatedly for the various chaining codes, e.g.  It's hard to do that in
> > python, at least in a way that's pythonic. :)
>
> Python's string immutability does introduce some expense, but I think not
> all that much - it forces an extra malloc/memcpy for each call to xor and
> encrypt, which means two extra malloc/memcpy calls per block, which I
> don't *think* is all that bad compared to the fourteen rounds of thorough
> bit twiddling done inside of the rijndael encrypt function.

There's a security issue here, too: if you strew copies of plaintext and
keys all over memory, it's almost certain to get swapped to disk.  Now,
secure memory is hard, even in C, but at least if you can burn buffers you
have a little more hope.  There's something to be said for an extremely
heavyweight crypto API (like cryptix) where keys and encryption are all
opaque blocks, perhaps in a hardware device, perhaps in another process
(which has used mlock) which protects them from needless fiddling.

That said, I think it's better for now to just implement this stuff in
python.

> >
> > I'd love to be proven wrong.
>
> The only way to tell for sure is to benchmark both ways - I'll go write a
> CBC mode implementation, and if someone else does a C implementation of
> rijndael and xor we can benchmark it...

xor you can do surprisingly fast with bytestolong and longtobytes or array:

def xor(a,b):
    aa = array.array('i',a)
    bb = array.array('i',b)
    for i in range(len(aa)):
        bb[i] = bb[i] ^ aa[i]
    return bb.tostring()

> At worst, doing modes in Python is 'not as fast as an optimized all C
> version' slow, rather than 'hope you've got a good book, it's about to
> start bit-twiddling in Python' slow.
>
> I'm hoping it incurs only a 25% or so extra hit, which I think would
> warrant doing it standard, and letting applications which *really* depend
> on crypto speed to do their own pure-C mode implementation.

The crypto API should provide convenience functions for common modes, if
only because most people (myself included) are likely to mess up
implementing them.  So rather than letting people write their own, it's
probably easier to provide an implementation of that interface in C...
when we get around to it.

Andrew



More information about the python-crypto mailing list