Inspector page: static SvelteKit site with /inspect (plan step 5)
A prerendered static site (adapter-static) with a landing page and
/inspect, which runs spec §63 steps 1 to 8 on a .dkc chosen with the file
picker, dropped anywhere on the page, or taken from the official fixtures
bundled at build time. It shows every step, the decoded header, the unlock
date in UTC and local time, and each extension's id, version, criticality,
length and hex, with a text view and an informative CBOR diagnostic view,
all escaped and labelled as unauthenticated before step 15. Copiar JSON
copies the exact "datekeys inspect -json" view.
No network: a hash-mode Content-Security-Policy with connect-src 'self'
is the first element of every page, and scripts/check-build.mjs verifies
it, the fixtures and the absence of external URLs after every build.
Large files are read only up to what steps 1 to 8 need.
Reviewed for design and accessibility (WCAG AA contrast, keyboard,
focus, live status, 360 px), security and correctness; 262 tests pass,
svelte-check has no warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
// The tests of src/lib. Vitest prefers this file to vite.config.ts, the
|
|
|
|
|
// SvelteKit configuration of the page, so the library tests run without the
|
|
|
|
|
// SvelteKit plugin; the page helpers in src/lib/inspector import the library
|
|
|
|
|
// by relative paths and need no $lib alias.
|
TypeScript implementation of DateKeys v0.8.2, steps 1 to 8
Canonical CBOR codec of the spec §58 profile, hand-written schema codecs
(profile, PUBLIC_HEADER, CONTROL_CBOR, .dkk, extensions), DKC1/DKK1
framing, a strict age header parser, dk1_ parsing and nanosecond date to
round resolution, and inspect (spec §63 steps 1 to 8) with the same checks
and view as "datekeys inspect -json". No runtime dependencies.
216 tests, cbor.ts at 100 % coverage, typecheck of the library without
Node types. A differential comparison with the Go reference at afb44a3
found no verdict, code or step disagreement in about 336,000 inputs. The
harness for the future Go vector files runs them when they appear.
vite 8.3.0 is declared explicitly: it is a required peer of vitest 5.0.1
that legacy-peer-deps does not install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
import { defineConfig } from 'vitest/config';
|
|
|
|
|
|
|
|
|
|
export default defineConfig({
|
|
|
|
|
test: {
|
|
|
|
|
include: ['src/**/*.test.ts'],
|
|
|
|
|
// BLS12-381 point checks and the 65 536-extension cases take a moment.
|
|
|
|
|
testTimeout: 30_000,
|
|
|
|
|
coverage: {
|
|
|
|
|
provider: 'v8',
|
Inspector page: static SvelteKit site with /inspect (plan step 5)
A prerendered static site (adapter-static) with a landing page and
/inspect, which runs spec §63 steps 1 to 8 on a .dkc chosen with the file
picker, dropped anywhere on the page, or taken from the official fixtures
bundled at build time. It shows every step, the decoded header, the unlock
date in UTC and local time, and each extension's id, version, criticality,
length and hex, with a text view and an informative CBOR diagnostic view,
all escaped and labelled as unauthenticated before step 15. Copiar JSON
copies the exact "datekeys inspect -json" view.
No network: a hash-mode Content-Security-Policy with connect-src 'self'
is the first element of every page, and scripts/check-build.mjs verifies
it, the fixtures and the absence of external URLs after every build.
Large files are read only up to what steps 1 to 8 need.
Reviewed for design and accessibility (WCAG AA contrast, keyboard,
focus, live status, 360 px), security and correctness; 262 tests pass,
svelte-check has no warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
include: ['src/lib/dkc/**/*.ts', 'src/lib/inspector/**/*.ts'],
|
|
|
|
|
exclude: ['src/lib/**/*.test.ts', 'src/lib/dkc/testing/**', 'src/lib/dkc/index.ts'],
|
TypeScript implementation of DateKeys v0.8.2, steps 1 to 8
Canonical CBOR codec of the spec §58 profile, hand-written schema codecs
(profile, PUBLIC_HEADER, CONTROL_CBOR, .dkk, extensions), DKC1/DKK1
framing, a strict age header parser, dk1_ parsing and nanosecond date to
round resolution, and inspect (spec §63 steps 1 to 8) with the same checks
and view as "datekeys inspect -json". No runtime dependencies.
216 tests, cbor.ts at 100 % coverage, typecheck of the library without
Node types. A differential comparison with the Go reference at afb44a3
found no verdict, code or step disagreement in about 336,000 inputs. The
harness for the future Go vector files runs them when they appear.
vite 8.3.0 is declared explicitly: it is a required peer of vitest 5.0.1
that legacy-peer-deps does not install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
reporter: ['text', 'html', 'json-summary'],
|
|
|
|
|
thresholds: {
|
Phase 2, step 4: local release verification
src/lib/dkc/release.ts is provider.Verify of the Go reference (spec §17,
§51, §63 step 10), in its order and with its texts:
- the round within the profile (ERR_DATEKEY_INVALID);
- the round of the release before the signature (ERR_ROUND_MISMATCH);
- the length of the signature;
- the pinned public key (ERR_UNKNOWN_PROFILE when it does not decode;
the point at infinity fails the verification, as with kyber);
- the signature (ERR_RELEASE_INVALID): the canonical encoding of a point
of G1 other than the point at infinity, gated by bls12381.ts, that
verifies on @noble/curves 2.4.0 as the BLS signature of
SHA-256(uint64be(round)), hashed with the RFC 9380 DST of G1.
Nothing noble throws becomes anything but ERR_RELEASE_INVALID, and no
text of noble is copied. Only Quicknet's scheme is verified (plan
decision 3): another scheme fails with ERR_UNKNOWN_PROFILE after the
round checks. It also defines ReleaseSource, with the contract for
network sources and correction 6, and suppliedRelease, the release that
the caller hands over (unverified, so step 10 checks it). index.ts does
not re-export it yet.
release.test.ts:
- replays TestVerifyRejects of the reference, with exact texts;
- accepts the published releases of rounds 1000, 1001, 2000 and 1004
(the last one recovered from the x + p encoding of the corpus, which
shows that encoding is the published signature re-encoded);
- shows the DST of G2, the one bls-unchained-on-g1 uses, fails;
- gives the code of each of the 7 corpus cases that fail at step 10,
with the round that inspect reads from the capsule.
ibe.failure.test.ts becomes noble.failure.test.ts and also fails noble's
BLS verification. Coverage of release.ts is 100 % and is now a
threshold. The site does not change.
npm run verify is green: 2,404 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
// The codec is covered completely (plan §7), and so are the IBE and
|
|
|
|
|
// the release verification (plan of phase 2, section 10, steps 3
|
|
|
|
|
// and 4).
|
TypeScript implementation of DateKeys v0.8.2, steps 1 to 8
Canonical CBOR codec of the spec §58 profile, hand-written schema codecs
(profile, PUBLIC_HEADER, CONTROL_CBOR, .dkk, extensions), DKC1/DKK1
framing, a strict age header parser, dk1_ parsing and nanosecond date to
round resolution, and inspect (spec §63 steps 1 to 8) with the same checks
and view as "datekeys inspect -json". No runtime dependencies.
216 tests, cbor.ts at 100 % coverage, typecheck of the library without
Node types. A differential comparison with the Go reference at afb44a3
found no verdict, code or step disagreement in about 336,000 inputs. The
harness for the future Go vector files runs them when they appear.
vite 8.3.0 is declared explicitly: it is a required peer of vitest 5.0.1
that legacy-peer-deps does not install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
'src/lib/dkc/cbor.ts': { 100: true },
|
Phase 2, step 3: the tlock IBE on noble 2, checked against Go
src/lib/dkc/ibe.ts is DecryptCCAonG2 of drand/kyber encrypt/ibe, the
decryption of tlock.TimeUnlock for Quicknet, on @noble/curves 2.4.0
(plan of phase 2, section 4). It adds nothing that kyber would reject:
- the signature and U pass the canonical-encoding gate of bls12381.ts,
which rejects the point at infinity too;
- H2 hashes GT in the order of kilic, never with noble's Fp12.toBytes;
- H3 and H4 follow kyber, including the rejection sampling of r, and
r = 0 never proves;
- roundIdentity is drand's DigestBeacon;
- the stanza body is exactly U || V || W, 128 bytes, as in tlock.
Errors are IbeError with a fixed reason (length, encoding, identity,
proof) and message: none carries sigma, the message, r or input bytes.
Anything noble throws past the gate is a proof failure. sigma and the
hashes derived from it are wiped on every path. The file keeps the MIT
notice of tlock-js, whose structure it follows. index.ts does not
re-export it yet; the opening of step 5 will use it.
scripts/ibe-go-vectors.go writes src/lib/dkc/testing/ibe-vectors.json
with kyber, tlock and age:
- the GT of e(G1, G2) and of its square, with H2;
- H3, including inputs accepted at the second and third iteration, and
H4;
- round identities;
- for the tlock stanza of every official fixture, the pairing, sigma, r
and the file key. tlock.TimeUnlock unwraps that file key, and age
opens OUTER_TIME_AGE with it;
- messages of 0, 1, 16 and 32 bytes encrypted by EncryptCCAonG2;
- kyber's verdict on eleven edited copies of the time_only stanza.
It restates the unexported H2, H3 and H4 and checks them on every
fixture against tlock and U = r·G2.
ibe.test.ts replays every vector and opens OUTER_TIME_AGE of each
fixture through age-encryption with a custom Identity: the header MAC
and STREAM verify, and a time_only fixture yields its control_cbor. It
also gates all 157 BLS edge encodings as the Go reference decodes them
and checks the fixed error texts. ibe.failure.test.ts mocks a noble
failure. Coverage of ibe.ts is 100 % and is now a threshold. The site
does not change.
npm run verify is green: 2,397 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
'src/lib/dkc/ibe.ts': { 100: true },
|
Phase 2, step 4: local release verification
src/lib/dkc/release.ts is provider.Verify of the Go reference (spec §17,
§51, §63 step 10), in its order and with its texts:
- the round within the profile (ERR_DATEKEY_INVALID);
- the round of the release before the signature (ERR_ROUND_MISMATCH);
- the length of the signature;
- the pinned public key (ERR_UNKNOWN_PROFILE when it does not decode;
the point at infinity fails the verification, as with kyber);
- the signature (ERR_RELEASE_INVALID): the canonical encoding of a point
of G1 other than the point at infinity, gated by bls12381.ts, that
verifies on @noble/curves 2.4.0 as the BLS signature of
SHA-256(uint64be(round)), hashed with the RFC 9380 DST of G1.
Nothing noble throws becomes anything but ERR_RELEASE_INVALID, and no
text of noble is copied. Only Quicknet's scheme is verified (plan
decision 3): another scheme fails with ERR_UNKNOWN_PROFILE after the
round checks. It also defines ReleaseSource, with the contract for
network sources and correction 6, and suppliedRelease, the release that
the caller hands over (unverified, so step 10 checks it). index.ts does
not re-export it yet.
release.test.ts:
- replays TestVerifyRejects of the reference, with exact texts;
- accepts the published releases of rounds 1000, 1001, 2000 and 1004
(the last one recovered from the x + p encoding of the corpus, which
shows that encoding is the published signature re-encoded);
- shows the DST of G2, the one bls-unchained-on-g1 uses, fails;
- gives the code of each of the 7 corpus cases that fail at step 10,
with the round that inspect reads from the capsule.
ibe.failure.test.ts becomes noble.failure.test.ts and also fails noble's
BLS verification. Coverage of release.ts is 100 % and is now a
threshold. The site does not change.
npm run verify is green: 2,404 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
'src/lib/dkc/release.ts': { 100: true },
|
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
|
|
|
// The stanza X25519 and its Bech32 identities (step 5).
|
|
|
|
|
'src/lib/dkc/x25519.ts': { 100: true },
|
|
|
|
|
'src/lib/dkc/bech32.ts': { 100: true },
|
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
|
|
|
'src/lib/dkc/digest.ts': { 100: true },
|
TypeScript implementation of DateKeys v0.8.2, steps 1 to 8
Canonical CBOR codec of the spec §58 profile, hand-written schema codecs
(profile, PUBLIC_HEADER, CONTROL_CBOR, .dkk, extensions), DKC1/DKK1
framing, a strict age header parser, dk1_ parsing and nanosecond date to
round resolution, and inspect (spec §63 steps 1 to 8) with the same checks
and view as "datekeys inspect -json". No runtime dependencies.
216 tests, cbor.ts at 100 % coverage, typecheck of the library without
Node types. A differential comparison with the Go reference at afb44a3
found no verdict, code or step disagreement in about 336,000 inputs. The
harness for the future Go vector files runs them when they appear.
vite 8.3.0 is declared explicitly: it is a required peer of vitest 5.0.1
that legacy-peer-deps does not install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
'src/lib/dkc/**/*.ts': { statements: 95, branches: 90, functions: 95, lines: 95 },
|
Inspector page: static SvelteKit site with /inspect (plan step 5)
A prerendered static site (adapter-static) with a landing page and
/inspect, which runs spec §63 steps 1 to 8 on a .dkc chosen with the file
picker, dropped anywhere on the page, or taken from the official fixtures
bundled at build time. It shows every step, the decoded header, the unlock
date in UTC and local time, and each extension's id, version, criticality,
length and hex, with a text view and an informative CBOR diagnostic view,
all escaped and labelled as unauthenticated before step 15. Copiar JSON
copies the exact "datekeys inspect -json" view.
No network: a hash-mode Content-Security-Policy with connect-src 'self'
is the first element of every page, and scripts/check-build.mjs verifies
it, the fixtures and the absence of external URLs after every build.
Large files are read only up to what steps 1 to 8 need.
Reviewed for design and accessibility (WCAG AA contrast, keyboard,
focus, live status, 360 px), security and correctness; 262 tests pass,
svelte-check has no warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
// The page model and helpers of the inspector (plan §8, phase 1).
|
|
|
|
|
'src/lib/inspector/**/*.ts': { statements: 95, branches: 90, functions: 95, lines: 95 },
|
TypeScript implementation of DateKeys v0.8.2, steps 1 to 8
Canonical CBOR codec of the spec §58 profile, hand-written schema codecs
(profile, PUBLIC_HEADER, CONTROL_CBOR, .dkk, extensions), DKC1/DKK1
framing, a strict age header parser, dk1_ parsing and nanosecond date to
round resolution, and inspect (spec §63 steps 1 to 8) with the same checks
and view as "datekeys inspect -json". No runtime dependencies.
216 tests, cbor.ts at 100 % coverage, typecheck of the library without
Node types. A differential comparison with the Go reference at afb44a3
found no verdict, code or step disagreement in about 336,000 inputs. The
harness for the future Go vector files runs them when they appear.
vite 8.3.0 is declared explicitly: it is a required peer of vitest 5.0.1
that legacy-peer-deps does not install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|