# DateKeys test data
Official vectors, fixtures and corpora of the DateKeys Protocol Specification
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
v0.9, generated by the reference implementation. Another implementation
consumes them as they are: this file documents every format, so that no Go code
has to be read. The rules that decide each verdict are in the specification;
this file points to them, and states only what belongs to the files
themselves.
```
go run ./internal/testkit/genfixtures -out testdata
```
regenerates everything except the `.dkc` and `.dkk` fixtures, which are
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
generated once and frozen (spec §67). The records of each fixture
(`< name > .json`, `<name>.dkk.json` , `<name>.inspect.json` ) are recomputed from
its frozen bytes, so the format 1 fixtures of v0.8.2 carry `"spec": "0.9"` and
the fields added since. The local gate (`scripts/check.sh`) and CI run it and
fail if any committed file changes: every file below is exactly what the
implementation computes today.
Conventions for every file:
- JSON in UTF-8, with LF line endings. Binary values are lowercase hex strings.
- `error` , `result` and similar fields hold the normative codes of spec §69, such
as `ERR_NON_CANONICAL_CBOR` .
- `step` is a step of the reading flow of spec §63, 1 to 18. Steps 1 to 8 are the
pre-unlock checks (`datekeys inspect`, `capsule.Inspect` ): no network, no
secret.
- The `spec` field names the version of the specification.
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- `format` is a capsule format, the `VERSION` of the PRELUDE (spec §22): 1 or
2. A writer produces format 2 only; format 1, that of v0.8.2, is still read
(spec §70).
| File | Content | Spec |
|---|---|---|
| `vectors/profile_quicknet.json` | Quicknet Provider Profile: its 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 |
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
| `vectors/cbor.json` | the CBOR profile, and one block of vectors per schema, CONTROL_CBOR in both formats | §58, CDDL |
| `vectors/tlock_ibe.json` | H2 of the tlock IBE: the serialization of an element of GT | §63 step 11 |
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
| `vectors/padding.json` | the padding of format 2: P for each content length L, and the length of PAYLOAD_AGE | §29.1 |
| `vectors/mutations.json` | the mutation corpus: the 88 mutations of §64 and further cases | §63, §64 |
| `vectors/inspect_differential.json` | 4380 mutations of the 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 |
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
| `fixtures/<name>.plaintext` | the content of each capsule, what the reader delivers: in format 2, without its padding | §67 |
| `fixtures/<name>.inspect.json` | the exact output of `datekeys inspect -json` for each `.dkc` | §63 |
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
There are twelve official capsules. Five are in format 1, the fixtures of
v0.8.2, kept for compatibility: `time_only` , `time_only_extensions` ,
`time_and_key_portable` , `time_and_key_recipients` and `empty_payload` . Seven
are in format 2:
| Fixture | Policy | Credentials | L | Padding code | P |
|---|---|---|---|---|---|
| `format2_time_only` | `time_only` | — | 78000 | 2, reforzado | 79872 |
| `format2_time_only_bloque256` | `time_only` | — | 78000, the same content | 1, bloque256 | 78080 |
| `format2_empty_payload` | `time_only` | — | 0 | 2 | 256 |
| `format2_time_only_extensions` | `time_only` | — | 34 | 2 | 256 |
| `format2_time_and_key_portable` | `time_and_key` | a portable `.dkk` ; 15 dummies | 46 | 2 | 256 |
| `format2_time_and_key_recipients` | `time_and_key` | a portable `.dkk` and three X25519 identities; 12 dummies | 41 | 2 | 256 |
| `format2_time_and_key_sixteen` | `time_and_key` | sixteen X25519 identities; no dummy | 41 | 2 | 256 |
The first two have a P above 64 KiB, so their PAYLOAD_AGE has two STREAM
chunks. `format2_time_only_extensions` carries a noncritical PUBLIC_HEADER
extension and a noncritical CONTROL_CBOR extension. The release that opens each
capsule, a published Quicknet signature, is in its `<name>.json` , so they all
decrypt offline.
## Edited files
`mutations.json` and `inspect_differential.json` give each mutated `.dkc` as
edits of a base file, not as its full bytes:
```json
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
{ "base": "time_only.dkc", "edits": [[4, 1, "03"]] }
```
- `base` is a file of `testdata/fixtures` . In `mutations.json` it may be absent:
the base is then the empty file, and the single edit holds the whole capsule.
- An edit is `[at, delete, insert]` : the `delete` bytes at offset `at` of the
base are replaced by the bytes of the hex string `insert` .
- The edits of one file refer to offsets of the unmodified base, are sorted by
`at` and do not overlap. The result is therefore built in one pass: copy the
base up to `at` , append `insert` , skip `delete` bytes of the base, go on with
the next edit, and copy the rest of the base.
- `[0, 78799, ""]` on `time_only.dkc` is the empty file; `"edits": []` is the
base unchanged.
## `vectors/cbor.json`
```json
{
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"spec": "0.9",
"walk": { "max_depth": 3, "max_len": 64 },
"accept": [ { "name": "uint 2^53 eight bytes", "hex": "1b0020000000000000", "value": "9007199254740992" } ],
"reject": [ { "name": "tag", "hex": "c101", "error": "ERR_NON_CANONICAL_CBOR" } ],
"schemas": [ { "block": "extension", "schema": "public_header", "name": "65 extensions", "hex": "a600…", "result": "ERR_NON_CANONICAL_CBOR" } ]
}
```
### Generic vectors: `accept` and `reject`
Each `hex` is checked as exactly one data item of the CBOR profile of spec §58:
major types 0, 2, 3, 4 and 5 only; integers and lengths in their shortest form;
definite lengths; map keys that are unsigned integers in strictly ascending
order; valid UTF-8 text; nothing after the item. `accept` holds the inputs that
pass, `reject` those that fail, all with `ERR_NON_CANONICAL_CBOR` .
The `walk` limits apply as well, as in the reference `codec.Walk` : containers
nest at most `max_depth` deep (a scalar has depth 0, `81818100` has depth 3),
and every byte string and text string has at most `max_len` bytes, every array
at most `max_len` items and every map at most `max_len` entries. The vectors
named "above max_len" or "above max_depth" fail on these limits only.
`value` is present for an accepted unsigned integer: a JSON number up to
2^53 − 1, and a decimal string above, so that no reader loses precision.
Among them: shortest-form boundaries, `a200010101` (the two-key map
`{0: 1, 1: 1}` ), a text with a leading BOM, keys out of order or repeated,
non-integer keys, indefinite lengths, tags, floats, simple values, negative
integers, truncation, lengths beyond the input, trailing bytes, overlong UTF-8
and surrogates.
### Schema vectors: `schemas`
Each vector is one encoded object:
- `schema` names the object and the decoder to run on `hex` :
- `provider_profile` : a Provider Profile (§11), decoded and then validated
as a profile to pin, by rules 1 to 3 of spec §12.1 in their order: the
CDDL with the `period` limit of the reference, the field rules
(`ERR_UNKNOWN_PROFILE`) and the chain-hash self-check
(`ERR_PROFILE_MISMATCH`), whose formula §12.1 gives. No `profile_hash` is
expected (rule 4). A vector that changes a hashed key recomputes
`chain_hash` , unless its name says that the chain hash no longer matches.
- `public_header` : PUBLIC_HEADER (§24). No profile registry is consulted and
no extension is known: a header naming an unpinned profile is valid here
(`ERR_UNKNOWN_PROFILE` comes from the registry at step 4), and critical
extensions are not checked here.
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- `control_cbor` : CONTROL_CBOR (§31), decoded for the capsule format given
by `format` , 1 when the field is absent: the schema version must equal it
(another is `ERR_UNSUPPORTED_VERSION` , layer 2), and keys 6,
`payload_length` , and 7, `padding` , are required in format 2 and not
defined in format 1. The names of the format 2 vectors start with
"format 2: ".
- `dkk_body` : BODY_CBOR of a `.dkk` (§41), without the 12-byte DKK1
prelude.
- `block` names the schema the vector exercises: the same as `schema` , or
`verification_metadata` (the `.dkk` body's key 6 varies) or `extension` (the
PUBLIC_HEADER's key 6, `noncritical_extensions` , varies).
- `result` is `ok` or the error code.
When bytes break several rules, the code is the one of the first failing
layer of spec §69.1: the type tag and the schema version, read first from keys
0 and 1 (layer 2), then the CDDL, the implementation limits included, and the
re-encoding (layer 3), and only then the fields with codes of their own in
ascending key order (layer 4). The objects of these vectors have no frame, so
layer 1 does not apply, and their critical extensions are not checked (see
above).
Each block has a minimal valid object, an unknown key, a missing required key, a
wrong type and values out of size or range. The `extension` block has, besides:
data `40` (empty) and `5801xx` (length not in its shortest form), data of every
other type (text, `null` , integer, map, array, tag, indefinite length), 64 and
65 extensions, an `extension_id` starting with a BOM, the pair U+FF61 and
U+10000 in UTF-8 byte order (valid) and in UTF-16 order (invalid), and
`extension_version` 2^32 − 1 (valid), 2^32 and 2^53 (invalid).
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
The `control_cbor` block has, besides, a key 6 in format 1, where it is not
defined, and in format 2: the minimal control of 103 bytes (L = 0),
`payload_length` 78000, 2^32 + 1 and L_MAX = 2^53 − 2^46 (valid), L_MAX + 1,
2^53 and 2^64 − 1 (invalid), a `payload_length` of 7 or 9 bytes, as an
unsigned integer or with a length not in its shortest form, `padding` 1
(valid), 0, 3, 257 and as a byte string, a missing key 6 or 7, keys 6 and 7
out of order, an unknown key 8, and schema versions 1 and 3
(`ERR_UNSUPPORTED_VERSION`).
#### Implementation limits
The vectors apply the implementation limits of the reference that spec §74
lists: the maximum `extension_id` length, the Provider Profile `period` of one
day, the maximum name lengths and the `public_key` length. The vectors named
"the implementation limit" sit at a limit and are valid; those named "above
the implementation limit" go one past it and are otherwise valid, so that an
implementation without the limit accepts them. The name alphabets, the
`genesis_time` range and the drand rules of the `provider_profile`
validation are not limits: they are rules of spec §12.1. Neither is the
minimum of one byte of `extension_id` (spec §31).
## `vectors/tlock_ibe.json`
H2, the hash of an element of GT in the IBE-CCA with which tlock wraps
FK_TIME: spec §63 step 11, and the paragraph "Serialización de GT en H2" after
the flow.
```json
{
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"spec": "0.9",
"description": "…",
"vectors": [
{ "name": "H2(e(G1, G2)), the generators of G1 and G2", "g1": "97f1…", "g2": "93e0…", "gt": "0f41…", "h2": "cb87319f24560b5231579a09ad79f12e" }
]
}
```
- `g1` , `g2` : a point of G1 and one of G2 in the canonical compressed
encoding of spec §12.2, 48 and 96 bytes; the vector uses the generators.
- `gt` : e(g1, g2), the pairing of G1 × G2 of step 11, in 576 bytes. Over the
tower Fp2 = Fp[u]/(u² + 1), Fp6 = Fp2[v]/(v³ − (u + 1)) and
Fp12 = Fp6[w]/(w² − v), every element is written with its coefficients from
the highest degree to the lowest: c1 then c0 for Fp12, c2, c1 and c0 for
Fp6, c1 then c0 for Fp2, and each element of Fp in 48 bytes big-endian. It
is the order of kilic/bls12-381, which drand/kyber and tlock use.
- `h2` : SHA-256 of the ASCII bytes `IBE-H2` followed by `gt` , truncated to
its first 16 bytes, the length of V.
A reader checks that its pairing of `g1` and `g2` serializes to `gt` and that
its H2 of those bytes is `h2` ; the vector fixes the pairing and the
serialization at once. The same 576 bytes with the twelve coordinates of Fp in
reverse order, c0 first at every level as `Fp12.toBytes` of `@noble/curves`
writes them, give `0118eea9d5971745f71e3c94926f1717` and another FK_TIME.
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
## `vectors/padding.json`
The padding of the payload of a format 2 capsule, spec §29.1: for each content
length L, the length P of the plaintext of PAYLOAD_AGE with each code, and the
length of PAYLOAD_AGE.
```json
{
"spec": "0.9",
"l_max": 8936830510563328,
"vectors": [
{ "l": 78000, "bloque256": 78080, "reforzado": 79872, "payload_age_bloque256": 78296, "payload_age_reforzado": 80088, "e": 16, "s": 5, "last_bits": 11 }
],
"rejected": [8936830510563329, 9007199254740992]
}
```
- `l` : L, the length of the content.
- `bloque256` : P with code 1, 256 · ⌈L / 256⌉, at least 256. `reforzado` : P
with code 2, the larger of that and Padmé.
- `payload_age_bloque256` , `payload_age_reforzado` : the length of PAYLOAD_AGE
for each P, 184 + P + 16 · max(1, ⌈P / 65536⌉): an age header of one X25519
stanza (168 bytes), the 16-byte nonce, and the P bytes in STREAM chunks of
64 KiB with a 16-byte tag each.
- `e` , `s` , `last_bits` : the intermediate values of Padmé, E = bitlen(L) − 1,
S = bitlen(E) and E − S; only for L > 256, and informative.
- `l_max` : L_MAX = 2^53 − 2^46, the largest L.
- `rejected` : lengths above L_MAX, which a writer rejects and which, as key 6
of a control, are `ERR_NON_CANONICAL_CBOR` .
Every number is below 2^53, so a JSON number holds it exactly. The lengths
include both sides of the boundaries where 32-bit arithmetic breaks
(2^31 − 2^25, 2^32 − 2^26, 2^32) and 2^49 − 1, the first L for which a
floating-point logarithm gives an E one too large (P does not change).
## `vectors/mutations.json`
The mutation corpus of spec §64, as frozen data. Each case is a `.dkc` , what
the reader is given to open it, and the exact error and step at which the full
reading flow (`capsule.Open`, §63) must fail.
```json
{
"name": "version changed",
"spec": true,
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"dkc": { "base": "time_only.dkc", "edits": [[4, 1, "03"]] },
"release": { "round": 1000, "signature": "b446…" },
"now": "2023-08-23T15:59:24Z",
"registry": "default",
"network": false,
"frozen": false,
"error": "ERR_UNSUPPORTED_VERSION",
"step": 2
}
```
- `name` : unique, stable.
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- `spec` : true for the 88 mutations listed in spec §64, false for the further
cases of the reference. The cases come in this order: the 33 mutations of
the first two lists of §64 on the format 1 fixtures (cases 1 to 33), 32
further cases (34 to 65), the same 33 mutations on the format 2 fixtures,
named "format 2: …" (66 to 98), the 22 of the third list (99 to 120), and 5
further cases (121 to 125).
- `dkc` : the capsule, as edits of a fixture (see above). The reader gets it as a
seekable file, so that the `capsule_digest` of an offered `.dkk` is checked
before any release request (spec §63 step 9.a).
- `dkk` : the hex of a complete `.dkk` file (prelude and body) offered as the
access credential; absent when none is offered.
- `identities` : age X25519 identities (`AGE-SECRET-KEY-1…`) offered as access
credentials; absent when none.
- `release` : what the release source answers to every request, whatever round
is asked for. The reader must verify it (§51): a case may serve a release of
Follow DateKeys v0.8.2 at f6f2e9f (canonical points, fixed error texts)
testdata is synced from datekeys-go f6f2e9f: mutations.json has 65
cases, the ten new §64 ones at steps 10 and 11 (phase 2, skipped and
counted: 31 run, 34 skipped).
The reference no longer copies library error text into errors, so the
TypeScript uses its fixed texts too: every unreadable age header is
"agewrap: not an age v1 header: malformed, truncated or beyond the
parser limits", with the parser's reason in the error's cause, which the
tests still compare with age's own texts; the profile messages for an
unknown drand scheme and a non-canonical public key follow Go. Against
Go at f6f2e9f, 407,196 differential inputs agree on verdict, code, step,
error text, check details and the full inspect -json output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
another round, a round with the signature of another, or a signature that is
not the canonical encoding of a point (§12.2). `null` means that no release
is available (`ERR_RELEASE_UNAVAILABLE`). The release is supplied directly,
as the caller's own, so one that breaks the rules of step 10 gets the code
of step 10; a source that fetched it over a network would have discarded
it, and the code would be `ERR_RELEASE_UNAVAILABLE` at step 9 (spec §63
steps 9 and 10).
- `now` : the reader's clock, RFC 3339. No release is requested before the round
time of the DateKey.
- `registry` : `default` pins exactly the Quicknet profile of
`profile_quicknet.json` ; `empty` pins none.
- `extensions` : the extensions the application implements. Each entry is known
at `(id, version)` , and its data is valid only when it equals the bytes of
`valid_data` . Each entry is registered in both arrays of every object
(§72), as a Go `extension.Registry` that does not implement
`extension.Placement` : an extension outside its registration counts as
unknown there (§54), so the cases "known critical PUBLIC_HEADER extension
with invalid data", "known critical CONTROL_CBOR extension with invalid
data" and "known critical .dkk extension with invalid data", at steps 4, 14
and 9, depend on it. Absent: the application knows no extension, the state
of the base protocol V1.
- `network` : whether the failure may come after a release request. When false,
the reader must fail without requesting any release (§27, §63): every failure
of steps 1 to 8 and of step 9 before the request (9.a to 9.c).
- `frozen` : the capsule was built once with age randomness; its bytes are kept
and never regenerated. These cases have no `base` .
- `error` , `step` : the expected code and the step of §63 that fails.
Every case reproduces offline: the recorded release stands in for the network.
A reader that implements only steps 1 to 8 can replay every case whose `step` is
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
at most 8: 44 cases, 26 of them from §64. Steps 1 to 8 are summarised in "The
checks of steps 1 to 8" below.
### Credentials and the release: step 9
What happens between step 8 and the release request is spec §63 step 9: for
`time_and_key` only, an offered `.dkk` is checked as an object and then bound
to the capsule (9.a), at least one credential must be offered (9.b), and for
either policy a `now` before the round time of the DateKey fails without a
request (9.c); only then is the release requested. For `time_only` the
credentials play no part: the §64 case "access_policy=time_only with
time_and_key structure" offers a `.dkk` whose `capsule_digest` is that of the
unmutated capsule, and fails at step 12, not at step 9. The codes after the
request, for the release (step 10) and for the identities that open each age
file (steps 11, 13 and 17), are those of spec §63 as well. In this corpus:
- identities are not examined before the release (spec §63 step 13);
- a `release` of `null` is `ERR_RELEASE_UNAVAILABLE` at step 9;
- every `release` is supplied directly, so an invalid one fails at step 10:
the source is not a network source, which would discard it at step 9;
- every `.dkk` offered decodes: the corpus checks step 9.a, not the decoding
of a `.dkk` , whose errors spec §63 also places at step 9.a.
Follow DateKeys v0.8.2 at f6f2e9f (canonical points, fixed error texts)
testdata is synced from datekeys-go f6f2e9f: mutations.json has 65
cases, the ten new §64 ones at steps 10 and 11 (phase 2, skipped and
counted: 31 run, 34 skipped).
The reference no longer copies library error text into errors, so the
TypeScript uses its fixed texts too: every unreadable age header is
"agewrap: not an age v1 header: malformed, truncated or beyond the
parser limits", with the parser's reason in the error's cause, which the
tests still compare with age's own texts; the profile messages for an
unknown drand scheme and a non-canonical public key follow Go. Against
Go at f6f2e9f, 407,196 differential inputs agree on verdict, code, step,
error text, check details and the full inspect -json output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
### Point encodings: steps 10 and 11
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
Ten cases of §64, in each format, test the canonical point encoding of spec
§12.2 and the tlock stanza body `U || V || W` of spec §63 step 11:
Follow DateKeys v0.8.2 at f6f2e9f (canonical points, fixed error texts)
testdata is synced from datekeys-go f6f2e9f: mutations.json has 65
cases, the ten new §64 ones at steps 10 and 11 (phase 2, skipped and
counted: 31 run, 34 skipped).
The reference no longer copies library error text into errors, so the
TypeScript uses its fixed texts too: every unreadable age header is
"agewrap: not an age v1 header: malformed, truncated or beyond the
parser limits", with the parser's reason in the error's cause, which the
tests still compare with age's own texts; the profile messages for an
unknown drand scheme and a non-canonical public key follow Go. Against
Go at f6f2e9f, 407,196 differential inputs agree on verdict, code, step,
error text, check details and the full inspect -json output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
- five edit the tlock stanza body of `time_only.dkc` : U with c0 + p, U the
point at infinity (the byte 0xc0, then zeros), U with the infinity flag
over its own coordinate bits, and bodies of 127 and 129 bytes. Each recomputes the header
MAC of OUTER_TIME_AGE with FK_TIME, so the age header stays authentic and
only the rules of step 11 reject the capsule (`ERR_INTEGRITY`); a reader
whose decoder reduces coordinates modulo p opens the first one;
- three serve the release of `time_only.dkc` with its signature edited: the
point at infinity, the infinity flag over its own coordinate bits, and the
negated signature (the sort flag flipped: a canonical point that does not
verify); a fourth serves the published signature of round 1004 re-encoded
as x + p, over a frozen capsule for round 1004, because no fixture round
has a signature whose x + p fits in 381 bits. All four fail at step 10
(`ERR_RELEASE_INVALID`);
- the last one serves the negated signature with U with c0 + p: step 10
comes first.
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
In format 2 the same ten edit `format2_time_only.dkc` and its release, and the
x + p case has a frozen format 2 capsule for round 1004.
### Format 2: the third list of §64
The 22 cases of the third list of §64 test what format 2 adds:
- the format against the rest of the capsule, with the other `VERSION` , a
public byte (§22, §76): a format 1 `time_and_key` capsule of one stanza
relabeled format 2 fails at step 12, and the other three relabelings at step
14, where the schema version of the control is not the format;
- the 16 stanzas of INNER_ACCESS_AGE: 15, 17, two for one recipient, and an
identity that opens none of them, at steps 12 and 13;
- keys 6 and 7 of CONTROL_CBOR, at step 14;
- the plaintext of PAYLOAD_AGE, at step 17: a padding byte that is not zero,
a plaintext of P − 1 or P + 256 bytes or without its padding, and a control
that declares another code or another L.
Each derives from a fixture without randomness. What it changes is sealed again
with the file keys that the release and the credentials of the fixture open,
FK_TIME and FK_ACCESS, or that its I_PAYLOAD unwraps, FK_PAYLOAD, and with the
nonces of the fixture; a stanza it adds takes its ephemeral scalar from a fixed
seed. So each case is a `base` with edits, and regenerates byte for byte. A
case that changes a `time_and_key` capsule offers the identity of its `.dkk` ,
because the `.dkk` itself would fail at step 9.a: its `capsule_digest` no
longer matches. The last five cases of the corpus offer the `.dkk` and show
that.
## The checks of steps 1 to 8
`mutations.json` and `inspect_differential.json` follow the rules of the
specification for steps 1 to 8, with the `default` registry (Quicknet pinned),
no extension known unless a case lists some, and no secret. The first failure
ends the flow, and within one object the first failing layer decides the code
(spec §69.1):
| Step | Rules | Spec |
|---|---|---|
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
| 1, 2 | magic, truncated prelude, `VERSION` 1 or 2 (the format), FLAGS and RESERVED, `PUBLIC_HEADER_LEN` in 1 to 1048576 and `SEALED_CONTROL_LEN` in 1 to 67108864 | §22, §23 |
| 3 | the PUBLIC_HEADER bytes are present | §23 |
| 4 | PUBLIC_HEADER: layers 2 to 4, the `public_header` decoder of the schema vectors, then the pinned profile of the DateKey and the critical extensions; with no extension known, every `critical_extensions` array fails | §63, §69.1 |
| 5 | the SEALED_CONTROL bytes are present, then its age header, parsed within `SEALED_CONTROL_LEN` bytes: malformed is `ERR_INTEGRITY` , one tlock stanza is required | §28.1 |
| 6 | the age header of PAYLOAD_AGE, from its offset to the end of the file: malformed is `ERR_INTEGRITY` , one X25519 stanza is required | §22, §28.1 |
| 7 | the round time of the DateKey is at most 9999-12-31T23:59:59Z (Quicknet: round 83903165811 at most); a `dk1_` round above it passes step 4 and fails here | §15 |
| 8 | the tlock stanza has exactly two arguments, the canonical decimal round and the lowercase hex chain hash, compared as strings | §63 step 8 |
The reference parses age headers with `filippo.io/age` v1.3.2, whose parser
limits (1024 stanzas, 128 arguments after the type, 2 MiB) spec §74 lists as
implementation limits. No case of these corpora depends on them.
## `vectors/inspect_differential.json`
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
A differential corpus of the pre-unlock checks: 4380 deterministic mutations of
the twelve official `.dkc` fixtures, 365 of each, with the verdict of steps 1
to 8 of §63 as the reference computes it (`capsule.Inspect` with the `default`
registry, no extension known, no network, no secret), by the rules that "The
checks of steps 1 to 8" above points to. The first 1825, those of the five
format 1 fixtures, are the corpus of v0.8.2 unchanged; the seven format 2
fixtures follow. The `format` field of the file describes the layout below in
words; it is not a capsule format.
```json
{
"seed": 20260925,
"bases": [ { "file": "time_only.dkc", "sha256": "99e9…" } ],
"mutations": [
{"base":0,"kind":"flip","edits":[[121,1,"b3"]],"result":"ERR_NON_CANONICAL_CBOR","step":4},
{"base":0,"kind":"flip","edits":[[725,1,"4d"]],"result":"ok"}
]
}
```
- `bases` : the fixtures, with the SHA-256 of their exact bytes. `base` in a
mutation is an index into this list.
- `edits` : see "Edited files".
- `result` : `ok` when steps 1 to 8 pass, or the error code; `step` is the step
that failed, absent when `ok` .
- `kind` names the generator and is informative: `flip` (one bit), `byte` (one
byte replaced), `truncate` , `insert` and `delete` (one to four bytes),
`length` (PUBLIC_HEADER_LEN and SEALED_CONTROL_LEN), `header` (PUBLIC_HEADER
re-encoded with one CBOR-aware change: a key removed, added or retyped, the
type tag, version, `capsule_id` , DateKey or `access_policy` changed, an
extension array added, a head not in its shortest form, keys out of order or
repeated, the whole item tagged, wrapped, made indefinite, truncated or
followed by bytes), `datekey` (the DateKey string alone), `age` (the age
header of SEALED_CONTROL or PAYLOAD_AGE edited: intro line, stanza type,
arguments, stanzas added or removed, body lines, MAC line, line endings).
Most `header` , `datekey` and SEALED_CONTROL `age` mutations also rewrite the
prelude lengths to match; some keep the old ones on purpose.
- `seed` seeds the generator of the reference and is informative too: every
mutation is stored explicitly.
## `fixtures/<name>.inspect.json`
For each official `.dkc` , the exact bytes that `datekeys inspect -json -in
< name > .dkc` prints when run in `testdata/fixtures` : JSON indented with two
spaces, fields in this order, and a final newline. The pre-unlock checks use
the `default` registry.
| Field | Content |
|---|---|
| `file` | the `-in` argument, `<name>.dkc` |
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
| `format` | the capsule format, once step 2 has passed |
| `capsule_id` | hex, once step 4 has decoded the header |
| `datekey` , `profile` , `round` | the canonical `dk1_` string, its profile and round |
| `unlock_at` | the round time of the DateKey, RFC 3339 in UTC, once step 7 passes |
| `access_policy` | `time_only` or `time_and_key` |
| `valid` | true when steps 1 to 8 pass |
| `error` | the code of the failure, absent when valid |
| `checks` | one entry per step run: `step` , `name` , `ok` , `detail` (free text) and, for a failed step, `error` |
`detail` is informative text of the reference; a second implementation compares
at least `step` , `name` , `ok` and `error` , and every other field.
## Existing vectors and fixtures
- `vectors/profile_quicknet.json` : the Quicknet profile fields,
`canonical_cbor` (hex) and `profile_hash` .
- `vectors/quicknet_rounds.json` : `vectors` of `requested` instants (RFC 3339
with nanoseconds) and the resolved `round` and `effective` time, or `error` .
- `vectors/dk1.json` : valid `vectors` with `network` , `round` ,
`canonical_json` , `base64url` and `dk1` ; invalid ones with `input` and the
`error` code (`accepted` would mean the input decodes).
Read capsule format 2 of spec v0.9
Syncs testdata with datekeys-go at spec-v0.9 (7e2d83c) and moves the
reader to the DateKeys Protocol Specification v0.9. Both capsule formats
are read; a format 1 capsule keeps the verdict v0.8.2 gave it.
- framing: the VERSION of the prelude is the capsule format, 1 or 2
(Prelude.format, FORMAT_1, FORMAT_2, isFormat).
- control: decodeControl and encodeControl take the format; schema
version 2 adds payload_length (8 bytes, at most L_MAX) and padding
(1 or 2).
- padding.ts: the rules bloque256 and reforzado of spec §29.1, exact up
to L_MAX with BigInt bit lengths and ceil roundings, and the length of
PAYLOAD_AGE.
- open: exactly 16 stanzas in INNER_ACCESS_AGE of format 2 (step 12), P
at step 16, and at step 17 a plaintext of exactly P bytes whose
padding is zero; only the first L bytes are delivered, never the
padding. Step 17 is recorded when it passes, and step 18 gives the
bytes of content, as the reference does. Opened reports the format, L
and, in format 2, the rule and P.
- inspect: the JSON view carries format, as datekeys inspect -json.
- The page shows the format, warns about format 1, and gives the
padding rule and P once a format 2 capsule opens.
Tests: the twelve fixtures, the 125 mutation cases through open from
memory and from a Blob, the 4380 differential cases, padding.json, the
format 2 CBOR vectors, and padding.test.ts against a BigInt statement of
§29.1. The error texts of the 125 corpus cases were compared with
capsule.Open at spec-v0.9. ibe-vectors.json gains the seven format 2
fixtures from scripts/ibe-go-vectors.go; its frozen values are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
- `fixtures/<name>.json` : for each `.dkc` , its `format` , its SHA-256, the
release that opens it, the hex of the prelude, PUBLIC_HEADER and
CONTROL_CBOR, the DateKey, `capsule_id` , `header_binding` ,
`payload_identity` (I_PAYLOAD, a test secret), the visible stanzas of each
age file, the identities or `.dkk` that open it, `payload_length` (L), the
exact extension data, and the result of every step of §63. In format 2 it
adds `padding` (the code) and `padded_length` (P) and, for `time_and_key` ,
`access_key_stanza` and `identity_stanzas` : the index, from 0, in
`inner_stanzas` of the stanza that the `.dkk` and each identity of
`identities` , in order, open. The other stanzas are dummies; the official
vectors are the only place where that is recorded (spec §39).
- `fixtures/<name>.dkk.json` : for each `.dkk` , its SHA-256, `credential_id` ,
`capsule_id` , `access_type` , `access_material` (a test secret),
`capsule_digest` , extensions and the capsule it opens.