Library reference

This module creates PEP-272 cipher object classes for building block ciphers in python.

To use, inherit the PEP272Cipher and overwrite encrypt_block or decrypt_block(self, key, string, **kwargs) methods and set the block_size attribute.

Example:

class YourCipher(PEP272Cipher):
    block_size=8

    def encrypt_block(self, key, string, **kwargs):
        ...

    def decrypt_block(self, key_string, **kwargs):
        ...

The PEP272Cipher class

Subclass and overwrite the PEP272Cipher.encrypt_block and PEP272Cipher.decrypt_block methods and the block_size attribute.

class pep272_encryption.PEP272Cipher(key, mode, IV=None, **kwargs)

A cipher class as defined in PEP-272.

Parameters:
  • key (bytes) – The symmetric key to use for encryption.
  • mode (int) – The mode of operation to use. For valid values see Reference/Block cipher mode of operation.
  • IV (bytes) – A unique bytestring with once the block size in length. For security reasons it should be unpredictable and must never be used twice for the same key. Required for CBC, CFB and OFB mode of operation.
  • **kwargs – See below.

Depending on the blockcipher mode of operation one or multiple of the following arguments must be passed depending on the mode of operation.

Keyword arguments:
 
  • iv (bytes) – Alternative name for IV
  • segment_size (int): The segment size for one encryption “segment” of CFB mode in bits. It must be multiple of 8 (only byte-sized operations are allowed) and the maximum size is the block size * 8. Required for CFB mode of operation.
  • counter (callable): A callable object returning block size bytes or a counter from Crypto.Util.Counter. For security reasons the counter output must never repeat. Required for CTR mode.
  • Additional keyword arguments are passed to the underlying block cipher implementation as kwargs.

Changed in version 0.4: IV can be used as a positional argument.

Changed in version 0.4: PyCryptodome counters are accepted for counter in addition to to callables.

decrypt(string)

Decrypt data with the key and the parameters set at initialization.

The cipher object is stateful; decryption of a long block of data can be broken up in two or more calls to decrypt(). That is, the statement:

>>> c.decrypt(a) + c.decrypt(b)

is always equivalent to:

>>> c.decrypt(a+b)

That also means that you cannot reuse an object for encrypting or decrypting other data with the same key.

This function does not perform any padding.

  • For MODE_ECB, MODE_CBC string length (in bytes) must be a multiple of block_size.
  • For MODE_CFB, string length (in bytes) must be a multiple of segment_size/8.
  • For MODE_CTR and MODE_OFB, string can be of any length.
Parameters:

string (bytes) – The piece of data to decrypt.

Raises:
  • ValueError – When a mode of operation has be requested this code cannot handle.
  • ValueError – When len(string) has a wrong length, as described above.
  • TypeError – When the counter in CTR returns data of the wrong length.
Returns:

The decrypted data, as a byte string. It is as long as string.

Return type:

bytes

decrypt_block(key, block, **kwargs)

Dummy function for the decryption of a single block. Overwrite with ‘real’ deryption function.

Parameters:
  • key (bytes) – The symmetric encryption key.
  • block (bytes) – A single ciphertext block to encrypt.
  • **kwargs – Additional parameters passed to __init__.
Raises:

NotImplementedError – This method is to be overridden.

Returns:

plaintext block

Return type:

bytes

encrypt(string)

Encrypt data with the key and the parameters set at initialization.

The cipher object is stateful; encryption of a long block of data can be broken up in two or more calls to encrypt(). That is, the statement:

>>> c.encrypt(a) + c.encrypt(b)

is always equivalent to:

>>> c.encrypt(a+b)

That also means that you cannot reuse an object for encrypting or decrypting other data with the same key.

This function does not perform any padding.

  • For MODE_ECB, MODE_CBC string length (in bytes) must be a multiple of block_size.
  • For MODE_CFB, string length (in bytes) must be a multiple of segment_size/8.
  • For MODE_CTR and MODE_OFB, string can be of any length.
Parameters:

string (bytes) – The piece of data to encrypt.

Raises:
  • ValueError – When a mode of operation has be requested this code cannot handle.
  • ValueError – When len(string) has a wrong length, as described above.
  • TypeError – When the counter callable in CTR returns data with the wrong length.
Returns:

The encrypted data, as a byte string. It is as long as string.

Return type:

bytes

encrypt_block(key, block, **kwargs)

Dummy function for the encryption of a single block. Overwrite with ‘real’ encryption function.

Parameters:
  • key (bytes) – The symmetric encryption key.
  • block (bytes) – A single plaintext block to encrypt.
  • **kwargs – Additional parameters passed to __init__.
Raises:

NotImplementedError – This method is to be overridden.

Returns:

ciphertext block

Return type:

bytes

Block cipher mode of operation

Note

For mote details about different modes of operation, see Discussions/Block cipher mode of operation.

Block ciphers can be used in different modes of operation. The mode of operation can be set by passing one of the constants to the cipher object. Different modes of operation may require to pass extra arguments to the constructor.

Below is an example from the mostly PEP-272 compliant PyCryptodome.

>>> from Crypto.Cipher import AES
>>> iv = b'random 16 bytes!'
>>> key = b'0123456789abcdef'
>>> cipher = AES.new(key, mode=AES.MODE_CBC, IV=iv)
>>> cipher.encrypt(b'\00'*16)
b'j\xa2\xb5\x80\xf7\xbd\xb4I\xda\xea\x9aN\x9d\xb5\x9a\x17'

