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.
DateKeys-App/CHANGELOG.md

29 lines
2.5 KiB

# Changelog
Cambios notables de la librería TypeScript y de la página. El proyecto usa versionado semántico; mientras sea 0.x, no hay promesa de estabilidad. La sección «Versiones» del [README](README.md) explica qué cubre cada número.
## 0.1.0 — sin publicar
Implementa la especificación DateKeys 0.8.2 (tag `spec-v0.8.2` de `datekeys-go`) para el perfil Quicknet, y pasa todos los vectores y fixtures compartidos de `datekeys-go` en `9ac9cd9`.
### Hecho
- Codec CBOR del perfil de §58 con los textos de error de la referencia Go.
- Schemas del Provider Profile, `PUBLIC_HEADER`, `CONTROL_CBOR` y `.dkk`.
- Tramas DKC1 y DKK1, cabeceras `age` y DateKey (`dk1_`).
- Extensiones, con los objetos y arrays de su registro.
- La inspección de los pasos 1 a 8 de §63.
- La página estática `/inspect`, sin red. Tras cada compilación se comprueban su política de seguridad y los paquetes de su bundle.
- Fase 2, en curso:
- dependencias de ejecución (`age-encryption` 0.3.1, `@noble/curves` y `@noble/hashes` 2.4.0) con sus guardas;
Phase 2, step 5a: open capsules, steps 9 to 18, in memory src/lib/dkc/open.ts runs steps 9 to 18 of spec §63 on top of the steps 1 to 8 of inspectWith. It follows capsule.Open of the Go reference, with its checks, codes and texts: - step 9: the access credentials (the .dkk as an object, then its capsule_id and capsule_digest), then the release, never before the round time. Any failure of the source is ERR_RELEASE_UNAVAILABLE alone, keeping its text and its cause (correction 6); - step 10: verifyRelease; - steps 11 to 13: OUTER_TIME_AGE, the structure against access_policy and INNER_ACCESS_AGE; - steps 14 to 18: CONTROL_CBOR, header_binding, I_PAYLOAD, PAYLOAD_AGE and the commit. The three age files open with the Decrypter of age-encryption and identities that apply the rules of Go's agewrap: the tlock identity on ibe.ts, and the access and payload identities on x25519.ts. A failure of age that no identity reports is ERR_INTEGRITY with the fixed reason of its phase, header or STREAM, never the text of age-encryption. The plaintext is decrypted in memory and returned only after step 18. Streaming to OPFS is step 5b. src/lib/dkc/x25519.ts opens one age X25519 stanza at a time, in the order of age's X25519Identity. Step 13 must try every identity on every stanza (spec §36), and age-encryption's Decrypter stops at the first. Its primitives are the ones age-encryption uses: X25519 and HKDF from noble curves and hashes, and ChaCha20-Poly1305 from @noble/ciphers 2.4.0. The author approved declaring that package as a direct dependency on 2026-09-28; it is the copy already installed and bundled. The guards now allow ciphers, and x25519.ts in the noble allowlist. src/lib/dkc/bech32.ts ports age's internal/bech32, with its MIT notice, to read AGE-SECRET-KEY-1 identities. Tests: - vectors.test.ts runs all 65 cases of the mutation corpus through open. Each gives the code and the step of Go, and no case that fails without the network requests a release. This includes the 34 cases of steps 9 to 18 that were skipped, so the suite no longer skips any test. - open.test.ts: - the five official fixtures open to their plaintext, with each credential, with the checks and details of the reference; - the unusable noncritical extensions are reported; - the source failures and the clock; - age failures by phase; - CONTROL_CBOR that does not decode, and a low-order share in INNER_ACCESS_AGE, through an OUTER_TIME_AGE resealed with the FK_TIME of the Go vectors; - the texts of the identities. - x25519.test.ts checks against age-encryption both ways and against the Go-written stanzas of the fixtures, and covers every low-order share. - bech32.test.ts has the vectors of the reference. x25519.ts and bech32.ts are at 100 % coverage, now thresholds. open.ts is at 100 % of lines; the one branch left is the one for an error that is not a DateKeysError. index.ts does not re-export the opening yet. The page imports index.ts, and re-exporting would pull noble into /inspect (58.7 to 84.9 KB gzip) even unused; step 8 will load it on demand. The site does not change. npm run verify is green: 2,490 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- el IBE de tlock (`ibe.ts`) y la verificación local de releases (`release.ts`), contrastados con la referencia Go;
- la apertura, pasos 9 a 18 de §63 (`open.ts`), con el texto en claro en memoria. Las identidades estrictas de `agewrap` se apoyan en `x25519.ts`, que abre cada stanza X25519 por separado, y en `bech32.ts`. Los 65 casos del corpus de mutaciones pasan por `open` con el código y el paso de Go, y los cinco fixtures oficiales se abren a su texto en claro;
Phase 2, step 5b: open from a Blob, streaming to an output open(dkc, opts) now takes a Uint8Array or a Blob, such as a File. - Of a Blob it reads only the prefix that steps 1 to 8 need. inspectedLength and readCapsule move from src/lib/inspector/load.ts to src/lib/dkc/prefix.ts, and the page imports them from the library. - The .dkk capsule_digest is computed over the Blob's stream with the new src/lib/dkc/digest.ts, an incremental SHA-256 on @noble/hashes, since Web Crypto hashes whole buffers only. digest.ts joins the noble allowlist of the guards. - PAYLOAD_AGE is decrypted in streaming. The plaintext goes to memory, as before, or to opts.output, a WritableStream. The output is written as age authenticates each chunk, closed only after step 18, and aborted after any failure at any step, even before step 17 (spec §56). A failure of the output is ERR_INTEGRITY with its text, as Go keeps the error of the writer of the plaintext. Tests: - the fixtures from Blobs, to memory and to an output; - a truncated two-chunk payload whose first chunk reached the output before the abort; - early failures that never write; - write and close failures, and an abort that fails; - a .dkk without capsule_digest; - the whole mutation corpus again as Blobs into an output, aborted in every case; - digest.ts against Web Crypto. Coverage of digest.ts is 100 % and a threshold. Checked in the browser (dev server, real OPFS). time_only.dkc, two STREAM chunks, opened from a Blob into FileSystemFileHandle.createWritable gives 78,000 bytes with the SHA-256 of its sidecar. The same file truncated fails at step 17, and the OPFS file keeps its previous content. The quota check, the temporary file and the download belong to the page, in step 8. npm run verify is green: 2,560 tests. The site does not change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- `@noble/ciphers` 2.4.0 como dependencia directa, aprobada el 28-09-2026: la copia que ya trae `age-encryption`;
- la apertura en streaming. La entrada puede ser un `Blob`, del que se lee solo el prefijo de los pasos 1 a 8 (`prefix.ts`, antes en la página) y se descifra `PAYLOAD_AGE` en streaming. La salida puede ser un `WritableStream`, que se cierra solo tras el paso 18 y se aborta ante cualquier fallo. En el navegador, con un fichero OPFS, un fallo de STREAM deja intacto su contenido anterior.
Phase 2, step 7: tlock encryption, checked against Go both ways - ibe.ts gains encryptOnG2RFC9380, EncryptCCAonG2 of kyber with the suite of tlock for Quicknet. Qid is H(id) on G1 with the RFC 9380 DST, sigma comes from crypto.getRandomValues, U = r·G2, V = sigma XOR H2(e(Qid, key)^r) and W = msg XOR H4(sigma). The key passes the canonical gate, and sigma and the masks are wiped. encryptOnG2WithSigma takes a given sigma, for the vectors only; index.ts exports neither. - tlock.ts adds timeRecipient, the age-encryption Recipient of OUTER_TIME_AGE, as Go's agewrap.TimeRecipient. It writes the stanza "tlock <round> <chain hash>" with the checks and texts of NewTimeRecipient: the scheme and the pinned key, then the round range. age-encryption has no labels, so the writer of phase 3 adds it alone. Vectors, in src/lib/dkc/testing/tlock-vectors.json from scripts/tlock-go-vectors.go: - Fixed-sigma encryptions of 1, 16 and 32 bytes for rounds 1000 and 1001. Go restates EncryptCCAonG2, since kyber draws sigma itself, and checks the restatement with ibe.DecryptCCAonG2 and tlock.TimeUnlock. encryptOnG2WithSigma reproduces them byte for byte. - The samples of scripts/tlock-ts-samples.mjs, which Node runs on the TypeScript sources: IBE bodies and age files that this library made for rounds 1000 and 1001. Go opened every one: the bodies with tlock.TimeUnlock and the age files with age.Decrypt and agewrap.NewTimeIdentity, the identity of step 11. It got the same file keys and plaintexts, and the samples are frozen with those verdicts. tlock.test.ts replays both blocks, the random round trip, the rejections with their texts, and an age file sealed with timeRecipient and opened with the step-11 identity of open.ts. Coverage of ibe.ts and tlock.ts is 100 %, now a threshold for tlock.ts too. Step 6 of the plan is recorded as done: the canonicality amendment is in spec-v0.8.2. npm run verify is green: 2,567 tests. The site does not change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- el cifrado del stanza tlock (`encryptOnG2RFC9380`) y el `Recipient` de `OUTER_TIME_AGE` (`tlock.ts`). Con sigma fijo, el cifrado reproduce byte a byte los vectores de Go. Además Go abre lo que cifra esta librería: el cuerpo IBE con `tlock.TimeUnlock` y el fichero `age` con `agewrap.NewTimeIdentity`.
- `VERSION` y `SPEC_VERSION`, también en el pie de la página.
### Pendiente para 0.1.0
Phase 2, step 5b: open from a Blob, streaming to an output open(dkc, opts) now takes a Uint8Array or a Blob, such as a File. - Of a Blob it reads only the prefix that steps 1 to 8 need. inspectedLength and readCapsule move from src/lib/inspector/load.ts to src/lib/dkc/prefix.ts, and the page imports them from the library. - The .dkk capsule_digest is computed over the Blob's stream with the new src/lib/dkc/digest.ts, an incremental SHA-256 on @noble/hashes, since Web Crypto hashes whole buffers only. digest.ts joins the noble allowlist of the guards. - PAYLOAD_AGE is decrypted in streaming. The plaintext goes to memory, as before, or to opts.output, a WritableStream. The output is written as age authenticates each chunk, closed only after step 18, and aborted after any failure at any step, even before step 17 (spec §56). A failure of the output is ERR_INTEGRITY with its text, as Go keeps the error of the writer of the plaintext. Tests: - the fixtures from Blobs, to memory and to an output; - a truncated two-chunk payload whose first chunk reached the output before the abort; - early failures that never write; - write and close failures, and an abort that fails; - a .dkk without capsule_digest; - the whole mutation corpus again as Blobs into an output, aborted in every case; - digest.ts against Web Crypto. Coverage of digest.ts is 100 % and a threshold. Checked in the browser (dev server, real OPFS). time_only.dkc, two STREAM chunks, opened from a Blob into FileSystemFileHandle.createWritable gives 78,000 bytes with the SHA-256 of its sidecar. The same file truncated fails at step 17, and the OPFS file keeps its previous content. The quota check, the temporary file and the download belong to the page, in step 8. npm run verify is green: 2,560 tests. The site does not change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- La acción "abrir" en `/inspect`, cargada bajo demanda, con el fichero temporal de OPFS, la cuota libre y la descarga (paso 8).

Powered by TurnKey Linux.