# `SpeckEx.Block`
[🔗](https://github.com/juulSme/SpeckEx/blob/v0.2.0/lib/speck_ex/block.ex#L1)

Low-level block cipher primitives for the Speck cipher.

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

> #### Here be dragons {: .warning}
>
> 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>>

# `variant`

```elixir
@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.

# `decrypt`

```elixir
@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`

```elixir
@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`

```elixir
@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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
