python-peps/pep-0272.txt

168 lines
5.8 KiB
Plaintext
Raw Normal View History

PEP: 272
Title: API for Secret-Key Encryption Algorithms
Version: $Revision$
Author: A.M. Kuchling <akuchlin@mems-exchange.org>
Status: Draft
Type: Informational
Created: 18-Sep-2001
Post-History:
Abstract
This document specifies a standard API for secret-key encryption
algorithms such as DES or Rijndael, making it easier to switch
between different algorithms and implementations. The API is
intended to be suitable for both block and stream ciphers.
Introduction
Encryption algorithms transform their input data (called
plaintext) in some way that is dependent on a variable key,
producing ciphertext. The transformation can easily be reversed
if and only if one knows the key. The key is a sequence of bits
chosen from some very large space of possible keys. There are two
classes of encryption algorithms: block ciphers and stream ciphers.
Block ciphers encrypt multibyte inputs of a fixed size (frequently
8 or 16 bytes long), and can be operated in various feedback
modes. The feedback modes supported in this specification are:
Number Constant Description
1 MODE_ECB Electronic Code Book
2 MODE_CBC Cipher Block Chaining
3 MODE_CFB Cipher FeedBack
5 MODE_OFB Output Feedback
6 MODE_CTR Counter
These modes are to be implemented as described in NIST publication
SP-800A[1]. Descriptions of the first three feedback modes can
also be found in Bruce Schneier's book _Applied
Cryptography_ [2].
(The value of 4 is reserved for MODE_PGP, a variant of CFB
described in RFC 2440: "OpenPGP Message Format"[3]. This mode
isn't considered important enough to make it worth requiring it
for all block encryption ciphers.)
In a strict formal sense, stream ciphers encrypt data bit-by-bit;
practically, stream ciphers work on a character-by-character
basis. Stream ciphers can use exactly the same interface as block
ciphers, fixing the block length at 1; this is how block and
stream ciphers can be distinguished. The only feedback mode
available for stream ciphers is ECB mode.
Specification
All cipher algorithms share a common interface.
Secret-key encryption modules define one function:
new(key, mode, [IV], **kwargs)
Returns a ciphering object, using the secret key contained in the
string 'key', and using the feedback mode 'mode', which must be
one of the constants from the table above.
If 'mode' is CBC or CFB, 'IV' must be provided, and must be a
string of the same length as the block size. Not providing a
value of 'IV' will result in a XXXError exception being raised.
(what exception? ValueError? ciphermodule.error?)
Depending on the algorithm, a module may support additional
keyword arguments to this function. The most common keyword
argument will likely be 'rounds', to set the number of rounds to
be used.
Secret-key encryption modules define two variables:
block_size
An integer value; the size of the blocks encrypted by this
module. For all feedback modes, the length of strings passed to
the encrypt() and decrypt() must be a multiple of the block size.
For stream ciphers, block_size will be 1.
key_size
An integer value; the size of the keys required by this
module. If key_size is None, then the algorithm accepts
arbitrary-length keys. You cannot pass a key of length 0
(that is, the null string '') as such a variable-length key.
Cipher objects require two attributes:
block_size
An integer value equal to the size of the blocks encrypted by
this object. For algorithms with a variable block size, this
value is equal to the block size selected for this object.
IV
Contains the initial value which will be used to start a
cipher feedback mode; it will always be a string exactly one
block in length. After encrypting or decrypting a string,
this value is updated to reflect the modified feedback text.
It is read-only, and cannot be assigned a new value.
Cipher objects require the following methods:
decrypt(string)
Decrypts 'string, using the key-dependent data in the object,
and with the appropriate feedback mode. The string's length
must be an exact multiple of the algorithm's block size.
Returns a string containing the plaintext.
encrypt(string)
Encrypts a non-empty string, using the key-dependent data in
the object, and with the appropriate feedback mode. The
string's length must be an exact multiple of the algorithm's
block size; for stream ciphers, the string can be of any
length. Returns a string containing the ciphertext.
Here's an example, using a module named 'DES':
>>> import DES
>>> obj = DES.new('abcdefgh', DES.MODE_ECB)
>>> plain="Guido van Rossum is a space alien."
>>> len(plain)
34
>>> obj.encrypt(plain)
Traceback (innermost last):
File "<stdin>", line 1, in ?
ValueError: Strings for DES must be a multiple of 8 in length
>>> ciph=obj.encrypt(plain+'XXXXXX')
>>> ciph
'\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006'
>>> obj.decrypt(ciph)
'Guido van Rossum is a space alien.XXXXXX'
References
[1] NIST publication SP 800-38A, "Recommendation for Block Cipher
Modes of Operation" (http://csrc.nist.gov/encryption/modes/)
[2] Applied Cryptography
[3] RFC2440: "OpenPGP Message Format" (http://rfc2440.x42.com,
http://www.faqs.org/rfcs/rfc2440.html)
Copyright
This document has been placed in the public domain.
Local Variables:
mode: indented-text
indent-tabs-mode: nil
End: