|
|
|
|
@ -0,0 +1,85 @@
|
|
|
|
|
# Borrador v0.16: decisiones para el autor
|
|
|
|
|
|
|
|
|
|
*7 de octubre de 2026. El borrador está en la rama `v0.16` de `datekeys-go` (`2c29625`), en `spec/DateKeys_Protocol_Specification_v0.16.md`. Recoge la revisión de Astra de la v0.15, con la dirección acordada tras su segunda y su tercera respuesta: cinco hallazgos, todos comprobados contra el texto y el código. Todavía no hay código: `SpecVersion` sigue en 0.15, y el anexo que escribe la CLI es el de la v0.15.*
|
|
|
|
|
|
|
|
|
|
Si apruebas lo que sigue tal como está, basta con decir «apruebo el borrador». Después se implementa en Go, con sus vectores, y se lleva a TypeScript y a Dart. La versión se cierra con su tag cuando las tres pasen.
|
|
|
|
|
|
|
|
|
|
## Lo que hace el borrador
|
|
|
|
|
|
|
|
|
|
1. **El sello sin `accuracy`** (§29.7, §29.11). Un sello válido solo acredita que es anterior a la fecha de apertura (S4) si su token lleva `accuracy` y t + precisión < round_time. Sin `accuracy` da S5, y S5 cambia de texto: «No acredita que se sellara antes de la fecha de apertura: ‹motivo›.» Hay tres motivos, que se comprueban en este orden:
|
|
|
|
|
- «se selló después de esa fecha o demasiado cerca de ella»;
|
|
|
|
|
- «el sello no dice la precisión que exige su política», si la política del token es la BTSP de ETSI (0.4.0.2023.1.1), que obliga a llevar `accuracy`;
|
|
|
|
|
- «el sello no dice su precisión», en los demás casos.
|
|
|
|
|
|
|
|
|
|
En F6, la línea de un firmante cuyo sello no lleva `accuracy` dice «sin acreditar que fuera antes de la fecha de apertura» y el motivo. El texto anterior de S5, «Sellado después de la fecha de apertura», era falso para un sello anterior a la fecha cuya precisión llegaba a ella.
|
|
|
|
|
2. **La llave de palabras en el anexo** (§79.7, nueva). El anexo trae la derivación entera: P, la sal, PBKDF2 con 600 000 iteraciones y dos vectores. La normalización va en dos niveles:
|
|
|
|
|
- **Sin tablas**, exacta para el texto que dan las listas de DateKeys: ASCII; á, é, í, ó, ú, ü y ñ con sus mayúsculas; y las marcas de U+0300 a U+036F. Se quitan las marcas, cada letra con tilde pasa a su letra base, A a Z pasan a minúsculas y se parte por los espacios.
|
|
|
|
|
- **Completa** para cualquier otro texto: NFD, quitar las marcas, minúscula simple y partir por los espacios. Usa `UnicodeData.txt` de Unicode 18.0.0, que el anexo nombra por su SHA-256 y su dirección en unicode.org.
|
|
|
|
|
|
|
|
|
|
El segundo vector, «Ñandú», dos espacios, «PINGÜINO», un tabulador y «camión árbol Éter ola», da la misma llave que «nandu pinguino camion arbol eter ola» y que el mismo texto con las tildes escritas como marcas sueltas. La v0.16 renumera El contenido como 79.8 y Lo que el anexo no comprueba como 79.9.
|
|
|
|
|
3. **El último bloque de `age`** (79.5). «El último más corto» pasa a «el último puede ser más corto, o estar completo». Con 65 536 bytes de plaintext hay un solo bloque, completo y marcado como último. `scripts/recovery` ya lo hacía bien, pero ningún fixture lo comprobaba.
|
|
|
|
|
4. **Las evidencias de la firma con certificado** (§29.10, §62.1 reglas 21 y 22). El escritor SHOULD guardar:
|
|
|
|
|
- la cadena de cada firmante, sin su raíz;
|
|
|
|
|
- la de la autoridad de cada sello, sin su raíz;
|
|
|
|
|
- las respuestas OCSP.
|
|
|
|
|
|
|
|
|
|
Así se sustituye el «podar a un certificado por firmante» de la v0.15. Si algo no cabe, el escritor MUST decir qué deja fuera y SHOULD ofrecer exportarlo. Nunca deja fuera una firma, el certificado de un firmante ni su sello. §29.10 ya no promete la respuesta OCSP: promete lo que la cápsula conserva.
|
|
|
|
|
5. **El JSON de drand, estricto** (§47.1):
|
|
|
|
|
- ningún objeto repite un nombre;
|
|
|
|
|
- los nombres se comparan exactos tras decodificar sus escapes;
|
|
|
|
|
- un sustituto suelto hace el JSON mal formado;
|
|
|
|
|
- `round` es un entero sin signo de 1 a 2⁵³ − 1, sin fracción ni exponente.
|
|
|
|
|
|
|
|
|
|
Lo demás es `ERR_RELEASE_INVALID`. Hoy las tres implementaciones leen como `encoding/json` de Go: el último de dos nombres repetidos gana, y `ROUND` vale como `round`. Comprobado: `{"round":1000,"ROUND":1001,…}` da la ronda 1001 en Go, y 1000 en un lector con `JSON.parse` o con el `json` de Python.
|
|
|
|
|
6. **Erratas.**
|
|
|
|
|
- §1 junta en una línea la Release API, la Release Cache y el objeto release.
|
|
|
|
|
- La lista de §74 acaba en punto.
|
|
|
|
|
- §77 añade ETSI EN 319 421 y 319 422.
|
|
|
|
|
- §79 nombra las interfaces de `drand/kyber`, que `scripts/recovery` también importa.
|
|
|
|
|
- La cabecera ya no dice «prevista» de la implementación de referencia.
|
|
|
|
|
|
|
|
|
|
No cambia ningún formato. Cambian dos veredictos, el del sello sin `accuracy` y el de algunos JSON de drand, y §70 y §76 lo registran.
|
|
|
|
|
|
|
|
|
|
## Decisiones
|
|
|
|
|
|
|
|
|
|
1. **El sello sin `accuracy` acredita como S5, sin margen ni tabla de políticas.** Es lo que pidió Astra: ningún margen fijo vale para toda TSA, y la precisión de una política solo la sabe quien la conoce. Una tabla de políticas con su precisión, para dar S4 a un sello sin `accuracy`, queda en §74 como trabajo futuro: habría que mantenerla en el spec y en las tres implementaciones.
|
|
|
|
|
- Recomendación: aprobar.
|
|
|
|
|
2. **Un motivo propio para un token BTSP sin `accuracy`.** Cuesta comparar un OID, y dice algo útil: que la autoridad incumple su propia política, y no solo que el sello no basta. Las cláusulas están comprobadas en los textos de ETSI: EN 319 421 V1.3.1, §5.1 (1 s o mejor), §5.2 (el OID), TIS-7.7.1-01 (el perfil de EN 319 422) y TIS-7.7.2-03; y EN 319 422 V1.1.1, §5.2.2 («the accuracy field shall be present»).
|
|
|
|
|
- Recomendación: aprobar.
|
|
|
|
|
3. **El escritor MUST avisar de un sello sin `accuracy`** (regla 19) y SHOULD ofrecer pedirlo a otra autoridad. No lo rechaza: el sello sigue probando que la firma existía en t. Hoy ningún escritor pide sellos, ni la CLI ni `/create`, así que la regla no cambia ningún código.
|
|
|
|
|
- Recomendación: aprobar.
|
|
|
|
|
4. **La receta sin tablas.** Cubre las letras de las dos listas, el español y el inglés de la EFF, y cualquier ASCII. Una letra de fuera, como la ç catalana o la ß, ya necesita las tablas. Ampliarla a todo Latin-1 es posible, pero alarga el anexo con casos que las listas no dan.
|
|
|
|
|
- Recomendación: aprobar como está.
|
|
|
|
|
5. **Sin paquete de recuperación en el spec.** Astra proponía nombrar en el anexo un paquete de recuperación por su versión, su SHA-256 y el SHA-256 de cada fichero. El borrador nombra solo `UnicodeData.txt` por su SHA-256. Sirve cualquier copia que lo cumpla, y unicode.org conserva todas sus versiones. Un paquete tiene dos problemas:
|
|
|
|
|
- el anexo no puede dar el SHA-256 de un paquete que lo contiene;
|
|
|
|
|
- necesita un sitio público donde alojarlo, y hoy no hay ninguno: el Gitea no es nuestro.
|
|
|
|
|
|
|
|
|
|
Cuando haya sitio, el paquete puede llevar `UnicodeData.txt`, el código de `scripts/recovery` y las listas, y el anexo lo nombraría sin contenerse a sí mismo.
|
|
|
|
|
- Recomendación: aprobar sin paquete, y añadirlo a §74 cuando haya sitio público.
|
|
|
|
|
6. **Las evidencias, SHOULD guardar y MUST decir lo que falta.** No es un MUST guardar las cadenas, porque pueden no caber ni en 64 KiB con varios firmantes. Los veredictos del lector no cambian: un certificado de más no decide nada. Ningún escritor firma hoy con certificados.
|
|
|
|
|
- Recomendación: aprobar. La medida del área (§74, §75 punto 13) incluirá las cadenas sin la raíz.
|
|
|
|
|
7. **La ronda del JSON de drand, de 1 a 2⁵³ − 1**, como en el objeto release. La ronda 0 y las mayores pasan de `ERR_ROUND_MISMATCH` a `ERR_RELEASE_INVALID`. Así el JSON y el objeto tienen el mismo rango.
|
|
|
|
|
- Recomendación: aprobar.
|
|
|
|
|
8. **Los vectores de los sellos.** En `security_cms.json`, once de los trece casos que dan S4 llevan un token sin `accuracy`, porque el generador no la escribe si es 0. Con la v0.16 darían S5, y algunos dejarían de probar lo que dicen. Por ejemplo, «an authority named with 50 spaces» prueba cómo se muestra el nombre de la autoridad, y S5 no lo muestra. La propuesta:
|
|
|
|
|
- regenerar esos casos con una `accuracy` de 1 s, para que sigan en S4;
|
|
|
|
|
- añadir los casos sin `accuracy` de §64: años antes de la fecha, de la política BTSP, después de la fecha y en `alg` 2;
|
|
|
|
|
- añadir uno con una `accuracy` de 0 segundos.
|
|
|
|
|
|
|
|
|
|
Los fixtures no cambian: `format3_sealed` y `format3_signed_cms` ya llevan `accuracy`.
|
|
|
|
|
- Recomendación: aprobar.
|
|
|
|
|
|
|
|
|
|
## Lo que queda para después
|
|
|
|
|
|
|
|
|
|
- **La revisión externa.** Su paquete sigue en la v0.15. Al cerrar la v0.16 se le añade este cambio, que responde a una revisión.
|
|
|
|
|
- **La licencia del anexo.** El anexo es texto del spec, CC BY 4.0, y ni su cabecera ni el README de Go lo dicen. Está pendiente de tu respuesta: si apruebas añadirla, irá en la cabecera que genera `annex_test.go`.
|
|
|
|
|
|
|
|
|
|
## Al aprobar
|
|
|
|
|
|
|
|
|
|
- `SpecVersion` 0.16, el SHA-256 en `spec/README.md`, el anexo regenerado con `DATEKEYS_WRITE_ANNEX=1`, el tag `spec-v0.16` y `main`.
|
|
|
|
|
- En Go:
|
|
|
|
|
- los veredictos y textos del sello;
|
|
|
|
|
- el lector estricto del JSON de drand;
|
|
|
|
|
- `scripts/recovery` con las palabras;
|
|
|
|
|
- el fixture con un último bloque completo;
|
|
|
|
|
- los vectores nuevos.
|
|
|
|
|
- TypeScript y Dart siguen a Go con los vectores sincronizados. En TypeScript, la guarda exige una prueba para cada fichero nuevo de `testdata`.
|