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-GCMccm()/ccm_with_sizes()for AES-CCMchacha20_poly1305()for ChaCha20-Poly1305xchacha20_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 usenonce: The nonce used during encryptiontag: The authentication tag from encryptionciphertext: 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 usenonce: The nonce used during encryption (must be non-empty)tag: The authentication tag from encryptionciphertext: The encrypted dataadditional_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 usenonce: A unique nonce (must be exactlynonce_sizebytes). 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 usenonce: A unique nonce (must be exactlynonce_sizebytes and non-empty)plaintext: The data to encryptadditional_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.