You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.4 KiB

Plan: la librería Dart (datekeys-dart)

v2, 2 de octubre de 2026. El autor hará la app en Flutter, así que la librería del protocolo hace falta en Dart. La v1 de este plan la escribió una sesión hecha por descuido con Sonnet 5.5. La revisión de esa sesión (spec_v0.11/revision_sesion_1_2_octubre.md, R3) encontró que le faltaban piezas, y esta versión las añade. Las tres decisiones del autor están en «Decidido».

Qué es

Un paquete Dart puro: sin Flutter y sin plataforma.

  • Implementa el mismo protocolo que datekeys-go y datekeys-ts, para que la app Flutter lo use como dependencia de ruta o de git.
  • Funciona en la VM de Dart, en Flutter (móvil y escritorio) y en la web si no usa dart:io.
  • Es la tercera implementación del spec. Como la de TypeScript, no genera datos de prueba propios: se contrasta con el testdata/ de datekeys-go, sincronizado a un commit fijo.

Estado de la máquina: está instalado el SDK de Dart 3.13. No hay Flutter, y la librería no lo necesita; la app sí.

Decidido (2 de octubre)

  1. Dependencias: solo package:crypto, el paquete oficial de dart-lang, para SHA-1, SHA-2 y HMAC. Todo lo demás es código propio:
    • HKDF y PBKDF2;
    • ChaCha20-Poly1305, X25519 y Ed25519 estricto;
    • scrypt;
    • BLS12-381 con el IBE de tlock;
    • ECDSA, RSA, DER, CMS y CBOR.
  2. Orden: primero lectura y verificación (etapas 1 a 5) y después el escritor (etapas 6 y 7), como en TypeScript.
  3. Nombre del paquete: datekeys, sin publicar en pub.dev.

Alcance, por etapas

Cada etapa se cierra con sus pruebas contra los vectores y fixtures de Go, como en TypeScript. El orden sigue la dificultad y lo que desbloquea.

Etapa Contenido Referencia en TypeScript
0 Esqueleto del paquete: dart analyze y dart test, testdata/ sincronizado con un SOURCE.json, licencia Apache-2.0 scripts/sync-testdata.mjs
1 Bytes, errores normativos, CBOR determinista (§58) y DER estricto, también el de los tiempos bytes.ts, errors.ts, cbor.ts, der.ts
2 Primitivas: SHA-1/2 y HMAC (de package:crypto); HKDF, PBKDF2, scrypt, ChaCha20-Poly1305, X25519 y Ed25519 estricto; age (stanza X25519, stanza scrypt y STREAM) age.ts, agefile.ts, x25519.ts, ed25519strict.ts
3 BLS12-381 y tlock: emparejamiento, hash a curva, IBE-CCA de drand y verificación de la firma de la ronda bls12381.ts, ibe.ts, tlock.ts, release.ts
4 Formatos: DateKey, perfil, cabecera, control, head, cuerpo, rutas (tablas Unicode 18.0.0), .dkk, llave de palabras, nota, inspección (pasos 1 a 8) y apertura (pasos 9 a 18) datekey.ts, profile.ts, header.ts, control.ts, head.ts, pathrule.ts, wordkey.ts, note.ts, open.ts, open3.ts
5 Firma y sello: los compromisos, alg 1 (Ed25519), alg 2 (CMS con el perfil de certificado del §29.10, ECDSA y RSA en BigInt) y RFC 3161, y los veredictos con sus textos author.ts, cms.ts, securitycms.ts, security.ts
6 Escritor: formato 3 con el área de 32 KiB, time_only y time_and_key, llave de palabras y nota pública writer.ts, encrypt.ts, wordkey.ts, note.ts
7 Localizador y sobre (datekeys.capsule) y claves de autor dkauthor1…, con su fichero cifrado con scrypt locator y authorkey de Go

Queda fuera de la librería:

  • la descarga de releases de drand, porque el cliente HTTP lo pone la app;
  • la descarga del resto de un localizador, también de la app, con las reglas de direcciones del §44.1 y la comprobación de la IP resuelta en cada conexión;
  • el almacenamiento y la interfaz.

La librería recibe una fuente de releases, como OpenOptions.Source en Go.

Lo que la v1 no tenía en cuenta

  • PBKDF2-HMAC-SHA256 con 600 000 iteraciones (§38.1) para abrir con una llave de palabras, que es lectura, no escritura. Con el API general de package:crypto, cada iteración reserva memoria y recalcula el estado de las dos claves del HMAC: en un móvil tarda bastantes segundos. Hace falta un HMAC-SHA256 propio que precalcule los estados interno y externo una sola vez y reutilice los búferes; y la app lo llama en un Isolate. El vector de §38.1 y los de la página dan la referencia.
  • scrypt con logN = 16 (§29.12), para leer y escribir los ficheros de clave de autor: el stanza scrypt de age, con su límite de factor de trabajo, como SetMaxWorkFactor(16) de Go.
  • Las tablas de Unicode 18.0.0 (NFD, minúsculas simples y best-fit) para las reglas de rutas y de texto (§29.5.1) y para la llave de palabras. No se escriben a mano: el generador de Go, internal/pathrule/gen, ya escribe el módulo de TypeScript con -ts, y hará falta una salida -dart. El digest de las tablas recalculado en Dart debe coincidir con TablesDigest, como en TypeScript.
  • Los vectores de firma y sello. En la v0.11 cubrían mucho menos de lo que dice el spec: una implementación con fallos los pasaba todos. La revisión del 2 de octubre los está completando en la rama v0.12 de datekeys-go, con el perfil de certificado del borrador v0.12. La etapa 5 debe sincronizarse con esa versión, no con spec-v0.11. Las etapas 0 a 4 no dependen de eso.

Rendimiento

Hay dos cuellos de botella:

  • BLS12-381: abrir una cápsula verifica la firma de la ronda y hace un emparejamiento. Con BigInt en la VM de Dart serán cientos de milisegundos o más, y bastante más compilado a JavaScript.
  • PBKDF2 con 600 000 iteraciones, solo al abrir o crear con una llave de palabras.

La app debe llamar a los dos en un Isolate para no congelar la interfaz. La librería no lo hace por sí misma. Las cifras reales se miden en la etapa 3, en la VM y en un móvil de gama media.

Estructura del repo

G:\bussines\datekeys\datekeys-dart, repo independiente:

datekeys-dart/
  pubspec.yaml            # name: datekeys; sin Flutter; entorno de Dart 3.x; solo package:crypto
  lib/datekeys.dart       # la API pública, como index.ts
  lib/src/…               # un fichero por módulo de la tabla
  test/…                  # dart test, contra testdata/
  testdata/               # sincronizado desde datekeys-go con su SOURCE.json
  tool/sync_testdata.dart # equivalente de sync-testdata.mjs

La app Flutter lo usa con datekeys: { path: ../datekeys-dart }, o con una dependencia de git cuando haya remoto.

Ramas. La librería sigue la versión del spec que implementa: empieza en v0.11 y pasa a v0.12 cuando datekeys-go cierre esa versión.

Powered by TurnKey Linux.