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.

18 KiB

Artifacts

State on 7 October 2026, specification v0.16. Paths are relative to each repository.

1. Repositories and frozen commits

Repository Role Frozen at Language of docs
datekeys-go Specification (spec/), CDDL, shared test data (testdata/), reference implementation in Go: library and CLI tag spec-v0.16, commit b6ff17a5fa5f119aa8125356437a09c657b15d0b (also the head of branch v0.16 and of main) English README (a Spanish one too); spec in Spanish
datekeys-ts TypeScript library and static pages /inspect and /create tag v0.5.0, commit 2c305cf (implements spec 0.16) Spanish README
datekeys-dart Pure Dart library, for a future Flutter app branch v0.16, commit b53afdc, no tag (implements spec 0.16) Spanish README
  • The repositories are private, on a Gitea server on the author's LAN (g.activething.com). They are not reachable from outside. The author will provide them by another means (for example git bundle files or archives); see NOTA_PARA_EL_AUTOR.md.
  • The gates of datekeys-ts and datekeys-dart compare their testdata/ with a sibling checkout ../datekeys-go. Lay the three out side by side:
work/
  datekeys-go/     at spec-v0.16
  datekeys-ts/     at v0.5.0 (the author's machine names this folder App)
  datekeys-dart/   at b53afdc

Specification files at the tag:

File SHA-256
spec/DateKeys_Protocol_Specification_v0.16.md (4 810 lines, about 61 000 words, Spanish) 807d4fe85ac09ad6f97abc75ab3e2156bb2f3fb0dc589777f4420627fad545e1
spec/datekeys.cddl (340 lines, English comments; v0.15 adds the rule release, v0.16 changes no schema) ba3ceb24203ef49f55d5da021b7e940ae6780ef83fccb10aa3d305e4dcfac3a3

Both were checked on 7 October 2026 with git show spec-v0.16:<file> | sha256sum. The documentation of the Go repository (README, SECURITY.md, docs/traceability.md, the header comment of the CDDL) is at v0.16 in the same commit, so one commit freezes Go.

spec/README.md lists the SHA-256 of every frozen version from v0.8.2 to v0.16. Earlier versions are in the same folder; §76 records each normative change with its reproducible case. The specification is CC-BY-ND-4.0 (since 7 October 2026; it was CC-BY-4.0); the code is Apache-2.0.

2. Build and gates

datekeys-go (Go 1.26.8)

cd datekeys-go
scripts/check.sh                       # the local gate, without fuzzing
scripts/check.sh 20s                   # and every fuzz target for 20 s each
FUZZ_PARALLEL=4 scripts/fuzz.sh 60s    # fuzzing only
go test -tags interop ./capsule        # the official age and tle CLIs open our files
go test -tags integration ./capsule ./provider/drand   # live Quicknet (network)

scripts/check.sh runs, in order: gofmt; go mod verify; go mod tidy leaves go.mod and go.sum unchanged; go vet; go test -race; coverage of at least 90 % in codec, capsule, accesskey, datekey and agewrap; govulncheck v1.8.0 (downloads the tool); scripts/recovery_check.sh (v0.15 and v0.16, below); and genfixtures, which regenerates testdata/ and fails if any committed file changes.

scripts/recovery_check.sh proves the annex of spec §79: it opens the fixtures format3_single (time_only), format3_time_and_key_portable (time_and_key, with its .dkk), and, since v0.16, format3_time_and_key_words (with the text of the words of the annex vector) and format3_full_chunk (a PAYLOAD_AGE of one full STREAM chunk) with scripts/recovery, using the release objects of testdata/releases/, and compares the BODY it recovers with the plaintext fixture. scripts/recovery imports no DateKeys, tlock or drand package: only the Go standard library (PBKDF2 included), golang.org/x/crypto (ChaCha20-Poly1305), filippo.io/age and drand's BLS12-381 library (github.com/drand/kyber-bls12381, with the interfaces of github.com/drand/kyber). It takes the words with -words and, for text outside the recipe without tables of §79.7, UnicodeData.txt with -unicodedata, checked by its SHA-256. Its tests check the import rule, run over ten fixtures of the three formats, and compare both normalisations of §79.7 with every case of vectors/wordkey.json (spec §76, v0.15 change 4; v0.16 changes 2 and 3).

scripts/fuzz.sh has 27 targets: codec (Decoder, Walk, Peek, Unmarshal, EncodeImpliesWalk), extension (DecodeArray), profile (Decode), provider (DecodeRelease, new in v0.15: the release object of §47.1), datekey (Parse), agewrap (Stanzas), accesskey (Decode), capsule (ParsePrelude, DecodeHeader, DecodeControl, DecodeHead, EvaluateSecurity, Inspect, EncodeImpliesDecode), internal/pathrule (CheckPath), locator (Unmarshal, ParseInfo, CheckURI, CheckResolvedIP), internal/der (DERCheck), internal/cms (ParseSignature, ParseToken, ParseCert). Each worker keeps a 100 MB shared-memory file in the temporary directory; FUZZ_MINIMIZE (default 0) sets the time spent minimising a new input.

The CLI (cmd/datekeys) has encrypt, decrypt, inspect, author keygen, author public, profile hash, datekey resolve and version (README.md). Since v0.15, decrypt -release <file> takes a release in hand (a release object, drand's JSON or a local release archive), makes no request and does not compare it with the clock. encrypt writes the recovery annex next to the capsule and says what opening will take (§62.1 rules 26 and 27), and draws random words with -new-words or takes them from dice with -dice.

Gate and fuzzing record:

  • On 7 October 2026, scripts/check.sh (without fuzzing) passed on b6ff17a, the frozen commit, and before on 4f78854 and 3fd0e93 of the same branch.
  • On 7 October 2026, FUZZ_PARALLEL=4 scripts/fuzz.sh 20s ran the 27 targets on b6ff17a, with no failing input.
  • For v0.15: scripts/check.sh passed on fe50885.
  • For v0.15: FUZZ_PARALLEL=4 scripts/fuzz.sh 20s ran the 27 targets on fe50885, FuzzDecodeRelease among them, with no failing input. The previous run, on 6 October 2026, covered the 26 targets of v0.14 on 39b2033.
  • Earlier: 60 s per target on 69dbb0c, clean (docs/HANDOFF.md, 6 October 2026).

datekeys-ts (Node.js 20 or later)

cd datekeys-ts
npm ci
npm run verify          # svelte-check, typecheck, tests with coverage thresholds, build and its check
npm run testdata:check  # testdata/ equals ../datekeys-go at the recorded commit

Coverage thresholds are 100 % for the cryptographic and format modules listed in its README. A guard test fails if a file of testdata/ is not used by any test, and src/lib/dependencies.test.ts pins the exact runtime dependencies. On 7 October 2026, npm run verify passed with 8 273 tests (1 skipped) on 2c305cf, the release commit of 0.5.0, with testdata/ at b6ff17a (testdata/SOURCE.json).

datekeys-dart (Dart SDK 3.13 or later; Node.js for the JavaScript run)

cd datekeys-dart
dart pub get
tool/check.sh           # dart format, dart analyze --fatal-infos, dart test, dart test -p node,
                        # and testdata/ against ../datekeys-go

On 7 October 2026 the gate passed on b53afdc with 2 286 tests on the VM and 720 on Node, with testdata/ at b6ff17a (150 files).

3. Shared test vectors (datekeys-go/testdata/)

Generated by the reference implementation (go run ./internal/testkit/genfixtures -out testdata). The .dkc and .dkk fixtures, security_cms.json and locator.json hold randomness and are frozen. TypeScript and Dart copy testdata/ from a Go commit and never generate fixtures. Every file says "spec": "0.16". The format of each file is documented in testdata/README.md (1 186 lines, English), so that no Go code needs to be read. At b6ff17a there are 150 files; v0.15 adds vectors/release.json, the five files of releases/ and the field source of mutations.json; v0.16 makes security_cms.json again, with seal_reason, adds 26 cases of drand's JSON to release.json and the annex vector to wordkey.json, and brings two fixtures, format3_time_and_key_words and format3_full_chunk.

File Content Spec
vectors/profile_quicknet.json Quicknet Provider Profile: canonical CBOR and profile_hash §11, §12
vectors/quicknet_rounds.json date → round resolution §15, §16, §65
vectors/dk1.json canonical dk1_ strings, and rejected encodings with their code §18, §19, §66
vectors/cbor.json the CBOR profile, and one block of vectors per schema, CONTROL_CBOR in the three formats §58, CDDL
vectors/tlock_ibe.json H2 of the tlock IBE: the serialisation of a GT element §63 step 11
vectors/release.json the release object: valid and invalid encodings, drand's JSON, each with its result at step 10 (ERR_NON_CANONICAL_CBOR, ERR_UNSUPPORTED_VERSION, ERR_PROFILE_MISMATCH, ERR_ROUND_MISMATCH, ERR_RELEASE_INVALID); and the lookups of a local release archive. Since v0.16, 38 cases of drand's JSON, 26 of them for the strict reading: repeated names, escaped names, ROUND, rounds with a fraction, an exponent, a sign, 0 or 2^53, lone surrogates §47.1, §50, §63 step 10 (v0.15, v0.16)
releases/<round>.cbor the release object of each published round the fixtures use: 1000, 1001, 1004 and 2000 (111 bytes each) §47.1 (v0.15)
releases/archive_1000_1004.bin a local release archive in the informative format of §50, rounds 1000 to 1004, with 1002 and 1003 missing (zero-filled) §50 (v0.15)
vectors/tlock_steps.json steps 10 and 11 for Quicknet value by value: round message, hash to G1, and the decryption of a tlock stanza with H2, H4, H3 and the file key §63 steps 10 and 11 (v0.14)
vectors/padding.json padding of formats 2 and 3: P for each L, and the PAYLOAD_AGE length §29.1
vectors/paths.json the paths of a format 3 head: rules of one entry, and of the paths of a head §29.5
vectors/path_fold.json the R7 key of segments, and their NFD §29.5, §29.5.1
vectors/head_schema.json format 3 heads and the result of decoding them §29.4 to §29.6, §69.1
vectors/security.json security areas in the context of a capsule, their verdicts and lines §29.3, §29.7, §29.9
vectors/security_cms.json security areas with an alg 2 signature or a seal_type 2 seal, with context, verdicts, results and lines; made again for v0.16 (143 cases), with the reason of S5, seal_reason §29.7, §29.10, §29.11
vectors/ed25519_strict.json Ed25519 signatures and the result of the strict profile §29.9
vectors/note.json public note data and the result of its rules §24.1, §29.6
vectors/resolved_ip.json the IP a locator name resolves to, NAT64 included, and whether a reader may connect §44.1 (v0.13)
vectors/wordkey.json key of words: the words of a text, what a writer refuses, the derived identity; since v0.16 the text of the annex vector, also with its marks apart §38.1, §64, §79.7
vectors/locator.json the datekeys.capsule extension, its envelope and locator, and what a reader rejects and uses §44.1, §64
vectors/mutations.json the mutation corpus: 222 cases, the 178 mutations of §64 and further cases. Since v0.15 each case names its release source: supplied (a release in hand, 220 cases) or network (2 cases); four cases are new (cases 219 to 222), and «round not reached yet» now opens with a release in hand §63, §64
vectors/inspect_differential.json 5 110 mutations of fourteen fixtures with the verdict of steps 1 to 8 §63
fixtures/<name>.dkc, <name>.json official capsules and every intermediate value §67
fixtures/<name>.dkk, <name>.dkk.json official access keys §68
fixtures/<name>.plaintext the content of each capsule (formats 1 and 2: the content; format 3: BODY) §67
fixtures/<name>.inspect.json the exact output of datekeys inspect -json §63

Twenty-eight official capsules (testdata/README.md): five of format 1 (v0.8.2, compatibility), seven of format 2 (v0.9, compatibility) and sixteen of format 3, among them format3_signed (alg 1, F4), format3_signed_cms (alg 2, two signers, ECDSA P-256 and RSA 2048, CAdES-T each, F6), format3_sealed (alg 1 and an RFC 3161 seal with accuracy, S4), format3_note, and, since v0.16, format3_time_and_key_words (a key of words, its text in words_text) and format3_full_chunk. Each record embeds the published Quicknet signature that opens it, so every fixture decrypts offline; since v0.15 the same signatures are also in releases/ as release objects. Test secrets (payload_identity, access_material, the seed of the test author key) are in the records on purpose.

4. Dependencies

Go (datekeys-go/go.mod, Go 1.26.8)

No dependency changed in v0.15 or v0.16: go.mod and go.sum are identical at 39b2033, fe50885 and b6ff17a; the TypeScript package.json and lock file change only the package version, to 0.4.0 and then to 0.5.0; the Dart pubspec.yaml and pubspec.lock are identical at 013b069, faa2c4c and b53afdc. The recovery program scripts/recovery uses only modules already in go.mod.

Direct:

Module Version Role (SECURITY.md)
filippo.io/age v1.3.2 age files, X25519, STREAM, header MAC; scrypt for author key files
github.com/drand/tlock v1.2.0 TimeLock, TimeUnlock, ciphertext encoding
github.com/drand/drand/v2 v2.1.7 BLS verification, chain-info hash
github.com/drand/kyber v1.3.2 pairing, IBE
github.com/drand/kyber-bls12381 v0.3.4 BLS12-381 on kilic
golang.org/x/crypto v0.57.0 required for GO-2026-6354 and GO-2026-6355

Indirect: filippo.io/hpke v0.4.0, github.com/BurntSushi/toml v1.6.0, github.com/kilic/bls12-381 v0.1.0 (archived), github.com/nikkolasg/hexjson v0.1.0, go.dedis.ch/fixbuf v1.0.3, go.uber.org/multierr v1.11.0, go.uber.org/zap v1.28.0, golang.org/x/net v0.58.0, golang.org/x/sys v0.48.0, golang.org/x/text v0.42.0, google.golang.org/genproto/googleapis/rpc (2026-07-06 pseudo-version), google.golang.org/grpc v1.84.0, google.golang.org/protobuf v1.36.11, gopkg.in/yaml.v3 v3.0.1. gRPC and protobuf come in through drand/v2 common/chain (SECURITY.md).

The Go standard library provides Ed25519 (with strict checks in internal/ed25519strict), RSA, ECDSA, SHA-2 and PBKDF2. CBOR (codec), DER (internal/der) and the CMS/X.509/RFC 3161 reader (internal/cms) are the module's own code.

TypeScript (datekeys-ts/package.json at v0.5.0, exact versions)

Runtime:

Package Version Role
age-encryption 0.3.1 the three age files, with own tlock Identity and Recipient; scrypt for author key files
@noble/curves 2.4.0 BLS12-381 (IBE and release verification), X25519, Ed25519 arithmetic, ECDSA P-256/384/521
@noble/hashes 2.4.0 SHA-1, SHA-2, HKDF
@noble/ciphers 2.4.0 ChaCha20-Poly1305

age-encryption brings @scure/base 2.4.0 and @noble/post-quantum 0.5.4, which carries its own @noble/curves and @noble/hashes 2.0.1. The IBE core (ibe.ts) is derived from tlock-js (MIT); tlock-js itself is not a dependency. Development: TypeScript 5.9.3, Vitest 5.0.1, Vite 8.3.0, Svelte 5.57.1, SvelteKit 2.70.3, svelte-check 4.7.6, adapter-static 3.0.10, @types/node 24.13.6.

Dart (datekeys-dart/pubspec.yaml and pubspec.lock at b53afdc)

  • Runtime: crypto 3.0.7 (SHA-1, SHA-2, HMAC), with typed_data 1.4.0 transitive. Everything else is own code: HKDF, PBKDF2, scrypt, ChaCha20-Poly1305, X25519, Ed25519, BLS12-381, ECDSA, RSA, DER, CMS and CBOR.
  • Development: test 1.31.1 or later (^1.31.1).
  • SDK: Dart >=3.13.0 <4.0.0.

5. Traceability

datekeys-go/docs/traceability.md (262 lines) maps every normative section of the specification to the Go code that implements it and the tests that exercise it, row by row from §3 to §76, with a row for the informative annex §79, and marks cases of §64 not yet in the repository as pending. It is intended for the external reviewer.

At v0.16 in the frozen commit b6ff17a. The rows of v0.16: §29.7 and §29.11 (the reason of S5, capsule.SealReason, Token.HasAccuracy and Token.BTSP), §47.1 (ParseDrandJSON and provider/drandjson.go), §62.1 (Result.Security for rule 19; rules 21 and 22 pending, since no writer asks an authority yet), §67 (the two fixtures) and §79 (the key of words of scripts/recovery). The rows of v0.15: §45 (the Release API answers with the release object), §47.1 (the release object, provider/release.go, FuzzDecodeRelease), §49 (a release in hand), §50 (archives and cache services) and §79 (scripts/recovery). The documentation fixes of v0.14 (22f184c: one drand scheme, 19 normative errors, no signed release of the module yet) are included in that commit.

6. Other documents a reviewer may want

All in the private docs repository; in Spanish:

  • REVISION_completitud_protocolo.md: completeness review against v0.8.2 (29 September 2026), AI-assisted.
  • REVISION_completitud_v0.13.md: completeness review against v0.13 (6 October 2026), AI-assisted.
  • spec_v0.14/decisiones.md: the ten decisions of the v0.14 draft.
  • diseno_recuperacion.md: the design of the long-term recovery (6 October 2026), with the options and the author's decisions, AI-assisted.
  • spec_v0.15/decisiones.md: the decisions of the v0.15 draft (7 October 2026). It describes the .dkr release file, which the author removed before approval; a note at its top says so (spec §76, v0.15 change 4).
  • spec_v0.16/decisiones.md: the eight decisions of the v0.16 draft (7 October 2026), the answer to Astra's review of v0.15, with a note on how they were approved.
  • spec_v0.10/revision_fable.md, spec_v0.11/revision_fable_astra.md: reviews by the AI systems Fable and Astra.

Powered by TurnKey Linux.