Skip to main content

Module frame

Module frame 

Source
Available on crate feature stream only.
Expand description

Wire format for streamed AEAD.

§Header (24 bytes)

  offset | size | field
  -------+------+--------------------------------------------------
   0..8  |  8   | magic = b"\x89CRYPTIO"
   8     |  1   | version = 0x01
   9     |  1   | algorithm (0x00 ChaCha20-Poly1305, 0x01 AES-256-GCM)
   10    |  1   | chunk_size_log2 (default 16 = 64 KiB chunks)
   11..16|  5   | reserved (all zero)
   16..23|  7   | nonce_prefix (random per stream)
   23    |  1   | reserved (zero)

The full 24-byte header is fed as Additional Authenticated Data (AAD) to every chunk. Tampering with the algorithm byte, chunk-size byte, or nonce prefix produces an authentication failure on the first chunk.

§Per-chunk nonce (12 bytes) — STREAM construction

  offset | size | field
  -------+------+--------------------------------------------------
   0..7  |  7   | nonce_prefix (copied from header)
   7..11 |  4   | counter (u32 big-endian, starts at 0)
   11    |  1   | last_flag (0x00 for non-final, 0x01 for final)

The last_flag bit is what defeats truncation attacks. A non-final chunk and the final chunk use different nonces — even if an attacker reads ahead and tries to verify a non-final chunk as final (or vice versa), the GHASH/Poly1305 tag will not match.

§Stream body

  [header (24 B)]
  [chunk_0 (chunk_size + 16 B)]   ── non-final, last_flag = 0
  [chunk_1 (chunk_size + 16 B)]   ── non-final, last_flag = 0
  ...
  [chunk_N-1 (chunk_size + 16 B)] ── non-final, last_flag = 0
  [chunk_N (< chunk_size + 16 B)] ── final, last_flag = 1

The final chunk is always strictly smaller than chunk_size + 16 bytes. If the encryptor’s internal buffer happens to hold exactly chunk_size bytes when finalize is called, it emits the buffered data as a non-final chunk and then a zero-byte final chunk (16 bytes total — just the tag). This makes EOF detection unambiguous: short read → final chunk; full read → non-final.

Constants§

DEFAULT_CHUNK_SIZE_LOG2
Default chunk-size log2 — 16 means 64 KiB chunks.
HEADER_LEN
Header size in bytes.
MAGIC
Magic prefix identifying a crypt-io stream. 8 bytes. The high bit in the first byte (0x89) helps detect binary-as-text mis-handling.
MAX_CHUNK_SIZE_LOG2
Maximum chunk-size log2 — 24 (16 MiB). Above this the buffering memory cost gets uncomfortable for streaming workflows.
MIN_CHUNK_SIZE_LOG2
Minimum chunk-size log2 — 10 (1 KiB). Below this the per-chunk AEAD overhead dominates.
NONCE_LEN
Per-chunk nonce size in bytes (matches both shipped AEADs).
NONCE_PREFIX_LEN
Length of the random nonce prefix carried in the header.
TAG_LEN
AEAD tag size (matches both shipped AEADs).
VERSION
Format version.