[PYTHON-CRYPTO] Comments

PC Drew drewpc at COLORADO.EDU
Tue Feb 13 04:33:36 CET 2001


--On Monday, February 12, 2001 9:54 PM -0500 Dan Parisien
<dan at eevolved.com> wrote:

> On Segunda 12 Fevereiro 2001 12:29, you wrote:
>
>> (i.e. change the
>> random module so that it uses our cryptographically strong RNG).  That's
>> the route I see.
>
> Yeah, shouldn't Yarrow be distributed with standard python? Or a
> secure random number generator that adheres to the standard Python random
> number
> generator interface but uses a source of safe entropic data as a default
> seed. (aka: yarrow or whatever is available on the OS like the /dev/*rand
> series)
>

I think so.  Anyone object?  I think we should lobby for that when we get
things up and running.

>> 2.  There was talk about how to handle different implementations of an
>> alogrithm (i.e. MD5 in pure python, c, c++, assembly, etc).  I think this
>> is  _fundamental_ for this library.
>
> I agree.
>
>> "hashes.MD5.python.imp2".
>
> Close, but I think that is flawed. In the real world, there will not be
> many implementations of one algorithm for the same programming language.
> Good code is hard to find :) However, I agree with the idea.
>

I know that's flawed, I was basically just showing a directory structure
way of doing things.

> Also to solve Michael's problem we could adhere to a intuitive standard of
> directories & subdirectories that could be recursed into instead of having
> a central crypto registry:
>
> + crypto/
>     . __init__.py
>     + hash/
>         . __init__.py
>         . MD5.py
>         . SHA.py
>         . SHA256.py
>         . SHA256c.pyd / SHA256c.so
>
>     + symmetric/
>         . __init__.py
>         . aes.py
>         . rijndaelc.pyd / rijndaelc.so
>         . twofish.py
>         . twofishc.pyd / twofishc.so
>         . DES.py
>
>     + asymmetric/
>         . __init__.py
>         . RSA.py
>         . eccc.pyd / eccc.so
>         . ecc.py
>
>     + random/
>         . __init__.py
>         . yarrow.py
>         . yarrowc.pyd / yarrowc.so
>
> The .pyd/.so's would be swigged c code, the .py's pure python
> implementations (or
> wrappers around the swig code).
>

I agree, looks great to me.

> Here's my proposal for an API; trying to keep the nomenclature as
> intuitive as possible.
>
> simplified APIs:
>
> class Hash:
>     """
>     Hash module base class
>     """
>     def __init__(data=None)
>         """
>         Constructor
>
>         . data : initial data
>         """
>
>     def update(data)
>         """
>         Update the digest with additional data
>         """
>
>     def digest()
>         """
>         Return the message digest
>         """
>

Looks good to me.  It'd be nice to have a variable that stores the size of
the digest and the number of rounds.  If this doesn't apply to the specific
algorithm, then the round is set to 1 and the digest size is set to the
digest size that it uses.  As described in the docs for amkCrypto, HAVAL
suports variable sized digests and mulitple rounds.

> class Symmetric:
>     """
>     Base class for symmetric cipher
>
>     Important Attributes:
>
>     . key : Key to use for encryption/decryption
>     """
>     def __init__(key=None)
>         """
>         Constructor
>
>         . key : (optional) key to use for encryption/decryption
>
>         Raises EncryptionKeyError if the key is not of a valid size, etc
>         """
>
>     def keygen(size=None)
>         """
>         Generate a symmetric encryption key using a default (and
>         replaceable) secure prng.
>
>         . size : (optional) bit size of the key. If None, use a reasonable
>             default. (I think bit size is more intuitive considering it is
>             the de-facto way of refering to key sizes)
>
>         Raises KeySizeError if the size is invalid
>         """
>
>     def encrypt(data, key=None)
>         """
>         Encrypt data.
>
>         . data : Data to encrypt
>
>         . key : (optional) use this key to encrypt data. If key is
>         omitted, use value stored in attribute `key`.
>
>         Raises EncryptionKeyError if the key is not valid or not set
>         """
>
>     def decrypt(data, key=None)
>         """
>         Return decrypted data.
>
>         . data : Data to decrypt
>
>         . key : (optional) same as the optional key in .encrypt
>
>         Raises EncryptionKeyError if the key is not valid or not set
>         """
>

Again, it'd be nice to be able to change the block size and the number of
rounds.

> class Asymmetric:
>     """
>     Base class for asymmetric ciphers
>
>     Important Attributes:
>
>     . privateKey : Private key
>
>     . publicKey : Public key
>
>     . encryptKey : Remote user's public key
>     """
>     def __init__(privatekey=None, publickey=None, encryptkey=None)
>         """
>         Constructor
>
>         . privatekey : Default value for attribute privateKey
>
>         . publickey :  Default value for attribute publicKey
>
>         . encryptkey : Default value for attribute encryptKey
>
>         Raises EncryptionKeyError if any of the keys are not valid.
>         """
>
>     def keypair(self, size=None):
>         """
>         Return generated [publicKey, privateKey]. Uses a default (and,
>             as always, replaceable) secure prng.
>
>         . size : bit size of the key. If not set, use a reasonable
>             default
>
>         Raises KeySizeError if the key size is not one of the supported
>             key sizes
>         """
>
>     def encrypt(data, key=None):
>         """
>         Return encrypted data.
>
>         . data : data to encrypt
>
>         . key : key to use for encryption. If None, use attribute
>             encryptKey.
>
>         Raises EncryptionKeyError if the key is not valid or it is
>             not set
>         """
>
>     def decrypt(data, key=None):
>         """
>         Return decrypted data.
>
>         . data : data to decrypt
>
>         . key : key to use for decryption. If None, use attribute
>             privateKey.
>
>         Raises EncryptionKeyError if the decyption key is not valid
>             or it is not set
>         """
>
>     def sign(data, privkey=None)
>         """
>         Return signature.
>
>         . key : key used to sign the data. If not set, attribute
>         privateKey is used.
>
>         Raises EncryptionKeyError if the private key is not valid or it is
>             not set.
>         """
>
>     def verify(data, signature, pubkey=None)
>         """
>         If the signature is valid return 1, else return 0
>
>         . data : Data that was signed
>
>         . signature : signature to verify
>
>         . pubkey : Remote user's public key. If None, verify with
>         attribute encryptKey
>
>         Raises EncryptionKeyError if the public key is not valid or it is
>         not set anywhere.
>         """
>

This part looks good too...I'm not sure, but can the user decide which
symmetric algorithm to use with an asymmetric algorithm?  I think so...if
so, there needs to be a variable that defines this.  Should it be an
instance of one of the symmetric modules or should it just be the name of
the module?

> What do you guys think?
>
> Dan

I think it's a great start!  I'll take this initial pseudo code and come up
with some actual Python code that matches this and post it on the web.  All
who care can download it and make comments.

--
PC Drew

  Be nice or I'll replace you with a very
  small shell script.





More information about the python-crypto mailing list