AeroVault wrapper-stack and cryptography (design home) #4
Replies: 3 comments 3 replies
|
A few of the core diagrams from the design conversation (axpdev-lab/aeroftp#276), kept here in the format's home so the picture lives next to the spec. Write pipelineThe full write path. Files are packed and split by content-defined chunking, each chunk is compressed with zstd, then encrypted with AES-256-GCM-SIV, and error correction is applied last, over the ciphertext. Chunking comes before compression on purpose: it is what keeps deduplication, resume, and random per-file extraction working. AEROVAULT3 container formatThe container on disk: a fixed 1024-byte header, then the encrypted chunk blocks, the encrypted manifest, and the extension directory and payloads that carry the optional v4 error-correction data. The data section starts immediately after the header, so the manifest can grow or be rebuilt without shifting the encrypted blocks. Where error correction sitsError correction is the last wrapper, sitting on top of the already-encrypted bytes, so it never has to decode the format. That is what lets one parity format protect a Full set and the original discussion are in axpdev-lab/aeroftp#276. Parity placement (detached by default)Where the error-correction parity lives is a choice. By default v4 is just v3 plus a detached |
|
I thought of another way of framing the differences in the file formats: |
|
Regarding the banner, please consider rephrasing it as "Military-grade encrypted container" or a similar description. |




Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This is the design home for the AeroVault format on its own repo. The original, long-form design conversation lived on the AeroFTP repo and shaped both the v3 architecture and the spec; this thread carries the settled decisions forward here, where the format now lives. Full history:
The wrapper-versus-step taxonomy, the small-file-packing model, the chunking trade analysis, and the algorithm-versioning clause are a sustained community design contribution by @EhudKirsh. The spec credits this explicitly.
Settled design
Write pipeline (v3 container), canonical order:
The order is deliberate, not incidental:
Container on-disk layout. All multi-byte integers are little-endian. The data section starts immediately after the header, so a writer can rebuild the header and manifest without shifting the data blocks.
Error Correction placement. One unified detached format,
.aerocorrect, content-SHA bound, shared byte-for-byte between the app and the standaloneaerovaultcrate (pinned by a cross-implementation fixture). Detached is the default placement, so the encrypted container stays byte-identical to a plain v3.embeddedandbothare opt-in. Why detached is the default, and the header/manifest chicken-and-egg that makes it the resilient choice, is discussed in #3.The detached sidecar writes three windows over the container, in a fixed order, so each region's parity is found by position:
This is exactly why detached recovers a damaged header or manifest while embedded cannot: those two regions cannot self-locate their own recovery once corrupted (chicken-and-egg), so they have to travel outside the container.
The
.aerocorrecton-disk layout: a small prefix, the locator stored in triplicate with per-copy checksums (so a lightly corrupted sidecar self-heals), and the parity region of concatenated AVEC Reed-Solomon payloads. The content-SHA binding is informational on repair; every rebuilt region is re-verified against the vault's authenticated values (header MAC / manifest cipher_hash) before it replaces the original.Bit-rot. The corruption error correction guards against is commonly called bit-rot. Because the content is encrypted, the stored bytes have to be exact to decrypt: a single flipped bit in a chunk (a parity-byte failure) would otherwise make that block, and anything chained after it, unrecoverable. Reed-Solomon parity is what repairs those bit-rot failures, on the ciphertext, before anything is decrypted.
Overhead levels. Low / Medium / Quartile / High, or a raw percentage; recorded on the manifest and read back from the AVEC payload, so reconstruction works regardless of the level a vault was created with.
Cryptography. AES-256-GCM-SIV content AEAD (nonce-misuse-resistant), Argon2id (128 MiB) KDF, AES-256-KW key wrapping, optional ChaCha20-Poly1305 cascade, HKDF-SHA256 key separation, HMAC-SHA512 header MAC. The per-file 16-byte
file_idplus chunk index/count is carried as AAD, so a chunk cannot be spliced across files or reordered.Versioning, three independent axes. Container on-disk major (AEROVAULT2 / AEROVAULT3), container product revision (rev. 3 vs rev. 4 once EC is added; on-disk major stays 3), and the crate semver. A plain v3 reader opens a v4 container and skips the non-critical EC extension.
Spec: AEROVAULT-V3-SPEC.md (pipeline in section 2), AEROCORRECT-SPEC.md, AEROVAULT-V2-SPEC.md. Crate: docs.rs/aerovault · crates.io/aerovault.
Use this thread for format-level design questions going forward.
All reactions