Testdata, wordlists and annex at spec-v0.16 of datekeys-go

The author approved specification v0.16 on 7 October 2026, tagged
spec-v0.16 at b6ff17a. Only the annex changes, with the SHA-256 of the
approved text, and so does its generated constant, and the README of
testdata; the README and the CHANGELOG name the approved version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.16
dev 7 hours ago
parent 0609e9edcc
commit b53afdcb3e

@ -4,9 +4,9 @@ Cambios notables de la librería Dart. El proyecto usa versionado semántico; mi
## Especificación 0.16, en la rama `v0.16` — sin versión
### El borrador v0.16 (07-10-2026)
### La v0.16 (07-10-2026)
- `datekeys-go` escribe en la rama `v0.16`, de `70d907b` a `3fd0e93`, el borrador v0.16, todavía sin aprobar, con la revisión de Astra de la v0.15. La librería lo porta de `4f78854` en la rama `v0.16`, desde `e2296b0` de la `v0.15`. `specVersion` pasa a `0.16`, y `testdata`, `wordlists` y `annex` se sincronizan con `3fd0e93`, que devuelve sus escapes a los vectores del JSON de drand y cambia el SHA-256 de la especificación en el anexo: 150 ficheros en `testdata`, con el campo `spec` de cada uno, los dos fixtures nuevos, `security_cms.json` hecho otra vez, los casos nuevos de `release.json` y de `wordkey.json`, y el anexo de recuperación del borrador, que `tool/recovery_annex_copy.dart` vuelve a escribir en `lib/src/recovery_annex.g.dart`.
- `datekeys-go` escribe en la rama `v0.16`, de `70d907b` a `b6ff17a`, la v0.16, aprobada el 7 de octubre de 2026 con el tag `spec-v0.16`, con la revisión de Astra de la v0.15. La librería lo porta de `4f78854` en la rama `v0.16`, desde `e2296b0` de la `v0.15`. `specVersion` pasa a `0.16`, y `testdata`, `wordlists` y `annex` se sincronizan con `b6ff17a`, el commit del tag, cuyo anexo lleva el SHA-256 de la versión aprobada; antes, `3fd0e93` devolvió sus escapes a los vectores del JSON de drand y cambió el SHA-256 de la especificación en el anexo: 150 ficheros en `testdata`, con el campo `spec` de cada uno, los dos fixtures nuevos, `security_cms.json` hecho otra vez, los casos nuevos de `release.json` y de `wordkey.json`, y el anexo de recuperación del borrador, que `tool/recovery_annex_copy.dart` vuelve a escribir en `lib/src/recovery_annex.g.dart`.
- **Un sello sin precisión no prueba la fecha (§29.7, §29.11),** como `7e3b810` de Go. Un sello válido es S4 solo si su token lleva `accuracy` y t más la precisión es anterior a `round_time`; si no, es S5, con la primera razón que se cumple: `late`, se selló después de la fecha o demasiado cerca de ella, también sin `round_time`; `no accuracy, BTSP`, el token no lleva precisión y su política es la BTSP de ETSI EN 319 421, `0.4.0.2023.1.1`, que la exige; o `no accuracy`. Una precisión vacía o de 0 segundos es una precisión de 0.
- `cms.dart`: `Token` gana `hasAccuracy`, `policy` y `btsp`, como `HasAccuracy`, `Policy` y `BTSP` de `internal/cms`, y la tabla de identificadores, `oidBTSP`.
- `verdicts.dart`: `SealReason`, con el código de Go en `code` y el texto del §29.7 en `text`; `Detail.sealReason` y `SignerLine.reason`. S5 ya no tiene texto propio: su línea es «No acredita que se sellara antes de la fecha de apertura: …», con la razón, y la de un firmante de F6 cuyo sello no prueba la fecha acaba en «sin acreditar que fuera antes de la fecha de apertura: …», donde decía «no antes de la fecha de apertura».

