Fordan .sec File Format

Version: 1  |  Status: Normative


Overview

A .sec file is a streaming, authenticated-encryption container for a single plaintext file. Files are split into fixed-size chunks; each chunk is independently encrypted and authenticated. The design allows both encryption and decryption to proceed with O(chunk) RAM regardless of the total file size, and makes truncation, chunk reordering, and bit-flips detectable rather than silently tolerated.


Magic Bytes and File Identity

Every .sec file begins with an 8-byte MAGIC sequence:

46 4F 52 44 41 4E 01 00   (ASCII "FORDAN" + 0x01 0x00)

A reader that does not see this exact MAGIC at offset 0 must reject the file immediately with an error.


Header Layout

OffsetSizeFieldDescription
08MAGICFORDAN\x01\x00 — format identity guard
82VERSIONu16 little-endian; current value is 1
101AEAD_ID0x01 = XChaCha20-Poly1305 (default), 0x02 = AES-256-GCM
111KDF_ID0x01 = Argon2id
124CHUNK_SIZEu32 little-endian; plaintext bytes per chunk (default 65536)
164TOTAL_CHUNKSu32 little-endian; total number of chunks
208PLAINTEXT_LENu64 little-endian; exact original file size
284ARGON2_Tu32 little-endian; Argon2 time cost
324ARGON2_Mu32 little-endian; Argon2 memory cost (KiB)
364ARGON2_Pu32 little-endian; Argon2 parallelism
4032SALTRandom 32-byte KDF salt (generated with getrandom)
7232HEADER_BLAKE3BLAKE3 hash of bytes 0..72 (integrity self-check)

Total header size: 104 bytes.


AEAD Algorithms

0x01 — XChaCha20-Poly1305 (default)

0x02 — AES-256-GCM


Key Derivation

The vault key is derived with Argon2id (argon2 crate) from:

Recommended defaults: t=3, m=65536, p=4.


Chunk Body

[ nonce (N bytes) | ciphertext (CHUNK_SIZE or less) | auth tag (16 bytes) ]

Where N = 24 for XChaCha20-Poly1305, N = 12 for AES-256-GCM.

Nonce Construction

nonce[i] = first_N_bytes( BLAKE3( key || chunk_index_as_u64_le ) )

Associated Data

AD[i] = MAGIC || VERSION_u16_le || chunk_index_u32_le || TOTAL_CHUNKS_u32_le

Binding to TOTAL_CHUNKS means a truncated file (missing trailing chunks) will cause the last surviving chunk's AD to fail authentication.


Threat Model and Error Detection

Truncation

A truncated file produces fewer chunks than TOTAL_CHUNKS. The reader counts successfully decrypted chunks and compares to TOTAL_CHUNKS; a shortfall is reported as truncation, not as a valid partial file.

Chunk Reordering

Because each chunk's nonce and AD embed the chunk index and TOTAL_CHUNKS, a reordered chunk will fail AEAD authentication at the position where it is presented.

Bit-Flips and Corruption

Any single-bit change to a chunk's ciphertext or auth tag causes the AEAD decryption to return an authentication failure for that chunk. Fordan treats any auth tag mismatch as a fatal error.


Streaming Decrypt

A compliant decoder:

  1. Reads exactly 104 header bytes; validates MAGIC, VERSION, and HEADER_BLAKE3.
  2. Derives the key from the passphrase and SALT.
  3. For i in 0..TOTAL_CHUNKS:
    1. Reads nonce_len + chunk_ciphertext_len + 16 bytes from the stream.
    2. Reconstructs the nonce from the key and chunk index.
    3. Decrypts and authenticates the chunk; aborts on auth tag failure.
    4. Writes the plaintext bytes to the output stream.
  4. Asserts that the total plaintext bytes written equals PLAINTEXT_LEN.

No seek is required. The decoder allocates one chunk buffer and reuses it for every chunk. Files of arbitrary size are processed with bounded RAM.


Partial Recovery

Fordan does not support partial recovery by design: a vault that cannot be fully verified is treated as corrupt. There is no --skip-bad-chunks flag.


Format Version History

VERSIONChange
1Initial format. XChaCha20-Poly1305 default; AES-256-GCM alternative.