[PYTHON-CRYPTO] aes library
Bram Cohen
bram at GAWTH.COM
Thu Apr 4 21:54:24 CEST 2002
Paul Rubin wrote:
> 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)
That's the approach I gave before, I figured I'd float this other one as a
possibility - I don't have a strong preference either way, although if
you're going to do both CBC and ECB operations, for example, the approach
I just gave avoids multiple key setupds.
> 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)
Argh, I cut and pasted wrong, so I mixed up the API for CBC and counter,
which of course made them gibberish.
The above is almost identical to the methods I meant to post for counter
objects, except that I didn't include a streamout (although I can see it's
utility, I don't have a strong opinion about it).
> 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?
The same thing that always happens to the IV - padding just has to do with
what's at the ending. In PKCS5 it's done by essentially the following
trick -
p = len(str) % 16
if p == 0:
p = 16
str += chr(p) * p
With 'no' padding it just raises a ValueError if len(str) % 16 isn't 0.
> 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
reusing iv's is such a bad idea that I think having set_iv and get_iv is
inadvisable, since it doesn't have any performance benefit when you're not
reusing iv's, and encourages very bad behavior.
'update' and 'final' I can go with, although 'final' should take an
optional padding = 1.
I don't like the direction call at all - encryption and decryption are two
completely different operations, likely not using any shared code, and
using direction='d' is vastly more obscure than calling the constructor of
CBC_decrypter.
> Should the IV be part of the ciphertext?
No, if the user wants to prepend the IV they can do that themselves.
> [Bram]
>
> AES.CBC_encrypter(pos = 0, bigendian = 1)
> AES.CBC_decrypter(pos = 0, bigendian = 1)
That should have been CTR_encrypter and CTR_decrypter, which makes the
following make a lot more sense -
> These are the same function. They return an object with the following
> methods -
>
> setpos(pos)
> getpos()
> encrypt(str)
> decrypt(str)
(see comments above)
> 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.
Is it currently possible to implement DSA in pure Python? I'd like the
minimum base functions put into the standard libs which make basic strong
crypto possible without resorting to C code.
-Bram Cohen
"Markets can remain irrational longer than you can remain solvent"
-- John Maynard Keynes
More information about the python-crypto
mailing list