PEP: 272 Title: API for Secret-Key Encryption Algorithms Version: $Revision$ Author: A.M. Kuchling 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. 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 ECB Electronic Code Book 2 CBC Cipher Block Chaining 3 CFB Cipher FeedBack 4 PGP Variant of CFB See _Applied Cryptography_ for descriptions of the first three feedback modes. The PGP feedback mode is described in the OpenPGP RFC. In a strict formal sense, stream ciphers encrypt data bit-by-bit; practically, stream ciphers work on a character-by-character basis. Stream ciphers use exactly the same interface as block ciphers, with a block length that will always be 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 following table. 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, \code{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.ECB) >>> plain="Guido van Rossum is a space alien." >>> len(plain) 34 >>> obj.encrypt(plain) Traceback (innermost last): File "", 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 RFC2440: "OpenPGP Message Format" (http://rfc2440.x42.com, http://www.faqs.org/rfcs/rfc2440.html) Applied Cryptography Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: