wordkey/lists/en.txt is the large wordlist for passphrases of the EFF,
7776 words, CC BY 4.0 under its copyright policy, without the dice number
of each line and in its order, so that the position of a word still gives
its dice, 11111 for the first. encrypt -new-words takes it by default, as
the author decided; -dic es takes the Spanish one. The alphabet of en is a
to z and the ASCII hyphen of its four compound words, such as t-shirt,
kept so that no word loses its dice. lists/README.md records its source,
the SHA-256 of the download, the change and the license.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
words:=fs.String("words","","time_and_key: at least 6 words that open the capsule; they stay in the shell history")
wordsFile:=fs.String("words-file","","time_and_key: file with the words that open the capsule")
newWords:=fs.String("new-words","","time_and_key: new file with words drawn at random from a list, that open the capsule")
dic:=fs.String("dic","es","list of -new-words: "+strings.Join(wordkey.Languages(),", "))
dic:=fs.String("dic","en","list of -new-words: "+strings.Join(wordkey.Languages(),", "))
wordCount:=fs.Int("word-count",wordkey.DefaultCount,"number of words of -new-words, 6 or more")
note:=fs.String("note","","public note of the capsule: one line that anyone with the .dkc reads before the date, and that can identify someone with it")
sign:=fs.String("sign","","file with the author key that signs the capsule")
@ -68,7 +68,7 @@ v0.14, and §47.1 and §79, new in v0.15. A case of §64 that is not in the repo
| 36.1 | Authenticity semantics | documented in `README.md`, `SECURITY.md` | — (a property the protocol does not provide) |
| 37 | X25519 recipient V1; the writer rejects a recipient that is not canonical (bit 255 set, or u ≥ p) or of low order, and MAY reject a point of the twist | `age.X25519Recipient`; `agewrap.X25519IdentityFromRaw`, `agewrap.CheckX25519Recipient` (run by `capsule.Encrypt`); the twist check is not implemented | `agewrap.TestRawKeys`, `TestNonCanonicalRecipients`; `capsule.TestEncryptRejectsInvalidOptions` |
| 38 | Portable Access Key | `EncryptOptions.NewPortableKey` (fresh `I_ACCESS` per capsule; no API accepts an existing one); `accesskey.AccessKey` | `capsule.TestPortableKeysAreNeverReused` |
| 38.1 | Key of words: one more X25519 credential of `time_and_key`, among the 16; the normalization: NFD with the tables of Unicode 18.0.0, without U+0300 to U+036F, the simple lower case of each code point, split by the spaces of the list; PBKDF2-HMAC-SHA256 of 600 000 rounds, salted with the chain hash, the round and `capsule_id`, into a raw X25519 identity; the writer requires at least 6 words, counting only different words of 3 or more letters, and refuses controls, ignorables and unassigned code points; a reader may ask for the words instead of a `.dkk`; SHOULD: random words of a public list by default, at least 6 of 2048 or more | `wordkey` (`Normalize`, `Check`, `Key`, `Identity`, `Rounds`, `MinWords`, `MinLetters`; `Generate`, `List`, `CheckList` with the alphabet of each language, `Bits`, `DefaultCount`, `MinListSize`, the list `lists/es.txt`), with `pathrule.NFD`, `Lower`, `DefaultIgnorable` and `Assigned`; `capsule.EncryptOptions.Words` (`accessRecipients`; `sealer.write` derives the identity once `capsule_id` is drawn); `cmd/datekeys`: `-words` and `-words-file` of `encrypt` and `decrypt` (`wordsText`), `-new-words`, `-dic` and `-word-count` of `encrypt`, the words of `decrypt` salted with what `capsule.Inspect` gives | `wordkey.TestNormalize`, `TestCheck`, `TestKeyVector` (the vector of §38.1), `TestBuiltInLists`, `TestCheckList`, `TestGenerate`, `TestBits`, `TestGenerateUniform`; `testdata/vectors/wordkey.json` (`internal/testkit.WordKeyVectors`, `TestVectorFilesAreCurrent`): the words of a text, what a writer refuses and the identities, the cases of §64 of v0.11; `capsule.TestEncryptFilesWords` (the words of another `capsule_id` do not open); `cmd/datekeys.TestKeyOfWords`, `TestNewWords` |
| 38.1 | Key of words: one more X25519 credential of `time_and_key`, among the 16; the normalization: NFD with the tables of Unicode 18.0.0, without U+0300 to U+036F, the simple lower case of each code point, split by the spaces of the list; PBKDF2-HMAC-SHA256 of 600 000 rounds, salted with the chain hash, the round and `capsule_id`, into a raw X25519 identity; the writer requires at least 6 words, counting only different words of 3 or more letters, and refuses controls, ignorables and unassigned code points; a reader may ask for the words instead of a `.dkk`; SHOULD: random words of a public list by default, at least 6 of 2048 or more | `wordkey` (`Normalize`, `Check`, `Key`, `Identity`, `Rounds`, `MinWords`, `MinLetters`; `Generate`, `List`, `CheckList` with the alphabet of each language, `Bits`, `DefaultCount`, `MinListSize`, the lists `lists/en.txt` and`lists/es.txt`), with `pathrule.NFD`, `Lower`, `DefaultIgnorable` and `Assigned`; `capsule.EncryptOptions.Words` (`accessRecipients`; `sealer.write` derives the identity once `capsule_id` is drawn); `cmd/datekeys`: `-words` and `-words-file` of `encrypt` and `decrypt` (`wordsText`), `-new-words`, `-dic` and `-word-count` of `encrypt`, the words of `decrypt` salted with what `capsule.Inspect` gives | `wordkey.TestNormalize`, `TestCheck`, `TestKeyVector` (the vector of §38.1), `TestBuiltInLists`, `TestCheckList`, `TestGenerate`, `TestBits`, `TestGenerateUniform`; `testdata/vectors/wordkey.json` (`internal/testkit.WordKeyVectors`, `TestVectorFilesAreCurrent`): the words of a text, what a writer refuses and the identities, the cases of §64 of v0.11; `capsule.TestEncryptFilesWords` (the words of another `capsule_id` do not open); `cmd/datekeys.TestKeyOfWords`, `TestNewWords` |
| 39 | Recipients of INNER_ACCESS_AGE: in formats 2 and 3 from 1 to 16 credentials, a dummy in each slot left (a fresh public key whose private key is dropped at once), the 16 in a uniformly random order; which slots are dummies is recorded only in the official vectors | `capsule/encrypt.go` (`accessRecipients`, `fillSlots`, `permute`); `agewrap.AccessIdentity` | `capsule.TestInnerHasSixteenStanzas`, `TestDummyRecipients`, `TestStanzaOrderIsUniform`, `TestCredentialBounds`, `TestFixtureRecipients`, `TestEncryptRoundTripBothPolicies`; `TestConformanceFixtures` (the stanza each credential opens, `access_key_stanza` and `identity_stanzas` in the records) |
| 40 | `.dkk` framing; `BODY_LEN` in 1..16 MiB (0 is `ERR_INTEGRITY`); order of the frame checks | `accesskey.Encode`, `accesskey.Decode` (the body buffer grows with the data read; every buffer holding the body is wiped) | `accesskey.TestDecodeRejects`, `TestDecodePrecedence`, `TestDecodeShortBodyAllocatesLittle`, `TestEncodeAndDecodeLeaveNoStaleMaterial`, `FuzzDecode` |
@ -7,8 +7,14 @@ from the normalized text of the words, whatever list they came from.
| List | Words | SHA-256 | Status |
|---|---|---|---|
| `en.txt` | 7776 | `6d557f0693958fb5e650b68b5bee585eb82cf4da32965505c789e924743bc522` | The large wordlist of the EFF, as published |
| `es.txt` | 7776 | `ff77b487765c000da97cca58fe94a2cdb947303e7a07460614d7d95d800034fe` | Draft, not yet reviewed by a native speaker |
Each list has 7776 = 6^5 words, sorted, so that five dice give a word: each
die minus one is a digit of the position of the word in base 6, the first
die the most significant. The dice 11111 give the first word and 66666 the
last, as in the list of the EFF.
A list changes only with its hash in this file and in `generate_test.go`:
an application that downloads a list pins its SHA-256 and refuses any other.
`wordkey.CheckList` checks a list against the alphabet of its language,
@ -18,8 +24,26 @@ typed again with the letter of the keyboard, and the capsule would not open.
| Language | Alphabet |
|---|---|
| `en` | `a` to `z` and the ASCII hyphen of the four compound words of the list of the EFF (`drop-down`, `felt-tip`, `t-shirt` and `yo-yo`), in lower case |
| `es` | `a` to `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` and `ñ`, in lower case and NFC |
## `en.txt`
- **Source:** the large wordlist for passphrases of the Electronic Frontier