kryptos/aead

Authenticated Encryption with Associated Data (AEAD).

AEAD provides both confidentiality and integrity for data, with optional authenticated additional data (AAD) that is integrity-protected but not encrypted.

Example

import kryptos/aead
import kryptos/block
import kryptos/crypto

let assert Ok(cipher) = block.aes_256(crypto.random_bytes(32))
let ctx = aead.gcm(cipher)
let nonce = crypto.random_bytes(aead.nonce_size(ctx))
let assert Ok(#(ciphertext, tag)) = aead.seal(ctx, nonce:, plaintext: <<"secret":utf8>>)

Types

AEAD context with its configuration.

Use the provided constructor functions to create contexts:

  • gcm() / gcm_with_nonce_size() for AES-GCM
  • ccm() / ccm_with_sizes() for AES-CCM
  • chacha20_poly1305() for ChaCha20-Poly1305
  • xchacha20_poly1305() for XChaCha20-Poly1305
pub opaque type AeadContext

Values

pub fn ccm(cipher: block.BlockCipher) -> AeadContext

Creates an AES-CCM context with the given block cipher.

Uses standard parameters: 16-byte (128-bit) authentication tag and 13-byte (104-bit) nonce, which allows messages up to 64KB.

Parameters

  • cipher: The AES block cipher (128, 192, or 256 bit)

Returns

An AES-CCM context ready for encryption or decryption.

pub fn ccm_with_sizes(
  cipher: block.BlockCipher,
  nonce_size nonce_size: Int,
  tag_size tag_size: Int,
) -> Result(AeadContext, Nil)

Creates an AES-CCM context with custom nonce and tag sizes.

CCM allows flexible nonce and tag sizes per RFC 3610:

  • Nonce size affects maximum message length (larger nonce = smaller max message)
  • Tag size affects authentication strength (larger tag = stronger)

Parameters

  • cipher: The AES block cipher (128, 192, or 256 bit)
  • nonce_size: Nonce size in bytes (7-13)
  • tag_size: Authentication tag size in bytes (4, 6, 8, 10, 12, 14, or 16)

Returns

Ok(AeadContext) if the sizes are valid, Error(Nil) if any size is out of range.

pub fn chacha20_poly1305(
  key: BitArray,
) -> Result(AeadContext, Nil)

Creates a ChaCha20-Poly1305 AEAD context with the given key.

Uses standard parameters per RFC 8439: 12-byte (96-bit) nonce and 16-byte (128-bit) authentication tag.

Parameters

  • key: A 32-byte (256-bit) key

Returns

Ok(AeadContext) if the key is exactly 32 bytes, Error(Nil) if the key size is incorrect.

pub fn gcm(cipher: block.BlockCipher) -> AeadContext

Creates an AES-GCM context with the given block cipher.

Uses standard parameters: 16-byte (128-bit) authentication tag and 12-byte (96-bit) nonce.

Note: This library only supports the full 16-byte authentication tag. Truncated tags (as permitted by NIST SP 800-38D) are not supported due to their reduced security guarantees.

Parameters

  • cipher: The AES block cipher (128, 192, or 256 bit)

Returns

An AES-GCM context ready for encryption or decryption.

pub fn gcm_with_nonce_size(
  cipher: block.BlockCipher,
  nonce_size: Int,
) -> Result(AeadContext, Nil)

Creates an AES-GCM context with a custom nonce size.

GCM supports variable nonce sizes, though 12 bytes is strongly recommended. This function is primarily useful for compatibility testing with test vectors.

Parameters

  • cipher: The AES block cipher (128, 192, or 256 bit)
  • nonce_size: The nonce size in bytes (1-64)

Returns

Ok(AeadContext) if the nonce size is valid, Error(Nil) if the nonce size is out of range.

pub fn nonce_size(ctx: AeadContext) -> Int

Returns the required nonce size in bytes for an AEAD context.

Parameters

  • ctx: The AEAD context

Returns

The nonce size in bytes. Default 12 for GCM (configurable 1-64 via gcm_with_nonce_size), 13 for CCM (configurable 7-13 via ccm_with_sizes), 12 for ChaCha20-Poly1305, or 24 for XChaCha20-Poly1305.

pub fn open(
  ctx: AeadContext,
  nonce nonce: BitArray,
  tag tag: BitArray,
  ciphertext ciphertext: BitArray,
) -> Result(BitArray, Nil)

Decrypts and verifies AEAD-encrypted data.

Parameters

  • ctx: The AEAD context to use
  • nonce: The nonce used during encryption
  • tag: The authentication tag from encryption
  • ciphertext: The encrypted data

Returns

Ok(plaintext) if authentication succeeds, Error(Nil) if authentication fails or nonce size is incorrect.

Example

import kryptos/aead
import kryptos/block
import kryptos/crypto

let assert Ok(cipher) = block.aes_256(crypto.random_bytes(32))
let ctx = aead.gcm(cipher)
let nonce = crypto.random_bytes(aead.nonce_size(ctx))
let assert Ok(#(ciphertext, tag)) = aead.seal(ctx, nonce:, plaintext: <<"secret":utf8>>)
let assert Ok(plaintext) = aead.open(ctx, nonce:, tag:, ciphertext:)
pub fn open_with_aad(
  ctx: AeadContext,
  nonce nonce: BitArray,
  tag tag: BitArray,
  ciphertext ciphertext: BitArray,
  additional_data aad: BitArray,
) -> Result(BitArray, Nil)

Decrypts and verifies AEAD-encrypted data with additional authenticated data.

The AAD must match exactly what was provided during encryption.

Parameters

  • ctx: The AEAD context to use
  • nonce: The nonce used during encryption (must be non-empty)
  • tag: The authentication tag from encryption
  • ciphertext: The encrypted data
  • additional_data: The same AAD used during encryption

Returns

Ok(plaintext) if authentication succeeds, Error(Nil) if authentication fails, AAD mismatch, or nonce size is incorrect/empty.

Example

import kryptos/aead
import kryptos/block
import kryptos/crypto

let assert Ok(cipher) = block.aes_256(crypto.random_bytes(32))
let ctx = aead.gcm(cipher)
let nonce = crypto.random_bytes(aead.nonce_size(ctx))
let aad = <<"header":utf8>>
let assert Ok(#(ciphertext, tag)) =
  aead.seal_with_aad(ctx, nonce:, plaintext: <<"secret":utf8>>, additional_data: aad)
let assert Ok(plaintext) =
  aead.open_with_aad(ctx, nonce:, tag:, ciphertext:, additional_data: aad)
pub fn seal(
  ctx: AeadContext,
  nonce nonce: BitArray,
  plaintext plaintext: BitArray,
) -> Result(#(BitArray, BitArray), Nil)

Encrypts and authenticates plaintext using AEAD.

Parameters

  • ctx: The AEAD context to use
  • nonce: A unique nonce (must be exactly nonce_size bytes). Never reuse a nonce with the same key.
  • plaintext: The data to encrypt

Returns

Ok(#(ciphertext, tag)) with the encrypted data and authentication tag, or Error(Nil) if the nonce size is incorrect.

pub fn seal_with_aad(
  ctx: AeadContext,
  nonce nonce: BitArray,
  plaintext plaintext: BitArray,
  additional_data aad: BitArray,
) -> Result(#(BitArray, BitArray), Nil)

Encrypts and authenticates plaintext with additional authenticated data.

The AAD is authenticated but not encrypted. It can be used for headers, metadata, or context that should be tamper-proof but remain readable.

Parameters

  • ctx: The AEAD context to use
  • nonce: A unique nonce (must be exactly nonce_size bytes and non-empty)
  • plaintext: The data to encrypt
  • additional_data: Data to authenticate but not encrypt

Returns

Ok(#(ciphertext, tag)) with the encrypted data and authentication tag, or Error(Nil) if the nonce size is incorrect or empty.

pub fn tag_size(ctx: AeadContext) -> Int

Returns the authentication tag size in bytes for an AEAD context.

Parameters

  • ctx: The AEAD context

Returns

The tag size in bytes. 16 for GCM, ChaCha20-Poly1305, and XChaCha20-Poly1305. Configurable 4-16 (even values) for CCM via ccm_with_sizes.

pub fn xchacha20_poly1305(
  key: BitArray,
) -> Result(AeadContext, Nil)

Creates an XChaCha20-Poly1305 AEAD context with the given key.

Uses extended parameters: 24-byte (192-bit) nonce and 16-byte (128-bit) authentication tag. The extended nonce provides better collision resistance when generating random nonces.

Parameters

  • key: A 32-byte (256-bit) key

Returns

Ok(AeadContext) if the key is exactly 32 bytes, Error(Nil) if the key size is incorrect.

Search Document