SpeckEx.Block (SpeckEx v0.1.0)

View Source

Low-level block cipher primitives for the Speck cipher.

This module provides generic functions that work with any Speck variant.

Here be dragons

This is a "no guardrails" implementation module of limited practical use. It works with single blocks of data and requires a cipher mode to process anything else. Use the main SpeckEx module unless you know what you are doing.

Supported Variants

  • :speck32_64 - 32-bit block, 64-bit key (4-byte block, 8-byte key)
  • :speck48_72 - 48-bit block, 72-bit key (6-byte block, 9-byte key)
  • :speck48_96 - 48-bit block, 96-bit key (6-byte block, 12-byte key)
  • :speck64_96 - 64-bit block, 96-bit key (8-byte block, 12-byte key)
  • :speck64_128 - 64-bit block, 128-bit key (8-byte block, 16-byte key)
  • :speck96_96 - 96-bit block, 96-bit key (12-byte block, 12-byte key)
  • :speck96_144 - 96-bit block, 144-bit key (12-byte block, 18-byte key)
  • :speck128_128 - 128-bit block, 128-bit key (16-byte block, 16-byte key)
  • :speck128_192 - 128-bit block, 192-bit key (16-byte block, 24-byte key)
  • :speck128_256 - 128-bit block, 256-bit key (16-byte block, 32-byte key)

Usage

# Initialize cipher
iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> is_reference(cipher)
true

# Encrypt a block
iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> ciphertext = SpeckEx.Block.encrypt(<<0::128>>, cipher)
iex> is_binary(ciphertext) and byte_size(ciphertext) == 16
true

# Decrypt a block
iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> ciphertext = SpeckEx.Block.encrypt(<<0::128>>, cipher)
iex> SpeckEx.Block.decrypt(ciphertext, cipher)
<<0::128>>

Summary

Types

All supported Speck block cipher variants. Naming: speck<block_size>_<key_size>, sizes in bits.

Functions

Decrypt a single block using the specified variant.

Encrypt a single block using the specified variant.

Initialize a Speck cipher with the given key and variant.

Types

variant()

@type variant() ::
  :speck32_64
  | :speck48_72
  | :speck48_96
  | :speck64_96
  | :speck64_128
  | :speck96_96
  | :speck96_144
  | :speck128_128
  | :speck128_192
  | :speck128_256

All supported Speck block cipher variants. Naming: speck<block_size>_<key_size>, sizes in bits.

All variants are supported for low-level block cipher operations. However, only variants with 32, 64 and 128-bit block sizes are supported for CTR and AEAD modes.

Functions

decrypt(data, cipher_ref, variant \\ :speck128_256)

@spec decrypt(binary(), reference(), variant()) :: binary()

Decrypt a single block using the specified variant.

Parameters

  • data - A binary of the correct block size for the variant
  • cipher_ref - A cipher reference from init/2
  • variant - The Speck variant (must match the cipher_ref's variant, default :speck128_256)

Returns

The decrypted block as a binary.

Examples

iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> ciphertext = SpeckEx.Block.encrypt(<<0::128>>, cipher)
iex> SpeckEx.Block.decrypt(ciphertext, cipher)
<<0::128>>

encrypt(data, cipher_ref, variant \\ :speck128_256)

@spec encrypt(binary(), reference(), variant()) :: binary()

Encrypt a single block using the specified variant.

Parameters

  • data - A binary of the correct block size for the variant
  • cipher_ref - A cipher reference from init/2
  • variant - The Speck variant (must match the cipher_ref's variant, default :speck128_256)

Returns

The encrypted block as a binary.

Examples

iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> ciphertext = SpeckEx.Block.encrypt(<<0::128>>, cipher)
iex> is_binary(ciphertext) and byte_size(ciphertext) == 16
true

init(key, variant \\ :speck128_256)

@spec init(binary(), variant()) :: reference()

Initialize a Speck cipher with the given key and variant.

Parameters

  • key - A binary of the correct size for the variant
  • variant - The Speck variant to use (default: :speck128_256)

Returns

A cipher reference resource that can be used for encryption/decryption.

Examples

iex> cipher = SpeckEx.Block.init(:crypto.strong_rand_bytes(32))
iex> is_reference(cipher)
true