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 = 1The 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-iostream. 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.