@ -26,7 +26,7 @@ Están hechas las etapas 0 a 5 del plan (`docs/PLAN_dart.md` del espacio de trab
- la 7b, las claves de autor `dkauthor1…`, con su firma Ed25519 y su fichero cifrado con scrypt, y el sellado del localizador y la creación del sobre, sobre el escritor de `age` de la 6a;
- fuera del plan, con la v0.15, las palabras al azar de la llave de palabras: las listas de palabras de `datekeys-go`, tomadas solo con su SHA-256 fijado y comprobadas con el alfabeto de su idioma, las palabras sacadas al azar de una y su fuerza en bits, y las de cinco dados cada una, con la lista numerada para los dados.
- fuera del plan, con la v0.15, lo que dice el SDK oficial al sellar: el anexo de recuperación que guarda junto a cada `.dkc` y el estado de un perfil en el registro de perfiles del §71.
- fuera del plan, con el borrador v0.16, todavía sin aprobar: un sello sin precisión ya no prueba la fecha y los veredictos dicen por qué, el escritor da los veredictos del área que escribe, el JSON de drand se lee estricto, y los dos fixtures de la v0.16.
- fuera del plan, con la v0.16, aprobada el 7 de octubre de 2026 con el tag `spec-v0.16`: un sello sin precisión ya no prueba la fecha y los veredictos dicen por qué, el escritor da los veredictos del área que escribe, el JSON de drand se lee estricto, y los dos fixtures de la v0.16.
La librería ya abre cápsulas reales, de los tres formatos, con todas sus credenciales, y evalúa toda su área de seguridad como Go: la firma de `alg` 1, la de `alg` 2 con certificados, el sello de `seal_type` 2 y todos los veredictos de su forma. Y ya escribe cápsulas del formato 3, con todas sus credenciales, su firma y su sello, byte a byte como Go con los mismos valores aleatorios, y Go las abre. Firma con una clave de autor y sella localizadores. Y saca al azar las palabras de una llave de palabras de las listas de `datekeys-go`, que toma solo con su SHA-256 fijado, o las da de unos dados. Y da el anexo de recuperación que el SDK oficial guarda junto a cada `.dkc` y el estado de un perfil fijado.
@ -125,9 +125,9 @@ Notas:
- **Las diferencias con Go.** `profileStatusOf` devuelve un registro, `(status, known)`, donde Go devuelve dos valores, y toma los bytes del hash, donde Go toma un `[32]byte`: un hash de otra longitud es un perfil que no conoce. Un perfil que no conoce está `active`, el `Status` cero de Go, con `known` a falso. `ProfileStatus` es un enum de tres valores, cada uno con el nombre de `Status.String` de Go en `label` y en `toString`; el `unknown` de Go, el de un `Status` fuera de rango, no tiene equivalente.
- **Lo que se exporta.** `lib/datekeys.dart` exporta `recoveryAnnex`, `recoveryAnnexSuffix`, `ProfileStatus` y `profileStatusOf`. `recoveryAnnexSha256`, el SHA-256 de los bytes del anexo que escribe también el programa, es interno, para las pruebas compiladas a JavaScript.
### El borrador v0.16
### La v0.16
El borrador v0.16 de `datekeys-go`, en la rama `v0.16` (de `70d907b` a `3fd0e93`), todavía sin aprobar, recoge la revisión de Astra de la v0.15. La librería lo porta de `4f78854`, en la rama `v0.16`, con los mismos textos, y sincroniza los datos de prueba con `3fd0e93`, que solo devuelve sus escapes a los vectores del JSON de drand:
La v0.16 de `datekeys-go`, en la rama `v0.16` (de `70d907b` a `b6ff17a`), aprobada el 7 de octubre de 2026 con el tag `spec-v0.16`, recoge la revisión de Astra de la v0.15. La librería lo porta de `4f78854`, en la rama `v0.16`, con los mismos textos, y sincroniza los datos de prueba con `3fd0e93`, que solo devuelve sus escapes a los vectores del JSON de drand:
| Módulo | Contenido | En Go |
|---|---|---|
@ -611,7 +611,7 @@ Manda ECDSA: con el exponente 65 537, una verificación de RSA son 17 multiplica
| Librería | `version` de `lib/src/version.dart` y de `pubspec.yaml`, que una prueba mantiene iguales | `0.1.0-dev` |
| Especificación | `specVersion` de `lib/src/version.dart`: la que nombra el campo `spec` de cada fichero de `testdata/` | `0.16` |
La rama sigue la versión de la especificación: hoy `v0.16`, la del borrador v0.16, y la rama `v0.15` se queda en `e2296b0`.
La rama sigue la versión de la especificación: hoy `v0.16`, la de la v0.16, y la rama `v0.15` se queda en `e2296b0`.
## Dependencias
@ -640,14 +640,14 @@ tool/check.sh
## Datos de prueba
`testdata/` es una copia de `datekeys-go/testdata` en un commit fijo. `testdata/SOURCE.json` registra el commit y el SHA-256 de cada fichero, igual que en `datekeys-ts`. La copia actual es la de `datekeys-go` en `3fd0e93`, la rama `v0.16`, el borrador v0.16 sin aprobar: 150 ficheros, con los fixtures `format3_time_and_key_words` y `format3_full_chunk` de la v0.16, `security_cms.json` hecho otra vez para la v0.16, con 143 casos y `seal_reason`, los 26 casos del JSON de drand estricto en `release.json` y el vector del anexo en `wordkey.json`; con `release.json` y `releases/`, el objeto release, el JSON de drand y el archivo de releases de la v0.15, con el campo `source` de `mutations.json`, con `tlock_steps.json`, los pasos 10 y 11 de Quicknet valor a valor, con `resolved_ip.json`, con `wordkey.json`, los vectores compartidos de la llave de palabras, y los veredictos y las líneas de la v0.16. Cada fichero dice `"spec": "0.16"`, como el `SpecVersion` de Go.
`testdata/` es una copia de `datekeys-go/testdata` en un commit fijo. `testdata/SOURCE.json` registra el commit y el SHA-256 de cada fichero, igual que en `datekeys-ts`. La copia actual es la de `datekeys-go` en `b6ff17a`, el commit del tag `spec-v0.16`: 150 ficheros, con los fixtures `format3_time_and_key_words` y `format3_full_chunk` de la v0.16, `security_cms.json` hecho otra vez para la v0.16, con 143 casos y `seal_reason`, los 26 casos del JSON de drand estricto en `release.json` y el vector del anexo en `wordkey.json`; con `release.json` y `releases/`, el objeto release, el JSON de drand y el archivo de releases de la v0.15, con el campo `source` de `mutations.json`, con `tlock_steps.json`, los pasos 10 y 11 de Quicknet valor a valor, con `resolved_ip.json`, con `wordkey.json`, los vectores compartidos de la llave de palabras, y los veredictos y las líneas de la v0.16. Cada fichero dice `"spec": "0.16"`, como el `SpecVersion` de Go.
`wordlists/` es la copia de `wordkey/lists` del mismo commit: las listas de palabras de `wordkey.Generate`, hoy `en.txt`, la de la EFF, y `es.txt`, y su `README.md`, con la fuente, el método y la licencia de cada lista, y el SHA-256 de cada lista numerada para los dados. `wordlists/SOURCE.json` tiene el formato de `testdata/SOURCE.json`, y `.gitattributes` guarda sus bytes exactos, como los de `testdata/`: `lib/src/wordlist.dart` fija el SHA-256 de cada lista.
`annex/` es la copia de `annex` del mismo commit: `recovery.md`, el anexo de recuperación de `datekeys.RecoveryAnnex`, el §79 de la especificación bajo su título. `annex/SOURCE.json` tiene el formato de `testdata/SOURCE.json`, y `.gitattributes` guarda sus bytes exactos: `lib/src/recovery_annex.g.dart` es su texto, que escribe `dart run tool/recovery_annex_copy.dart` tras cada `sync` que lo cambie.
```bash
dart run tool/sync_testdata.dart sync --commit 3fd0e93
dart run tool/sync_testdata.dart sync --commit b6ff17a
```
```bash
@ -879,7 +879,7 @@ rm -rf "$tmp"
| `cms_signatures.json`, `cms_algorithms.json` | `cms.ParseSignature` y `SignerInfo.Check` en las firmas de las pruebas de `internal/cms` (la forma, los algoritmos y las claves), con identificadores que dan la vuelta y SET OF con un elemento repetido |
| `cms_tokens.json` | `cms.ParseToken` y `Token.Check` en los tokens de esas pruebas, el TSTInfo campo a campo, la precisión y el `messageImprint` en sus límites, y la autoridad en los extremos de su validez, al nanosegundo; y, desde la v0.16, `HasAccuracy`, `Policy` y `BTSP` de cada token, también en `cms_mutations.json` y `cms_corpus.json` |
| `cms_mutations.json` | Firmas y tokens editados nodo a nodo y bit a bit, cada edición como el nodo, la operación y el SHA-256 del resultado |
| `cms_corpus.json` | Cada firma CMS y cada token de `security_cms.json` y de los fixtures `format3_signed_cms` y `format3_sealed` del borrador v0.16, leídos como los leen los veredictos de `capsule`, firmante a firmante |
| `cms_corpus.json` | Cada firma CMS y cada token de `security_cms.json` y de los fixtures `format3_signed_cms` y `format3_sealed` de la v0.16, leídos como los leen los veredictos de `capsule`, firmante a firmante |
| `cms_vectors.g.dart` | Una parte de cada fichero `cms_*.json`, como constantes de Dart |
| `age_writer.json` | Los ficheros que escribe `age.Encrypt` con el keystream de una semilla como `crypto/rand`, con cada valor que saca, su tamaño y su orden: un recipient X25519, sobre textos de 0 a 3 MiB, en los bordes de los chunks de 64 KiB; dos, tres y dieciséis, y uno con el bit 255 a 1, que `age` acepta; scrypt con factores de trabajo de 1 a 16 y contraseñas en UTF-8; y el stanza tlock de rondas de 1 a 11 cifras. Uno pequeño va entero, y uno grande, como su cabecera, su longitud y su SHA-256. Además: el keystream de varias semillas, `crypto/rand.Int` y el `permute` de `capsule.Encrypt` sobre él; los errores de `age.Encrypt`, con lo que saca antes de cada uno; los de `NewScryptRecipient`, `SetWorkFactor` y `NewTimeRecipient`; el STREAM tras `Close`; `ParseX25519Recipient`, `CheckX25519Recipient` y `GenerateX25519Identity`; y `testkit.StreamLen` y `capsule.PayloadAgeLength` |
| `age_writer.g.dart` | El mismo JSON como constante de Dart |

@ -1,7 +1,7 @@
{
"module": "g.activething.com/go/DateKeys",
"commit": "3fd0e9372b4e759d6b65e37802322b6e01643da4",
"commit": "b6ff17a5fa5f119aa8125356437a09c657b15d0b",
"files": {
"recovery.md": "dfb823cc2e8638e890cc690eea1d82bbcc661a50157be1ab4e8aaa5a4f80a6cb"
"recovery.md": "856f37efbc74a86af0db996e7c7678a8b506f839f0a8074389c0dbabc5dafa81"
}
}

@ -1,6 +1,6 @@
# Cómo abrir una cápsula DateKeys sin software de DateKeys
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.16, cuyo texto tiene el SHA-256 a3cbdc6ef99aeb3ec77e40c4ce838f6f5b8950af6191383e4033761d2ca1df80. Es el mismo para toda cápsula: no lleva ningún dato de esta. Su licencia es CC BY-ND 4.0, Atribución-SinDerivadas 4.0 Internacional (https://creativecommons.org/licenses/by-nd/4.0/deed.es): se puede copiar y compartir sin cambios, citando su origen.
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.16, cuyo texto tiene el SHA-256 807d4fe85ac09ad6f97abc75ab3e2156bb2f3fb0dc589777f4420627fad545e1. Es el mismo para toda cápsula: no lleva ningún dato de esta. Su licencia es CC BY-ND 4.0, Atribución-SinDerivadas 4.0 Internacional (https://creativecommons.org/licenses/by-nd/4.0/deed.es): se puede copiar y compartir sin cambios, citando su origen.
## 79. Anexo informativo: recuperación sin software DateKeys

@ -14,7 +14,7 @@
const recoveryAnnex = '''
# Cómo abrir una cápsula DateKeys sin software de DateKeys
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.16, cuyo texto tiene el SHA-256 a3cbdc6ef99aeb3ec77e40c4ce838f6f5b8950af6191383e4033761d2ca1df80. Es el mismo para toda cápsula: no lleva ningún dato de esta. Su licencia es CC BY-ND 4.0, Atribución-SinDerivadas 4.0 Internacional (https://creativecommons.org/licenses/by-nd/4.0/deed.es): se puede copiar y compartir sin cambios, citando su origen.
Este texto acompaña a una cápsula del tiempo de DateKeys, un fichero `.dkc`: dice cómo abrirla, llegada su fecha, sin ningún software de DateKeys, por si ya no existe. Es el anexo informativo §79 de la especificación del protocolo DateKeys v0.16, cuyo texto tiene el SHA-256 807d4fe85ac09ad6f97abc75ab3e2156bb2f3fb0dc589777f4420627fad545e1. Es el mismo para toda cápsula: no lleva ningún dato de esta. Su licencia es CC BY-ND 4.0, Atribución-SinDerivadas 4.0 Internacional (https://creativecommons.org/licenses/by-nd/4.0/deed.es): se puede copiar y compartir sin cambios, citando su origen.
## 79. Anexo informativo: recuperación sin software DateKeys
@ -206,4 +206,4 @@ Este anexo comprueba lo que decide que el resultado es el correcto: la firma del
///
/// Internal: lib/datekeys.dart does not export it.
const recoveryAnnexSha256 =
'dfb823cc2e8638e890cc690eea1d82bbcc661a50157be1ab4e8aaa5a4f80a6cb';
'856f37efbc74a86af0db996e7c7678a8b506f839f0a8074389c0dbabc5dafa81';

12
testdata/README.md vendored

@ -1,7 +1,7 @@
# DateKeys test data
Official vectors, fixtures and corpora of the DateKeys Protocol Specification
v0.15, generated by the reference implementation.
v0.16, generated by the reference implementation.
Another implementation consumes them as they are: this file documents every
format, so that no Go code has to be read. The rules that decide each verdict
are in the specification; this file points to them, and states only what
@ -21,10 +21,14 @@ added since. The local gate (`scripts/check.sh`) and CI run it and fail if any
committed file changes: every file below is exactly what the implementation
computes today.
The `spec` field of every file is `"0.15"`, the version this module declares.
The `spec` field of every file is `"0.16"`, the version this module declares.
v0.15 adds the release object and a release in the caller's hand (§47.1,
§63 step 9.c): `vectors/release.json`, the files of `releases/`, and the
field `source` of `mutations.json`.
field `source` of `mutations.json`. v0.16 adds the reason of a seal that
proves nothing before the opening date, `seal_reason`, to
`security_cms.json`, made again; the strict reading of drand's JSON to
`release.json`; and the fixtures `format3_time_and_key_words`, with
`words_text`, and `format3_full_chunk`.
What v0.12 changes from v0.11, the texts of the verdicts of a certificate and
of a seal, the profile of a certificate and the rules of the addresses and of
the padding of a locator, is in the files: the verdicts and the lines of
@ -402,7 +406,7 @@ flow).
```json
{
"spec": "0.15",
"spec": "0.16",
"description": "…",
"profile": "datekeys:quicknet:v1",
"scheme": "bls-unchained-g1-rfc9380",

@ -1,8 +1,8 @@
{
"module": "g.activething.com/go/DateKeys",
"commit": "3fd0e9372b4e759d6b65e37802322b6e01643da4",
"commit": "b6ff17a5fa5f119aa8125356437a09c657b15d0b",
"files": {
"README.md": "acd08972fca2ec6d84f203f7dea95c13ce290736200795025dbd525794e33f21",
"README.md": "a7b2d6810928ccb8be33e39ede053a2cada38cd74b2888dc8655f3d5c0bb8375",
"fixtures/empty_payload.dkc": "871e9bf05b52bbae17f3adfbbf97b46e7f0e53aa8f57bcaa506e43f36f53a9d4",
"fixtures/empty_payload.inspect.json": "373e5d012b023ad58bbb54cbdffe0bed9e50c637438a4083ddb74d5414c59f59",
"fixtures/empty_payload.json": "4ef16c75b3a7fe543ab37ff2c08e9e5061dc2d22f4b2724fe572c658af41c72a",

@ -1,6 +1,6 @@
{
"module": "g.activething.com/go/DateKeys",
"commit": "3fd0e9372b4e759d6b65e37802322b6e01643da4",
"commit": "b6ff17a5fa5f119aa8125356437a09c657b15d0b",
"files": {
"README.md": "a29122e04cd8dac3e44d6f271da2ca99ac98e28b27e88c16b58162fe3eebedad",
"en.txt": "6d557f0693958fb5e650b68b5bee585eb82cf4da32965505c789e924743bc522",

Loading…
Cancel
Save

Powered by TurnKey Linux.