Symmetric Ciphers

Overview

from tomcrypt import cipher

The tomcrypt.cipher module contains a Descriptor class which describes a cipher, and a Cipher class for using a cipher (eg. keys, IVs, etc.). As a convenience there is a pre-made Descriptor for every cipher provided.

The module also contains a list of the names of all ciphers provided, and the modes that they can operate in:

>>> sorted(cipher.names)
['aes', 'anubis', 'blowfish', 'cast5', 'des', 'des3', 'kasumi', 'khazad', 'kseed', 'noekeon', 'rc2', 'rc5', 'rc6', 'rijndael', 'saferp', 'twofish', 'xtea']
>>> sorted(cipher.modes)
['cbc', 'cfb', 'ctr', 'ecb', 'f8', 'lrw', 'ofb']

We can inspect some of the properties of a cipher via attributes on a Descriptor or Cipher:

>>> cipher.aes.block_size
16
>>> cipher.aes.min_key_size
16
>>> cipher.aes.max_key_size
32

Descriptor.key_size returns the size of the largest key than can be constructed from a string of a given size:

>>> cipher.aes.key_size(18)
16

We can construct a Cipher object directly (and pass a cipher name via the cipher kwarg) or, as a shortcut, use an instantiated Descriptor as a factory. You can pass a key, iv, cipher (if calling Cipher; defaults to "aes"), mode (defaults to "ctr"), tweak (only for "lrw" mode), and salt_key (only for “f8” mode).

>>> encryptor = cipher.Cipher(key=b'0123456789abcdef', iv=b'0123456789abcdef', cipher='aes', mode='ctr')
>>> # OR
>>> encryptor = cipher.aes(key=b'0123456789abcdef', iv=b'0123456789abcdef', mode='ctr')

>>> message = encryptor.encrypt(b'This is a message')
>>> message
b'&\x1a\x17\xfb>\xb5\x8e!a\x87u\r\nz\xd4\x02\x94'

>>> decryptor = cipher.aes(key=b'0123456789abcdef', iv=b'0123456789abcdef', mode='ctr')
>>> decryptor.decrypt(message)
b'This is a message'

For those modes which support an IV, you can explicitly get and set it via Cipher.get_iv and Cipher.set_iv methods.

Descriptor API

class tomcrypt.cipher.Descriptor(name)

LibTomCrypt descriptor of a symmetric cipher.

Can be called as convenience to calling Cipher, passing the cipher name via kwargs.

__init__(name)
Parameters:name (str) – Name of a cipher, e.g. "aes" or "3des".
>>> aes = Descriptor('aes') # Same as tomcrypt.cipher.aes.
__call__(key, iv=None, mode='ctr', **kwargs)

Initialize a cipher state.

This is a convenience for constructing Cipher objects; any keyword arguments will be passed to the constructor.

>>> cipher = aes(b'0123456789abcdef', b'\0' * 16)
>>> cipher.encrypt(b'hello')
b'c\xfey\xb6$'
name

Name of this cipher.

>>> aes.name
'aes'
block_size

Block size of this cipher.

>>> aes.block_size
16
default_rounds

Default number of “rounds” for this cipher.

>>> aes.default_rounds
10
max_key_size

Maximum key size for this cipher, in bytes.

>>> aes.max_key_size
32
min_key_size

Minimum key size for this cipher, in bytes.

>>> aes.min_key_size
16
key_size(size)

The largest key that can be sliced from a string of the given size.

Parameters:key_size (int) – Length of availible key material.
Returns int:The size that can be sliced from the string.
Raises LibError:
 if the size is too small.
>>> aes.key_size(16)
16

>>> aes.key_size(128)
32

>>> aes.key_size(8)
Traceback (most recent call last):
...
LibError: Invalid keysize for block cipher.

Cipher API

class tomcrypt.cipher.Cipher(key, iv=None, cipher='aes', mode='ctr', **kw)

All state required to encrypt/decrypt with a symmetric cipher.

>>> cipher = Cipher(b'0123456789abcdef', b'0123456789abcdef', cipher='aes', mode='cbc')

See Cipher.add_header() for example of EAX mode.

Basics

Cipher.__init__(key, iv=None, cipher='aes', mode='ctr', **kw)
Parameters:
  • key (bytes) – Symmetric key.
  • iv (bytes) – Initialization vector; required for non-ECB modes.
  • cipher (str) – The name of the cipher to use.
  • mode (str) – Cipher block chaining more to use.

Mode Specific Parameters (by keyword only):

Parameters:
  • header (bytes) – Only for “eax” mode.
  • nonce (bytes) – Only for “eax” mode.
  • salt_key (bytes) – Only for “f8” mode.
  • tweak (bytes) – Only for “lrw” mode.
Cipher.encrypt(input)

Encrypt a string.

>>> cipher = aes(b'0123456789abcdef', b'\0' * 16)
>>> cipher.encrypt(b'this is a message')
b'\x7f\xf3|\xa9k-\xd3\xd5t=\xa2\xa1\xb3lT\xb2d'
Cipher.decrypt(input)

Decrypt a string.

>>> cipher = aes(b'0123456789abcdef', b'\0' * 16)
>>> cipher.decrypt(b'\x7f\xf3|\xa9k-\xd3\xd5t=\xa2\xa1\xb3lT\xb2d')
b'this is a message'

Initialization Vectors

Cipher.get_iv()

Returns the current IV, for modes that use it.

Returns bytes:The current IV.
Raises tomcrypt.Error:
 when the mode does not use IVs.
>>> cipher = aes(b'0123456789abcdef', b'ThisWillSetTheIV')
>>> cipher.get_iv()
b'ThisWillSetTheIV'
Cipher.set_iv(iv)

Sets the current IV, for modes that use it.

See the LibTomCrypt manual section 3.4.6 for what, precisely, this function will do depending on the chaining mode.

Parameters:iv (bytes) – The current IV.
Raises tomcrypt.Error:
 When the mode does not use IVs.
>>> cipher = aes(b'0123456789abcdef', b'\0' * 16)
>>> cipher.set_iv(b'ThisWillSetTheIV')
>>> cipher.encrypt(b'hello')
b'\xe2\xef\xc5\xe6\x9e'

EAX-Specific Methods

Cipher.add_header(header)

Add the given string to the EAX header. Only for EAX mode.

>>> cipher = aes(b'0123456789abcdef', b'\0' * 16, mode='eax', nonce=b'random')
>>> cipher.add_header(b'a header')
>>> cipher.encrypt(b'hello')
b'Y\x9b\xe5\x87\xcc'
>>> cipher.done()
b'A(|\x9f@I#\x0f\x93\x90Z,\xb5A\x9bN'
>>> cipher = aes(b'0123456789abcdef', b'\0' * 16, mode='eax', nonce=b'random', header=b'a header')
>>> cipher.decrypt(b'Y\x9b\xe5\x87\xcc')
b'hello'
>>> cipher.done()
b'A(|\x9f@I#\x0f\x93\x90Z,\xb5A\x9bN'
Cipher.done()

Return authentication tag for EAX mode.

See Cipher.add_header(...) for example.

Table Of Contents

Previous topic

Development

Next topic

Hash Functions

This Page