The maths checks out.
Every claim deny.sh makes is backed by a cryptographic verification suite. These aren't unit tests. They're statistical proofs.
Statistical Indistinguishability
Can anyone tell the difference between a real control file and a deniable one? We generated 1,000 deniable control files and ran every standard randomness test against them. The answer is no.
Ciphertext Invariance
The encrypted file never changes. Creating a deniable control file is a pure mathematical operation on the control data, not on the ciphertext. We verified this across 50 consecutive deny operations.
Length Independence
The ciphertext doesn't reveal how long the real message is. The 4-byte length prefix is inside the encrypted zone, so different control files produce different lengths. An attacker can't determine the real message length from the ciphertext.
Cross-implementation
The browser engine and the server engine produce identical output. Hex-mode round-trips work across implementations, including unicode.
Known-Answer Tests
Deterministic inputs produce deterministic outputs. The key derivation function is verified to be sensitive to every input: password order, salt value, and individual password changes all produce different keys.
Fuzz Testing
500 rounds of random messages (1-200 bytes), random passwords, random control data. Every round: encrypt, decrypt, generate deniable control, decrypt with fake control. Plus all 256 possible single-byte values tested individually.
Security Properties
The encryption is non-deterministic (random salt per call), wrong passwords produce garbage rather than errors, and different control files for the same ciphertext are uncorrelated.
Multiple Deniable Messages
One ciphertext. One pair of passwords. 100 different control files. 100 different decrypted messages. The original still works after all 100 denials.
What this proves.
"Mathematically indistinguishable"
Chi-squared 99.6% pass rate. Entropy within 0.19 bits of truly random data. No statistical test can tell a real control file from a deniable one.
"No metadata leak"
Length prefix hidden inside encrypted zone. Ciphertext invariant across deny operations. No side channels.
"Unlimited deniability"
100 fake messages generated from one ciphertext, all verified correct. The only limit is that decoys must be the same length or shorter than the original.
"Zero failures"
500 fuzz rounds with random inputs. 256 single-byte edge cases. Every permutation of encrypt, deny, and decrypt succeeded.
Run it yourself.
The verification suite is open source. Clone the repo, run the tests, verify every claim independently.
# clone
$ git clone https://github.com/deny-sh/deny-sh
$ cd deny-sh
# install + build
$ npm install && npm run build
# run the full verification suite
$ node run-verification.mjs
Last run: 1 April 2026 00:24 UTC / Node.js v22.22.2 / Linux x64