BL2.ru

Key as a story: encode a key in English sentences

A random key becomes a short story like "Apparently, Margaret painted forty silver lighthouses in Lisbon." It does not look like a key, so it can sit in notes, mail or a folder of documents, and it decodes back to exactly the same bytes. A checksum turns a typo or an autocorrected word into an error instead of a different key.

🔒 Everything is computed in your browser (crypto.getRandomValues, WebCrypto, Argon2id in WebAssembly). Nothing is sent anywhere, and this page does not record even our own anonymous statistics.

⚠ Experimental, format v0. The word lists are not frozen yet: a story made today may not decode in a later version of this page. Do not keep the only copy of an important key as a story for now.

How it works

A story is just another way to write bytes, like hex or the words of a seed phrase. Every sentence has seven word slots: a name (1024 words, 10 bits), a verb in the past tense (512, 9 bits), a number (16, 4 bits), an adjective (1024, 10 bits), a plural noun (1024, 10 bits), a preposition (in, near, outside, beyond, behind, above, below, around: 3 bits) and a place (512, 9 bits). That is 55 bits per sentence. Four sentence patterns take turns so the text does not read like a table: "Margaret painted ...", "Near Oslo, Hugo borrowed ...", "Then ...", "... also ...".

  • The first word, "Apparently", is the format version (v0).
  • Then come 3 bits of length, the bytes themselves, zero padding and a 30-bit RS1024 checksum, the same code as in SLIP-39 Shamir shares (customization string "storykey").
  • 16 bytes take 3 sentences, 32 bytes take 6, and a 77-byte encrypted key file takes 12.

Typos and autocorrect

Case, punctuation, accents and line breaks are ignored, and a short title line before the story is skipped. A word is recognised by its first four letters, so "lighthouse" still means "lighthouses". Every list has unique four-letter prefixes and no look-alikes (no two words one letter apart). An unknown word is reported with its sentence and similar words. If a word is replaced by another valid word (autocorrect, a slip), the checksum does not match: one changed word is always detected, never decoded into another key. The page then suggests a one-word fix, which is a guess to check against your copy.

Encrypting with a passphrase

The story itself is not encrypted: whoever reads it has the key. For protection, encrypt first: the bytes in the story are version (1) + salt (16) + IV (12) + ciphertext and tag, where the key is Argon2id(passphrase, salt) with 64 MiB of memory and 3 passes, and the cipher is AES-256-GCM. There is nothing in clear: no fingerprint, no identifier, no length field, so the bytes look random. A 32-byte key gives exactly 77 bytes, the size of a password vault key file.

Decoy folder

Make N stories from random bytes with the same length, version and a valid checksum, and put the real one among them, each with a random title, like a folder of short stories. The decoys cannot be told apart even by someone who knows this page, because the real story is ciphertext with nothing in clear. Guessing the passphrase now costs N + 1 Argon2id runs per guess: 100 decoys add about 6.7 bits. It is a modest gain; the main protection is still the passphrase. Inside the zip the files are in random order with random dates of the last five years, the real one too, so neither order nor dates point to it; just do not keep a separate copy of the real story next to the folder. Remember the title of the real story, or choose all the files in the "Decrypt" tab and let the page try each one (a second or so per file).

What this is not

  • Not a "brain wallet". The direction is always random bytes to text. There is no way to type your own story or a favourite quote and get a key from it: human text has little entropy, known texts are in dictionaries, and a slow hash does not save it.
  • Not neural steganography. A language model could write smoother text, but decoding would need the same model weights and bit-identical arithmetic. Another GPU, library or model version and the key is gone. Fixed word lists decode the same way forever.

Format v0 is experimental

The word lists will be frozen forever once the format is final: a story has to decode in 20 years. Until then they may change. For a key you cannot afford to lose, keep another backup, for example Shamir shares.

FAQ

Is the story encrypted?
No. A story made in the "Random key" tab is only another way to write the key, like hex: anyone who reads it has the key. Its only protection is that it does not look like a key. For real protection use the "Encrypt with a passphrase" tab: then the story holds Argon2id + AES-256-GCM ciphertext.
What if I mistype a word or the phone autocorrects it?
You get an error, not another key. An unknown word is reported with its sentence and similar words. A replacement by another valid word breaks the 30-bit checksum, and one changed word is always detected. The page then suggests a one-word correction. Case, punctuation and a missing word ending do not matter.
Can I write my own story and turn it into a key?
No, on purpose. That is a "brain wallet": text written by a person has far less entropy than it seems, and quotes, lyrics and books are in attackers' dictionaries. Keys here are always made by crypto.getRandomValues, and the story only records them.
How much does a decoy folder help?
With N decoys an attacker has to run Argon2id N + 1 times for every passphrase guess, because each file has its own salt and nothing marks the real one. 100 decoys add about 6.7 bits, 1000 about 10. It is a real but modest gain: a strong passphrase matters far more.
Why is the format experimental?
The word lists and sentence patterns are version 0 and may still change. After they are frozen, a story will decode forever, and a new list will get a new version word. Until then, do not keep the only copy of an important key as a story.
Is anything sent to a server?
No. Keys, secrets and passphrases stay in your browser, random numbers come from crypto.getRandomValues, and the page does not send even our own anonymous click statistics. On a shared computer, still close the tab afterwards.