testdata and wordlists at datekeys-go e671032, with the same testdata:
wordlists/en.txt is the large wordlist of the EFF, 7776 words, CC BY 4.0,
in its order and without the dice numbers. WORD_LIST_SHA256 pins it, and
the alphabet of en is a to z and the hyphen of its four compound words.
/create still offers the Spanish list, and check-build.mjs wants the site
to ship that one alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ -12,6 +12,7 @@ El SHOULD de §38.1, ofrecer palabras al azar de una lista pública, como hace `
- **`wordlist.ts`**, como `wordkey.Generate`, `CheckList` y `Bits` de Go en `27a75ee`, con sus textos: `generateWords` sortea palabras distintas, 7 por defecto, con `crypto.getRandomValues`; `wordBits` da su fuerza, 90 bits para 7 de 7 776; `checkWordList` rechaza una lista de menos de 2 048 palabras, con dos que son una al normalizarlas o con un carácter que no es una letra del alfabeto de su idioma, que da el código y no la lista (para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`); y `readWordList` solo acepta una lista con el SHA-256 fijado para su idioma, que sea UTF-8 y que `checkWordList` acepte. `wordkey.ts` gana `wordRules`, que carga una vez las tablas de Unicode para quien lee muchas palabras.
- **La página `/create`** ofrece palabras al azar por defecto. Con la política «con llave», una casilla abre la cápsula también con unas palabras: al marcarla, la página descarga del propio sitio la lista española (`create-words.ts`, el fichero que Vite publica con un nombre con hash), la acepta solo con su SHA-256 fijado, y sortea 7 palabras que no salen del navegador. Las muestra numeradas, con su fuerza calculada con la lista cargada y un botón para sacar otras. «Las elijo yo» deja escribir las propias, con el aviso de que son más débiles. En los dos casos hay que escribirlas otra vez para comprobar que se tienen; dan igual mayúsculas y tildes. `planCapsule` recibe `wordsKind` (`none`, `random` u `own`) y pide las palabras que falten.
- **Corregido en `/create`:** el efecto que comprueba las rutas escribía `pathCheck` y lo volvía a leer, así que Svelte lo relanzaba sin fin en cuanto se cargaban las reglas, con el primer fichero, comentario o autor: `effect_update_depth_exceeded` en la consola y `checkPaths` repetido sobre toda la lista. Lo lee ahora de una variable local. Venía de `7dc88ef` (1 de octubre) y está en la `0.4.0`.
- **La lista inglesa.**`testdata` y `wordlists` pasan a `e671032` de `datekeys-go`, con el mismo `testdata`: `wordlists/en.txt` es la lista grande de la EFF, de 7 776 palabras, CC BY 4.0, en su orden y sin los números de los dados. `WORD_LIST_SHA256` fija su SHA-256, y el alfabeto de `en` es de la `a` a la `z` y el guion de sus cuatro palabras compuestas, como `t-shirt`. `/create` sigue ofreciendo la española, y `check-build.mjs` exige que la página publique solo esa.
- **`licenses.txt`** lleva el `README.md` de `wordlists/`, con el origen, el método y la licencia de la lista (CC BY-SA 4.0), y `check-build.mjs` exige que esté y que la lista se publique byte a byte.
@ -82,7 +82,7 @@ La inspección (pasos 1 a 8) no importa ninguna dependencia. Funciona en navegad
| `securitycms.ts` | Los veredictos de una firma de `alg` 2, F1, F2, F5 y F6, con cada firmante requerido y ajeno nombrado como el §29.7 del borrador v0.12 (su nombre si cumple las reglas del autor declarado, tiene como mucho 64 puntos de código y no lleva dos espacios seguidos, y si no el SHA-256 del certificado; su emisor, o el SHA-256 de su `Name`; y la autoridad de su sello), y los de un sello, S1 a S5, con su autoridad y t. `encodeSigners` escribe `SIGNERS` para el escritor, ordenado y con los textos de Go | `capsule/signature2.go` |
| `note.ts` | La nota pública (§24.1): la extensión `datekeys.note` de la cabecera, de 1 a 1024 bytes de UTF-8 que cumplen las reglas del autor declarado, con los textos y el orden de `extension.CheckNote`. Una cadena con un sustituto suelto se rechaza: nunca se escribe con U+FFFD. `checkNoteData` comprueba los bytes de una nota en el orden de Go: la longitud, el UTF-8 y las reglas. `publicNote` la lee como Go, con un U+FEFF inicial que la deja inservible, y `unusableNote` distingue una nota inservible de ninguna | `extension` (`CheckNote`, `NewNote`, `Note`), `capsule` (`Header.UnusableNote`) |
| `wordkey.ts` | La llave de palabras (§38.1): `normalizeWords` (NFD con las tablas de Unicode 18.0.0, sin las marcas U+0300 a U+036F, la minúscula simple de cada punto de código, partido por los espacios de la lista), `checkWords` (al menos 6 palabras distintas de 3 letras o más, sin controles, invisibles ni puntos sin asignar), `wordRules` (las dos, con las tablas cargadas una vez) y `wordKey`, PBKDF2-SHA256 de 600 000 rondas de Web Crypto con la sal de la cadena, la ronda y `capsule_id`. `quickWords`, `hiddenCodePoint` y `countedWords` leen con las tablas de la plataforma, para un formulario que no puede esperar a las de Unicode 18.0.0 | `wordkey.Normalize`, `Check`, `Key` |
| `wordlist.ts` | Las palabras al azar de la llave de palabras (el SHOULD de §38.1), con los textos de Go: `generateWords` sortea `DEFAULT_WORD_COUNT` palabras distintas, 7, con `randomIndex` y `crypto.getRandomValues`; `wordBits` da su fuerza, 90 bits para 7 de 7 776; `checkWordList` rechaza una lista de menos de 2 048 palabras, con dos que son una al normalizarlas o con un carácter que no es una letra del alfabeto de su idioma, que da el código y no la lista (para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`): una letra cirílica que parece latina se volvería a escribir con la latina, y la cápsula no se abriría; y `readWordList` solo acepta una lista con el SHA-256 fijado para su idioma en `WORD_LIST_SHA256`, que sea UTF-8 y que `checkWordList` acepte. Ninguna lista se da por buena, tampoco las de DateKeys | `wordkey.Generate`, `CheckList`, `Bits`, `List` |
| `wordlist.ts` | Las palabras al azar de la llave de palabras (el SHOULD de §38.1), con los textos de Go: `generateWords` sortea `DEFAULT_WORD_COUNT` palabras distintas, 7, con `randomIndex` y `crypto.getRandomValues`; `wordBits` da su fuerza, 90 bits para 7 de 7 776; `checkWordList` rechaza una lista de menos de 2 048 palabras, con dos que son una al normalizarlas o con un carácter que no es una letra del alfabeto de su idioma, que da el código y no la lista (para `es`, de la `a` a la `z`, `á`, `é`, `í`, `ó`, `ú`, `ü` y `ñ`; para `en`, de la `a` a la `z` y el guion de las cuatro palabras compuestas de la lista de la EFF): una letra cirílica que parece latina se volvería a escribir con la latina, y la cápsula no se abriría; y `readWordList` solo acepta una lista con el SHA-256 fijado para su idioma en `WORD_LIST_SHA256`, que sea UTF-8 y que `checkWordList` acepte. Ninguna lista se da por buena, tampoco las de DateKeys | `wordkey.Generate`, `CheckList`, `Bits`, `List` |
| `pathrule.ts`, `pathrule-tables.ts` | Las reglas de las rutas y de los textos del head (§29.5, §29.6), de R1 a R10 con R4b, R6b, R6c y R9, NFD, el pliegue y la clave de R7, con los textos de error de Go. Nunca usa `normalize`, `toLowerCase`, `localeCompare`, `Intl` ni las clases `\p{…}`, cuya versión de Unicode cambia con el motor: las tablas de Unicode 18.0.0 y WindowsBestFit las genera `datekeys-go` (`pathrule/gen -ts`), y una prueba recalcula su digest | `internal/pathrule` |
| `open3.ts`, `sink.ts` | El paso 17 del formato 3 en sus subpasos 17.2 a 17.8, con la precedencia de Go: un fallo de `age` o un texto en claro que no mide P prevalecen, manda el primer subpaso que falla, y los códigos distintos de `ERR_INTEGRITY` solo se dan tras leer `PAYLOAD_AGE` hasta el final. `Sink` (`begin`, `create`, `commit`, `abort`) recibe los ficheros y solo los publica en el paso 18; `MemorySink` los guarda en memoria, que crece con los bytes recibidos y nunca con los tamaños que declara el head | `capsule/open3.go` |
| `framing.ts` | Prelude DKC1 (16 bytes), con el formato de la cápsula, de 1 a 3, y DKK1 (12 bytes) en el orden de §23 y §40, longitudes de 1 byte hasta los límites de §57, y troceo de secciones | `capsule/framing.go` |
@ -470,10 +470,10 @@ Comprueba que los ficheros coinciden con `SOURCE.json`, sin faltantes ni sobrant
`.gitattributes` marca `testdata/**` y `wordlists/**` como binarios para que git no altere ningún byte.
Copia actual: la de `testdata/SOURCE.json`, `datekeys-go` en `27a75ee`, de la rama `v0.15` después del tag `spec-v0.15`, que se sincroniza con `node scripts/sync-testdata.mjs sync --commit 27a75ee`. Su `testdata` es el del tag (`fe50885`), que añade `vectors/release.json`, los ficheros de `releases/` y el campo `source` de `mutations.json`; y trae `wordkey/lists`, con la lista española.
Copia actual: la de `testdata/SOURCE.json`, `datekeys-go` en `e671032`, de la rama `v0.15` después del tag `spec-v0.15`, que se sincroniza con `node scripts/sync-testdata.mjs sync --commit e671032`. Su `testdata` es el del tag (`fe50885`), que añade `vectors/release.json`, los ficheros de `releases/` y el campo `source` de `mutations.json`; y trae `wordkey/lists`, con la lista inglesa de la EFF y la española. La página solo publica la española.
## Licencia
Apache-2.0 ([LICENSE](LICENSE)), como la librería Go de referencia. El código que se derive de terceros conserva su aviso de copyright y licencia en el propio fichero: el núcleo IBE (`ibe.ts`), derivado de `tlock-js` (Apache-2.0 OR MIT, usado bajo MIT), y `bech32.ts`, portado de `age` (MIT). El sitio publica esos avisos y los de sus paquetes npm en `licenses.txt`.
Las listas de palabras de `wordlists/` no son código de este proyecto ni tienen su licencia: la española es CC BY-SA 4.0, una adaptación de FrequencyWords de Hermit Dave. Su `README.md`, copiado de `datekeys-go`, dice de dónde sale, cómo se hizo y su licencia.
Las listas de palabras de `wordlists/` no son código de este proyecto ni tienen su licencia: la inglesa es la de la EFF, CC BY 4.0, y la española es CC BY-SA 4.0, una adaptación de FrequencyWords de Hermit Dave. Su `README.md`, copiado de `datekeys-go`, dice de dónde sale, cómo se hizo y su licencia.
@ -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