Security architecture · last updated 16 Jun 2026
Exactly how Farewell protects your data.
Below are the precise algorithms, parameters, and on-disk format Farewell uses.
Design principles
- Standard primitives only. No home-grown cryptography — AES-GCM-SIV, Argon2id, BLAKE3, Ed25519, ML-DSA-87, all from well-reviewed implementations.
- Offline by construction. The app opens no socket — no accounts, no sync, no telemetry. Nothing to intercept, nothing to subpoena from a server.
- No recovery, no backdoor. The passphrase (and optional hardware key) is the only way in. We cannot reset it, and neither can anyone who compels us.
- Apart from the random salt, every remaining byte is computationally indistinguishable from random data without the correct passphrase. A vault file carries no magic bytes, version, or algorithm identifier in cleartext. The only plaintext is a 32-byte random salt.
Encryption at rest
All vault contents are sealed with AES-256-GCM-SIV, an authenticated cipher (AEAD). GCM-SIV is chosen over plain AES-GCM for nonce-misuse resistance: even if a nonce were ever reused, it does not catastrophically leak the key or plaintext relationships the way GCM does.
| Cipher | AES-256-GCM-SIV (RFC 8452) |
| Key size | 256 bits |
| Nonce | 96 bits (12 bytes) |
| Auth tag | 128 bits (16 bytes) |
| Associated data | bound per record (position-tied, prevents reordering) |
File contents are split into 64 KiB chunks; each chunk is encrypted independently with its own key derived from the master key via BLAKE3, so random access never requires decrypting the whole vault, and chunks can't be swapped between positions.
Key derivation (passphrase)
Your passphrase is stretched into a key with Argon2id — the memory-hard KDF recommended for password hashing — making offline guessing ruinously expensive.
| Algorithm | Argon2id, version 1.3 (0x13) |
| Memory cost | 1 GiB (1 048 576 KiB) |
| Iterations (t) | 4 |
| Parallelism (p) | 4 lanes |
| Output | 32 bytes (256-bit key) |
| Salt | 32 random bytes, unique per vault |
| Cost | ≈ 2 s on Apple silicon (M2) |
Hardware-key vaults use a lighter KDF on purpose. When a vault is bound to a FIDO2 key, the key's hardware secret — not the passphrase — carries the brute-force resistance, so a copied file is uncrackable without the physical key regardless of KDF cost. The chosen profile is not stored on disk (that would be a fingerprint); on open, Farewell simply tries the candidates in order.
Hashing & sub-keys
BLAKE3 (256-bit) is used for integrity hashing, as a keyed MAC, and to derive per-chunk sub-keys from the master key via its derive_key context mechanism.
Post-quantum posture
Your content is protected by a 256-bit symmetric key, which remains far beyond the reach of foreseeable quantum attacks. It is sealed with 256-bit AES-256-GCM-SIV; the best known quantum attack (Grover) only halves that to ~128-bit effective security — out of reach. And because a local vault is unlocked symmetrically from your passphrase (no public-key step), there is nothing for Shor's algorithm to attack.
The integrity stamp survives independently of your passphrase, but the signing key does not.
For defence in depth, each vault is stamped at creation with a one-shot ML-DSA-87 signature (NIST FIPS 204, the post-quantum signature standard) over its fixed metadata (format version, capacity, salt, and the verifying key).
“Where is the private signing key?” Nowhere — by design. The signing key is ephemeral: a fresh keypair is generated at creation, used once to sign, then the secret key is wiped from memory immediately. It is never written to disk, never reused, and lives nowhere afterwards — there is no signing key to steal, leak, or be compelled to produce. Only the verifying key (public by nature) and the signature remain, and they live inside the AEAD-encrypted metadata.
The vault’s confidentiality and authenticity rest on the AEAD plus your passphrase or hardware key: the metadata cannot be read or altered without them. The ML-DSA-87 stamp sits on top of that as an independent, algorithm-diverse integrity check, and yields a stable per-vault fingerprint (a hash of the verifying key) you can record and re-check.
“If the verifying key ships inside the very blob it signs, what does the signature buy?” Once an attacker possesses the vault key, confidentiality and integrity are already compromised; the signature is not intended to defend against that scenario, so we don't claim it adds third-party authenticity (the AEAD + your passphrase do that). Its honest value is narrower and threefold: (1) algorithm diversity — an independent post-quantum check over the metadata that would catch a fault in the AES-GCM-SIV path the GCM tag itself missed; (2) a stable, verifiable fingerprint for the vault; (3) a forward-compatible slot — the same field is built to carry a non-ephemeral signer (a release- or device-bound key) in a later version, which would add third-party authenticity, with no format break. Today's ephemeral form is that machinery in its simplest case.
| Content cipher | AES-256-GCM-SIV — 256-bit, Grover-safe |
| Integrity signature | ML-DSA-87 (FIPS 204), one-shot per vault |
| Signing key | ephemeral — generated at creation, then destroyed |
| Verifying key / signature | 2592 B / 4627 B (stored inside the encrypted metadata) |
| Implementation | libcrux (formally verified) |
Vault format (v6)
A vault is a single fixed-layout file. Apart from the leading random salt, every byte is ciphertext or random padding — there are no headers or markers that would identify it as a Farewell vault.
# on-disk layout — nothing in cleartext except the salt
[0 .. 32) salt 32 bytes, uniform random (plaintext)
[32 .. 4128) slot 4096 bytes — AEAD-wrapped master key,
or random padding (deniable)
[4128 .. +blob) metadata AEAD blob: chunk count + the one-shot
ML-DSA-87 attestation
[.. .. EOF) chunks 64 KiB plaintext each, stored as
12-byte nonce + ciphertext + 4 + 16-byte tag
| Format version | v6 (0x0006) — not written in cleartext |
| Master key | 256-bit, AEAD-wrapped in the slot |
| Hardware keys | up to 3 FIDO2 keys per vault (any one opens it) |
| Chunk plaintext | 65 536 bytes (64 KiB) |
| Auto-wipe | none — see below |
There is deliberately no “wipe after N failures” feature: a counter that updates on a wrong passphrase would have to live outside passphrase-gated encryption, making the file detectable — incompatible with byte-level deniability, and useless against an adversary who imaged the disk first. Offline-guessing resistance rests on Argon2id + passphrase entropy (and the optional hardware key) instead.
In-memory key hygiene
Keys exist in RAM only while a vault is open. Farewell bounds and scrubs that exposure with the standard defences — and is honest about the line past which no user-space program can reach.
| Live master key | held in an mlock-pinned buffer (SecureBuffer) |
| Anti-swap | mlock(2) — key pages aren't written to swap (best-effort) |
| On lock / drop | zeroized: master key, derived keys, AEAD keys |
| Transient secrets | passphrase & wrapping keys wiped immediately after use |
| Wipe primitive | zeroize crate — volatile writes + compiler fence |
“How do you verify the wipe is effective?” The part that can be guaranteed is at the compiler level: the zeroize crate overwrites secrets with volatile writes plus a compiler fence, so the optimizer cannot quietly drop the zeroing the way it can with a naïve memset on memory that's about to be freed. That crate is widely used and audited, and you can confirm it by reading the source. Keys are also mlocked, so they never reach swap where they would outlive the process. What no user-space program can fully guarantee is the rest of the machine — a hibernation image, kernel page copies, CPU registers and stack spills, or the passphrase as it briefly transits the OS text field and USB stack. We mitigate (mlock against swap, zeroize-on-drop, auto-lock to shrink the window) and we disclose the limit rather than claim a perfection no one can deliver.
And we test it, in CI. A regression test seeds a key buffer with a known sentinel, drops it, and asserts the backing store is all-zero afterwards. To do this soundly — reading freed memory would itself be undefined behaviour — the snapshot is taken from inside the allocator's dealloc, while the memory is still live, and it watches one specific allocation rather than scanning the whole heap (so there are no false positives from transient copies). Removing the wipe makes the test fail immediately, so a future change can't silently drop it. This guards the part that's actually at risk — a key copy escaping the buffer, or a missing wipe — not the OS-level limits above, which no test can reach.
What Farewell deliberately does not do
- No network connection of any kind — no telemetry, no license server, no “phone home”.
- No passphrase recovery, master key, or escrow.
- No plaintext metadata, filenames, or sizes leaked on disk.
- No decrypted copies written to disk while you view files.
Threat model
Encryption is only as useful as the threats it actually addresses. Here is the honest scope — what Farewell is built to defeat, and what it cannot.
What it protects
- Data at rest. A locked vault is unintelligible without your passphrase (and hardware key, if you set one).
- Offline theft or seizure of the file. A stolen laptop, an imaged disk, a copied USB stick, a cloud backup of the vault — all useless to whoever holds them.
- Tampering. Any modification to the file is detected on open (AEAD authentication).
- “Harvest now, decrypt later.” Content is sealed with a 256-bit symmetric key, beyond the reach of any foreseeable quantum attack.
- Compelled disclosure from us. There is no recovery key, no server, no backdoor — nothing we can be forced to hand over.
What it does not protect
- An unlocked vault. Once open, its contents are in the clear for that session — anyone at your unlocked machine sees what you see.
- Malware running under your account. Code with your privileges can read what you can read; encryption can't fence off your own user.
- Screen capture and keyloggers. A compromised OS, keyboard, or screen recorder captures your passphrase and your plaintext as you type and view them.
- A machine compromised while in use. mlock and zeroize raise the bar against cold-boot and swap forensics, but a live, rooted system is out of scope.
- Coercion of you. Farewell helps you avoid revealing that a vault exists; it is a mitigation, not a guarantee against an adversary who can compel you.
The short version: Farewell protects the file, not the live machine. Keep the vault locked when you're not using it, and run it on a device you trust.
Questions or want to scrutinize the cryptography? Write to security@farewell.pro.