This library supports following modes of operation:

  • Electronic code book (ECB)
  • Cipher Block Chaining (CBC)
  • Cipher Feedback (CFB)
  • Output Feedback (OFB)
  • Counter (CTR)

The CFB variant of PGP is not supported.

Planned modes are (extending to PEP-272):

  • Propagating Cipher Block Chaining (PCBC), used in older Kerberos versions
  • Infinite Garble Extension (IGE), used by Telegram.
  • OpenPGP mode, compatible to PyCrypto or PyCryptodome.

Authenticated encryption (AE) or authenticated encryption with associated data (AEAD) are currently not supported, as they would require additional methods to finalize the encryption and sometimes have special requirements.

Constant Number Source Implemented Specification
MODE_ECB 1 PEP-272 Yes NIST.SP.800-38A
MODE_CBC 2 PEP-272 Yes NIST.SP.800-38A
MODE_CFB 3 PEP-272 Yes NIST.SP.800-38A
MODE_PGP 4 PEP-272 No RFC 4880
MODE_OFB 5 PEP-272 Yes NIST.SP.800-38A
MODE_CTR 6 PEP-272 Yes NIST.SP.800-38A
MODE_OPENPGP 7 PyCrypto No RFC 4880
MODE_XTS 8 PyCryptoPlus No IEEE P1619 and NIST.SP.800-38E
MODE_CCM 8 PyCrypto (unreleased) / PyCryptodome No NIST.SP.800-38C
MODE_EAX 9 PyCrypto (unreleased) / PyCryptodome No The EAX Mode of Operation
MODE_SIV 10 PyCrypto (unreleased) / PyCryptodome No RFC 5297
MODE_GCM 11 PyCrypto (unreleased) / PyCryptodome No NIST.SP.800-38D
MODE_OCB 12 PyCrypto (unreleased) / PyCryptodome No RFC 7253

Utility functions

Utility library for compatibility with Python 2 and 3. A counter to use with CTR is also included.

There are versions of chr and ord-methods to work with bytes with Python 3 and strings with Python 2.

class pep272_encryption.util.Counter(nonce=None, initial_value=0, suffix=None, iv=None, IV=None, block_size=None, endian='big', wrap_around=False)

Counter for usage in CTR mode.

Big endian is as assumed for all counter operations by default.

Parameters:
  • nonce (bytes) – Prefix for counter operations.
  • initial_value (int) – Initial integer value.
  • suffix (bytes) – Suffix to add after output.
  • iv (bytes) – Counter output to resume. The usage of iv prohibits the use of nonce, initial_value, block_size and suffix.
  • IV (bytes) – Alternative for iv.
  • block_size (int) – Size of counter in-/output
  • endian (str) – Endian for number/byte conversions.
  • wrap_around (bool) – If an exception should not be raised if the counter returns the same value twice. For security reasons, setting this value to true is not recommended.

The counter is not thread safe.

Without arguments, it generates a random nonce, with the counter starts at 0:

>>> c = Counter()  # random nonce
>>> c().endswith(b"\x00")
True
>>> c().endswith(b"\x01")
True
>>> c().endswith(b"\x02")
True

Alternatively, a nonce and an initial value can be set:

>>> c = Counter(nonce=b'\x00\x01\x02', initial_value=0xff01,
...                   block_size=8)
>>> c()
b'\x00\x01\x02\x00\x00\x00\xff\x01'
>>> c()
b'\x00\x01\x02\x00\x00\x00\xff\x02'

The third alternative is to give a full start string. Counter length is determined by the IV length:

>>> c = Counter(IV=b'\x00'*4, endian="little")
>>> c()
b'\x00\x00\x00\x00'
>>> c()
b'\x01\x00\x00\x00'
block_size = 16

Used by many algorithms

pep272_encryption.util.b_chr(ordinal)

Return a byte string of one character with 0 <= ordinal <= 255.

Parameters:ordinal (int) – The Unicode code point of a single char
Returns:The byte string representation of the ordinal
Return type:bytes
pep272_encryption.util.b_ord(byte)

Return the Unicode code point for a byte or iteration product of a byte string alike object (e.g. bytearray).

Parameters:byte (bytes or str or int) – The single byte or iteration product of a byte string to convert
Returns:Unicode code point
Return type:int
pep272_encryption.util.from_bytes(bytestring, byteorder)

Convert a bytestring to an interger.

Parameters:
  • bytestring (bytes) – The byte string to convert.
  • byteorder (str) – either ‘big’ or ‘little’
Return type:

int

pep272_encryption.util.split_blocks(bytestring, block_size)

Splits bytestring in block_size-sized blocks.

Raises an error if len(string) % blocksize != 0.

pep272_encryption.util.to_bytes(integer, length, byteorder)

Convert an integer to a bytestring.

Parameters:
  • integer (int) – The integer to convert.
  • length (int) – Length of the created byte string.
  • byteorder (str) – either ‘big’ or ‘little’.
Return type:

bytes

pep272_encryption.util.xor_strings(one, two)

xor two bytestrings together.

Parameters:
  • one (bytes) – First string
  • two (bytes) – Second string
Returns:

The xored strings

Return type:

bytes