← Back to blog

What the decoy realism engine generates

June 2026 · 5 min read

A decoy only works if it survives inspection. A coercer who holds your ciphertext and types a wrong password should see something that looks exactly like a real secret of the kind you'd plausibly be hiding, not random noise that announces there is more here. So the bar for a decoy is precise: it has to be shape-correct, and where the real thing carries a checksum, the fake has to pass it too.

The realism engine generates decoys across 69 credential types, each one validator-gated before it leaves the engine. The categories span most of what production systems actually hold.

Cloud, API & infrastructure (32)
Stripe, GitHub, OpenAI, Anthropic, AWS, GCP, Azure, Slack, Discord, Twilio, SendGrid, npm, PyPI, GitLab, Cloudflare, plus PEM private keys, JWTs and database connection URIs.
Crypto wallets (4)
BIP39 seed phrases, Ethereum and Solana private keys, Bitcoin WIF keys, each passing its own checksum (BIP39 word checksum, Base58Check).
Healthcare (5)
UK NHS numbers (Modulus 11), US NPI (Luhn), DEA numbers, Medicare MBIs, NDC product codes.
Finance & securities (10)
IBANs (mod-97), credit cards (Luhn), LEIs, ISINs, CUSIPs, EINs, DUNS, US routing and account numbers, BIC/SWIFT codes.
Government & identity (8)
US SSNs, UK NI numbers, ITINs, passport MRZ lines, US passports, USCIS numbers, India Aadhaar (Verhoeff), eIDAS identifiers.
Network, device & contact (8)
Email addresses, E.164 phone numbers, IPv4 and IPv6 addresses, MAC addresses, IMEIs (Luhn), VINs, UUIDs.

Shape is not enough

Twenty-five of these types carry a hard deterministic validator. The engine doesn't just match a shape, it runs the same checksum a real value passes (Luhn, mod-97, Verhoeff, Base58Check, NHS Modulus 11, and more) and rejects any candidate that fails. The rest are shape-locked by prefix, length, and character-class rules. Either way, what comes out is something an attacker would have to do real forensic work to doubt.

A static pool of pre-written decoys would itself be a fingerprint: generate the same fake wallet twice and the second one is recognisable. So the engine returns different bytes every time, seeded so the output is stable per record but never repeats across records.

Honey Mode

Honey Mode takes this one step further. On 63 of the 69 types, a wrong password doesn't return a decryption failure, it returns a deterministic, type-correct fake, derived only from the wrong-password output and a public salt. The same wrong password always returns the same value, so an attacker who retries can't catch it shifting, and the fake leaks nothing about the real secret.

Six types are deliberately refused: the two unstructured catch-alls (generic, freeform-secret) and four whose output is a JSON blob or multi-branch URI that can't yet be reproduced byte-identically across every SDK. Data with no fixed shape has nothing to fake, so we don't pretend it does.

The same bytes everywhere

All of it lives in every reference SDK: TypeScript, Rust, Python, Go. The generation is byte-identical across all four, so a decoy generated in one verifies in another. The full type list, with live samples you can regenerate on click, is on the tools page.

One ciphertext. Multiple plausible plaintexts.

No account. No tracking. Everything in your browser.

Try the encryptor
// read next
The decoy realism engine
How the engine produces decoys you couldn't write yourself
Why deniable encryption matters
One ciphertext, two valid decryptions, and where it applies