The Deniability Problem
Standard encryption proves a message exists. Under coercion, possessing an encrypted file is itself incriminating. An adversary who compels you to surrender your passphrase gains the message — and knows there's nothing else to find.
Deniable encryption solves this: one container holds two independent encrypted messages at different offsets. You reveal the decoy passphrase. The adversary gets a plausible message. The real message remains undetectable — the rest of the container is indistinguishable from random padding.
The Two-Passphrase Model
Each passphrase independently derives an encryption key, a nonce, and a slot offset via Argon2id. The real passphrase decrypts the real message. The decoy passphrase decrypts the decoy. Without both passphrases, there is no way to prove two messages exist — or even that the container holds any message at all.
Why Argon2id Is Load-Bearing
Argon2id is not incidental — it is the security foundation. Without memory-hard key derivation, the deniability model collapses: an attacker who can brute-force both passphrases simultaneously recovers both offsets and both messages.
Argon2id with high memory parameters (64MB+ per derivation, per RFC 9106) makes simultaneous brute-force computationally hopeless. The cost scales per passphrase attempt — attacking two passphrases is twice as expensive.
Container Format
The container is a fixed-size block of bytes. It begins as entirely random (CSPRNG). Two encrypted message slots are written at derived offsets, overwriting random bytes. The result: no headers, no magic bytes, no length fields, no structure detectable by forensic analysis. The entire container looks like random data.
Passphrase → Argon2id(64B) → key[0..31] + nonce[32..43] + offset[44..47] → ChaCha20-Poly1305 AEAD
What This Cannot Protect Against
- Implementation bugs in this demonstration code
- Keyloggers or compromised devices capturing passphrases
- Coercion with violence (rubber-hose cryptanalysis)
- Metadata outside the container (filenames, timestamps, access logs)
- Browser memory not being securely wiped (passphrases enter as JS strings)
- Weak passphrases — deniability collapses if either passphrase can be brute-forced
Honest Limitations
Shadow Vault is a demonstration of deniable encryption concepts, not production-grade deniable storage. Browser-based cryptography is inherently weaker than native tools. Strong, unique passphrases are required for both messages — deniability depends on the attacker being unable to brute-force either one. For real-world deniable encryption, use VeraCrypt with hidden volumes.