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.
7.9 KiB
7.9 KiB
Changelog
Cambios notables de la librería Dart. El proyecto usa versionado semántico; mientras sea 0.x, no hay promesa de estabilidad.
Especificación 0.11, en la rama v0.11 — sin versión
Etapa 2: primitivas y age (05-10-2026)
- Primitivas, de código propio. Son internas:
lib/datekeys.dartno las exporta.- SHA-256 con su compresión, y HMAC-SHA256 con los estados interior y exterior de la clave calculados una vez. Sobre ellos, HKDF-SHA256 (RFC 5869) y PBKDF2-HMAC-SHA256 (RFC 8018), cuyas iteraciones son dos compresiones sobre palabras: 600 000 iteraciones tardan 1,1 s en la VM, frente a unos 3,5 s con el HMAC de
package:crypto. - scrypt (RFC 7914) con Salsa20/8, con las comprobaciones y los textos de
scrypt.Keyde Go. - ChaCha20, Poly1305 en diez limbs de 13 bits, y ChaCha20-Poly1305 (RFC 8439), con el tag comparado en tiempo constante.
- X25519 (RFC 7748) sobre el cuerpo de TweetNaCl en doubles, con clamping y el secreto todo a ceros rechazado con el texto de
crypto/ecdh. - Ed25519 estricto (§29.9), port de
internal/ed25519strict:verifyStrict,canonical,smallOrderyonCurve. La aritmética de los puntos es la de TweetNaCl; los escalares módulo ℓ yonCurveusanBigInt, que no es de tiempo constante, solo con datos públicos. - El Base64 de Go, con su modo estricto y el offset de sus errores, y el Bech32 de
age, con sus textos. - De
package:cryptosolo se usa SHA-512, en Ed25519.
- SHA-256 con su compresión, y HMAC-SHA256 con los estados interior y exterior de la clave calculados una vez. Sobre ellos, HKDF-SHA256 (RFC 5869) y PBKDF2-HMAC-SHA256 (RFC 8018), cuyas iteraciones son dos compresiones sobre palabras: 600 000 iteraciones tardan 1,1 s en la VM, frente a unos 3,5 s con el HMAC de
- Lectura de
agev1, port defilippo.io/agev1.3.2 (lib/src/age.dart):- la cabecera y sus límites de
internal/format, con los textos de error de Go; - el MAC de la cabecera, sobre la cabecera escrita otra vez como la escribe
age; - los stanzas X25519 y scrypt. La identity de scrypt rechaza por defecto un factor de trabajo por encima de 16, como
authorkeyde Go; el deagees 22; - la clave del payload y el STREAM de
internal/stream, que se descifra según llega el texto cifrado, con los mismos casos de fin de fichero que el lector de Go: sin chunk final, chunk que no se autentica, último chunk vacío y datos tras el final; - cada fallo es una
AgeExceptioncon el texto de Go y su fase, la cabecera o el payload, para que la etapa 4 dé las razones fijas decapsule.classify. LaDateKeysExceptionde una identity pasa sin cambios.
- la cabecera y sus límites de
agewrap(lib/src/agewrap.dart): las reglas de stanzas deOUTER_TIME_AGE,PAYLOAD_AGEeINNER_ACCESS_AGE, la lectura de los stanzas sin secretos,PayloadIdentityyAccessIdentity, con los textos y los códigos de Go.checkTimeStanzasrecibe la ronda, el chain hash y el id del perfil, que llegará con la etapa 4.- Vectores de Go en
test/vectors/, que escribentool/gen_primitive_vectors.goytool/gen_age_vectors.gocon las librerías de la caché de módulos, en el contexto del módulo dedatekeys-goy sin cambiar nada en él:primitives.jsony su copia en Dart,primitives.g.dart: RFC 5869, 7748, 7914, 8032 (porsign.inputde Go) y 8439, PBKDF2 con el vector del §38.1, los puntos de orden pequeño, Base64 y Bech32. Incluye dos mensajes con los que una suma de productos de Poly1305 pasa de 2^32: un acarreo tomado con un desplazamiento fallaría en la web, y una prueba lo detecta en Node;age.json: ficheros X25519 y scrypt, sus cortes y manipulaciones, un corpus de cabeceras contra la gramática del §28.1 y el límite de 2 MiB, y las reglas e identities deagewrap, con el texto de Go en cada caso;age_fixtures.json: elPAYLOAD_AGEde los 24 fixtures con supayload_identity, y elINNER_ACCESS_AGEde los 6time_and_key, sacado deOUTER_TIME_AGEcon el release del fixture.
- Pruebas. 296 en la VM y una aplazada, 127 más que en la etapa 1; 83 en Node.js, 27 más. Las de las primitivas y las de
agesin ficheros corren también compiladas a JavaScript, sin los casos largos (PBKDF2 a 600 000 iteraciones, scrypt con logN 16, X25519 iterada 1000 veces). - Fallos inyectados, uno a uno y revertidos: 46 en las primitivas,
ageyagewrap. Las pruebas detectan todos los que cambian un resultado. Cuatro no lo cambian: la máscara de una mitad de rotación de SHA-256 cuyos bits altos solo llegan a sumas enmascaradas, el redondeo de_carcuando sus entradas nunca son negativas, el de un acarreo del producto del cuerpo, que conserva el valor, y el acarreo del limb 1 de Poly1305 tomado con desplazamiento, cuya suma no pasa de 2^32. tool/bench.dartmide las primitivas en la VM y compilado a JavaScript; las cifras, en el README.
El gate con Node.js (05-10-2026)
tool/check.shcorre tambiéndart test -p node: las pruebas que no leen ficheros, compiladas a JavaScript, comprueban en cada commit que los enteros son exactos en la web. Lo decidió el autor.
Etapa 1: errores, bytes, CBOR y DER (05-10-2026)
- Errores normativos (§69).
ErrorCodecon los 19 códigos en el orden del spec yDateKeysException, con el mensajecontexto: CÓDIGOde Go.wrapywithContexthacen lo quefmt.Errorf("prefijo: %w"), yerrorCodelo quedatekeys.Code. Una prueba compara el catálogo con las líneasERR_del §69, leído dedatekeys-goen el tagspec-v0.11. - Bytes. Hexadecimal, comparación y concatenación.
- UTF-8 estricto: rechaza lo que rechaza
utf8.Validde Go y conserva un U+FEFF inicial. ElUtf8Decoderdedart:convertlo descarta, en la VM y en la web, así que no se usa. - Un
Stringcon un surrogate suelto se escribe en UTF-8 generalizado (WTF-8), que no es UTF-8 válido. utf8.DecodeRuney el%qde Go (strconv.Quote). La tabla destrconv.IsPrintde Go 1.26 se copia dedatekeys-ts, y una prueba fija el SHA-256 del conjunto de runas.
- UTF-8 estricto: rechaza lo que rechaza
- CBOR (§58, §58.1). Port de
codec/codec.go:CborEncoder,CborDecoder,unmarshalCbor,peekSchema,checkSchemaywalkCbor, con los mismos textos de error.- Los enteros son exactos en la VM y en la web: un
inthasta 2^53-1 y unBigIntpor encima, también en las claves de los mapas y en los textos de error. - El
Encoderde Go rechaza el UTF-8 inválido; aquí el único texto inválido es un surrogate suelto, y el error lo cita como Go citaría sus bytes en UTF-8 generalizado. CborEncoder.uintexige 0..2^53-1, con un texto propio, como endatekeys-ts;uint64escribe hasta 2^64-1.
- Los enteros son exactos en la VM y en la web: un
- DER estricto. Port de
internal/der/der.goen601e6d2, ya del borrador v0.12:check,split,content,setOfSortedyparseTime.parseTimedevuelve unDerTimecon los campos y los segundos Unix, exacto al nanosegundo. Es interno:lib/datekeys.dartno lo exporta. - Pruebas. Port de
errors_test.go,codec_test.go,internal_test.go,vectors_test.goyder_test.go, decbor.test.tsy debytes.test.ts, con los textos de error que imprime Go.- Los objetivos de fuzzing de Go son propiedades con semilla, contra un codificador y un decodificador de referencia escritos aparte, como
internal/cbortest. testdata/vectors/cbor.json: los 36accepty los 67reject, con los límites dewalky los valores. Los 172 vectores deschemasse leen y se aplazan: necesitan los decodificadores de esquema de la etapa 4.- 169 pruebas en la VM y una aplazada. Las 56 que no leen ficheros pasan también en Node.js (
dart test -p node); las que leen ficheros llevan@TestOn('vm').
- Los objetivos de fuzzing de Go son propiedades con semilla, contra un codificador y un decodificador de referencia escritos aparte, como
Etapa 0: el paquete (05-10-2026)
- Paquete
datekeysen Dart puro, sin Flutter, para Dart 3.13 y sin publicar (publish_to: none). testdata/sincronizado con el tagspec-v0.11dedatekeys-go(ae33434): 124 ficheros. Sutestdata/SOURCE.jsones el mismo, byte a byte, que escribedatekeys-tspara ese commit.tool/sync_testdata.dart, el equivalente descripts/sync-testdata.mjs.test/testdata_test.dartcomprueba la copia y que cada fichero nombre la versión de la especificación.tool/check.sh, el gate local.- Dependencias:
package:cryptoen ejecución ypackage:testen desarrollo. - Licencia Apache-2.0.