You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/spec/datekeys.cddl

306 lines
14 KiB

; DateKeys Protocol Specification v0.11 (working draft) - CBOR schemas (RFC
; 8610 CDDL).
;
; Normative companion of spec/DateKeys_Protocol_Specification_v0.11.md. The
; reference implementation g.activething.com/go/DateKeys still implements
; v0.9, whose schemas are in tag spec-v0.9. These schemas include the three
; control versions: 1, of capsule format 1 (v0.8.2), 2, of format 2 (v0.9),
; and 3, of format 3, and the security and head objects of format 3.
;
; Encoding rules that CDDL cannot express (spec section 58, 58.1):
; - Every structure uses the CBOR profile of the protocol (spec section 58):
; Deterministic CBOR (RFC 8949 section 4.2.1) restricted to major types 0,
; 2, 3, 4 and 5, with unsigned integer map keys in strictly ascending
; order, shortest-form integers and lengths, definite lengths only and
; valid UTF-8 text. Negative integers, tags, floats, simple values
; (including null) and indefinite lengths are rejected.
; - A decoder re-encodes what it decoded and rejects any byte difference
; (ERR_NON_CANONICAL_CBOR).
; - A semantically absent optional field is omitted. Empty arrays, empty
; maps, null, "" and h'' never stand for absence; the .size and non-empty
; constraints below make those forms invalid.
; - Maps are closed: keys not listed here are rejected. New semantics go in
; extensions (spec section 54).
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; - The elements of each extension array are in strictly ascending order of
; the UTF-8 bytes of extension_id (spec section 54): bytes compared as
; unsigned integers, the first differing byte decides and a proper prefix
; sorts first; never UTF-16 code units, case folding, Unicode
; normalization or a locale collation. U+FF61 (ef bd a1) sorts before
; U+10000 (f0 90 80 80). The strict order also forbids a repeated
; extension_id within an array, and no extension_id appears in both
; arrays of one object, so an extension_id appears at most once per
; object.
; - A violation of a normative rule of this schema, including .size,
; integer ranges and the 64-extension maximum, is ERR_NON_CANONICAL_CBOR
; unless spec section 57 names a more specific error (schema version,
; compact_datekey, access_type and access_material, Provider Profile
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; names and public key). Those rules are checked with the fields, after
; the rest of this schema; here a field needs only the CBOR type of its
; rule, and another type is ERR_NON_CANONICAL_CBOR. The implementation
; limits marked below are not normative; spec section 74 lists them,
; with the limits of the reference outside this schema, and an
; implementation that applies them uses the same mapping.
; - The schema version of a control (key 1) is the one spec section 22
; assigns to the format of its capsule, the VERSION of the PRELUDE:
; control-v1 only in format 1, control-v2 only in format 2 and
; control-v3 only in format 3. A decoder
; picks the rule by the format, and another version is
; ERR_UNSUPPORTED_VERSION, read before the rest of the schema (spec
; section 69.1, layer 2). CDDL cannot express that link.
; - payload-length holds L as an unsigned 64-bit big-endian integer in
; exactly 8 bytes, whatever its value, and a decoder reads all 8 bytes;
; the value is at most max-payload-length (spec section 29.1, 31). A
; larger value is ERR_NON_CANONICAL_CBOR, like any rule of this schema.
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; - When bytes break several rules, the code is the one of the first
; failing layer (spec section 69.1): frame, then type tag and schema
; version (keys 0 and 1; for a control, the version of its capsule
; format), then this schema, then the fields with codes of their own in
; ascending key order.
; - In format 3, security and head sit inside BODY, the plaintext of
; PAYLOAD_AGE (spec section 29.2), whose 12-byte frame (AREA_LEN,
; SECURITY_LEN, HEAD_LEN) CDDL cannot express. A failure of security
; never has an error code: it only changes the verdicts (spec section
; 29.3, 29.7). In head, path lengths (R1) and the path order (R8) are
; rules of this schema (ERR_NON_CANONICAL_CBOR); the other path rules
; and the text rules are checked with the fields (ERR_HEAD_INVALID,
; spec section 29.4 to 29.6), and the paths sort by their UTF-8 bytes,
; like extension_id.
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; Spec section 11 and 12. Spec section 12.1 adds the rules a profile must
; follow to be pinned (ERR_UNKNOWN_PROFILE), among them period at most 2^32-1
Spec v0.8.2 amendment: canonical point encoding; no library error text Amendment of the unreleased v0.8.2, recorded in §76 with its case: the second implementation's phase-2 research found that tlock-js over @noble/curves 1.9.7 accepts U re-encoded as c0 + p and a signature x + p and returns the same file key, while the reference rejects both (noble 1.9.7 differed from kilic on 5,615 of 41,686 encodings), and the spec did not say which encodings are valid. - §12.2 defines the canonical encoding of a BLS12-381 point (drand's compressed ZCash form) and requires decoders to reject every other byte string; §12.1 applies it to public_key. - §63 step 10 applies it to the release signature (ERR_RELEASE_INVALID) and step 11 defines the tlock stanza body U || V || W (96 + 16 + 16 bytes for Quicknet) with a canonical, non-infinity U (ERR_INTEGRITY). - §64 gains ten mutations, exported to mutations.json (65 cases). The signature x + p case uses published Quicknet round 1004, the first after 1000 whose x allows x + p < 2^381. The reference already gave every stated code and step. Errors no longer copy text from tlock, kyber, age, drand or kyber-bls12381. kyber's IBE error carried the candidate plaintext and r, and with one bit of W flipped the message disclosed the real tlock file key with that bit flipped. Every such place now uses a fixed reason with its normative sentinel; TestTlockFailureDiagnosticsCarryNoSecrets fails with the old wrapping. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; and a public key that is the canonical encoding (spec section 12.2) of a
; point of the key group of the scheme, 48 or 96 bytes, other than the point
; at infinity, and the chain-hash self-check, SHA-256(uint32_be(period) ||
; int64_be(genesis_time) || public_key || genesis_seed || network), network
; left out when it is "default" (ERR_PROFILE_MISMATCH).
provider-profile = {
0 => "datekeys-provider-profile",
1 => 1,
2 => profile-id,
3 => name, ; provider, "drand"
4 => name, ; provider network identifier, "quicknet"
5 => bstr .size 32, ; chain_hash
6 => public-key, ; group public key
7 => period, ; seconds; spec section 11: 1..max-safe-uint
8 => 0..max-safe-uint, ; genesis_time, Unix seconds
9 => name, ; scheme, "bls-unchained-g1-rfc9380"
10 => bstr .size 32, ; genesis_seed
}
; Spec section 24. Stored as exact bytes after the 16-byte PRELUDE and covered
; by header_binding = SHA-256(PRELUDE || PUBLIC_HEADER). The same header,
; schema version 1, in all three capsule formats.
public-header = {
0 => "datekeycap",
1 => 1,
2 => capsule-id,
3 => compact-datekey, ; the only source of the profile
4 => access-policy,
? 5 => extensions, ; critical_extensions
? 6 => extensions, ; noncritical_extensions
}
; Spec section 31. Sealed inside OUTER_TIME_AGE (time_only) or inside
; INNER_ACCESS_AGE inside OUTER_TIME_AGE (time_and_key).
control = control-v1 / control-v2 / control-v3
; Capsule format 1 (v0.8.2).
control-v1 = {
0 => "datekeys-control",
1 => 1,
2 => bstr .size 32, ; header_binding
3 => bstr .size 32, ; payload_identity, raw X25519 identity I_PAYLOAD
? 4 => extensions, ; critical_extensions
? 5 => extensions, ; noncritical_extensions
}
; Capsule format 2 (v0.9). 103 bytes without extensions.
control-v2 = {
0 => "datekeys-control",
1 => 2,
2 => bstr .size 32, ; header_binding
3 => bstr .size 32, ; payload_identity, raw X25519 identity I_PAYLOAD
? 4 => extensions, ; critical_extensions
? 5 => extensions, ; noncritical_extensions
Spec v0.9 draft: apply the 22 corrections of the final review The final review of the draft found 22 problems, and none had been applied yet. All of them are applied now, together with four places that repeated them (§62.1 rules 1 and 4, §76 changes 4 and 10). - §29.1, §76 change 4: 32-bit arithmetic first gives a wrong P at L = 2 113 929 217 with signed operators and at L = 4 227 858 433 with >>> 0, not at 2^32 + 1. The vector table gains a row for each, checked against a BigInt Padme. Above 2^32, Padme exceeds bloque256 except at L_MAX. The Node log2 error changes E and lastBits, not P or S. - §56, §76 change 4: a reader MUST NOT present the content as valid before step 17 ends; a streaming reader MUST NOT write the padding and MUST signal the step 17 error so that what it wrote is discarded. The author chose this over the stricter rule, which forbade delivering any byte before step 17 and so the streaming Open(dst) of the reference. - §64: the 15 and 17 stanza mutations recalculate the PRELUDE and header_binding; every time_and_key mutation offers the identity, because any change breaks the capsule_digest of a .dkk; the duplicate recipient mutation names its identity. Three new mutations cover the shape of payload_length (7 or 9 bytes, a CBOR integer); the format 2 cbor.json vectors of §76 list them too. - §39, §62.1 rule 4: the official test vectors may show which slots are dummies. §70, §62.1 rule 1: the format 2 rule binds implementations that write capsules, and a test vector generator MAY write format 1. - §62 step 8 gets the 64 MiB limit of §61 step 6. - Accuracy: §22 (an older reader detects a new padding code only after the network request; the .dkk schema is §41), §37 and §76 change 10 (the §63 rules do not detect those recipients), §55.2 (the writer knows the number of parties; relays are §48), §76 changes 1 and 8. - Wording: §62.1 rules 7 and 11, §63 step 4, §76 change 11, the field names in the CDDL comments, and a v0.9 entry in spec/README.md. go test ./... passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
6 => payload-length, ; payload_length, L, the length of the content (spec section 29.1)
7 => padding-scheme, ; padding, the code of the padding rule of PAYLOAD_AGE (spec section 29.1)
}
; Capsule format 3 (v0.10). The keys of control-v2; L is the length of BODY
; (spec section 29.2). 103 bytes without extensions.
control-v3 = {
0 => "datekeys-control",
1 => 3,
2 => bstr .size 32, ; header_binding
3 => bstr .size 32, ; payload_identity, raw X25519 identity I_PAYLOAD
? 4 => extensions, ; critical_extensions
? 5 => extensions, ; noncritical_extensions
6 => payload-length, ; payload_length, L, the length of BODY
7 => padding-scheme, ; padding, the code of the padding rule of PAYLOAD_AGE
}
; Fixed width, so that the length of CONTROL_CBOR, visible in
; SEALED_CONTROL_LEN, never depends on L (spec section 55.2). Value at most
; max-payload-length (see the rules above). L = 0 is 48 0000000000000000.
payload-length = bstr .size 8
; No code stands for "no padding" (spec section 29.1).
padding-scheme = &(bloque256: 1, reforzado: 2)
; 2^53 - 2^46: the largest L whose padded length P stays within
; max-safe-uint under both padding rules (spec section 29.1).
max-payload-length = 8936830510563328
; Spec section 29.3. SECURITY_CBOR of format 3, inside the area of BODY.
; Version 1 in every later version of the spec that keeps format 3. Keys 2
; and 3 hold separately encoded CBOR, author-signature and seal, with the
; CBOR profile; a failure of their content only changes its own verdict.
; v0.11 defines alg 1 (Ed25519, spec section 29.9), alg 2 (CMS with X.509
; certificates, 29.10) and seal_type 2 (RFC 3161, 29.11); seal_type 1
; (DateKeys) and 3 (OpenTimestamps) stay reserved. A writer writes security
; empty (22 bytes) in a capsule without signature or seal, and never key 3
; with alg 2.
security = {
0 => "datekeys-security",
1 => 1,
? 2 => bstr .size (1..65536), ; author-signature, encoded on its own
? 3 => bstr .size (1..65536), ; seal, encoded on its own
}
author-signature = {
0 => 1..4294967295, ; alg
1 => bstr, ; public key
2 => bstr, ; signature
}
seal = {
0 => 1..4294967295, ; seal_type
1 => bstr, ; token
}
; The author-signature of each alg this version defines (spec sections 29.9
; and 29.10). A reader that does not implement an alg checks only the
; generic author-signature above.
author-signature-ed25519 = {
0 => 1,
1 => bstr .size 32, ; public key A
2 => bstr .size 64, ; signature R || S
}
author-signature-cms = {
0 => 2,
1 => bstr .cbor signers, ; required signers, encoded on its own
2 => bstr, ; ContentInfo of type SignedData, DER, detached
}
; SHA-256 of the DER certificate of each required signer, in strictly
; ascending byte order, without repetitions.
signers = [1*16 bstr .size 32]
seal-rfc3161 = {
0 => 2,
1 => bstr, ; TimeStampToken, DER
}
; Spec section 24.1. data of extension datekeys.note, version 1, in the
; noncritical array of PUBLIC_HEADER: UTF-8 text with the rules of section
; 29.6, not CBOR.
note-data = bstr .size (1..1024)
; Spec section 44.1. data of extension datekeys.capsule, version 1, in the
; noncritical array of a .dkk.
capsule-data = {
? 0 => tstr .size (1..1024), ; note, a copy of the public note
1 => tstr, ; compact_datekey, canonical dk1_
? 2 => bstr, ; locator: an age file with one tlock stanza
}
; Plaintext of the locator, readable at the unlock date.
capsule-locator = {
0 => [1*16 tstr .size (1..2048)], ; addresses (URI)
1 => bstr .size 32, ; capsule_digest
}
; Spec section 29.4. HEAD_CBOR of format 3, at most 16 MiB. Always version 1
; in format 3: a new version needs a new format (spec section 22). These
; limits are normative and fixed with the format.
head = {
0 => "datekeys-head",
1 => 1,
2 => bstr .size 32, ; salt, fresh from a CSPRNG
? 3 => tstr .size (1..16384), ; comment (spec section 29.6)
? 4 => tstr .size (1..256), ; declared_author (spec section 29.6)
? 5 => [1*65535 file], ; strictly ascending UTF-8 bytes of path
? 6 => extensions, ; critical_extensions
? 7 => extensions, ; noncritical_extensions
}
file = {
0 => tstr .size (1..1024), ; path (spec section 29.5)
1 => 0..max-payload-length, ; size
2 => 0..max-payload-length, ; start
3 => 0..max-payload-length, ; end, exclusive
4 => bstr .size 32, ; SHA-256 of the file
? 5 => 0..253402300799, ; mtime, UTC seconds, informative
}
; Spec section 41. BODY_CBOR of a .dkk, after the 12-byte DKK1 prelude.
access-key-body = {
0 => "datekeys-access-key",
1 => 1,
2 => bstr .size 16, ; credential_id
3 => capsule-id,
4 => access-type,
5 => access-material,
? 6 => verification-metadata,
? 7 => extensions, ; critical_extensions
? 8 => extensions, ; noncritical_extensions
}
; Spec section 43. Present only when it holds a digest: never an empty map.
verification-metadata = {
0 => bstr .size 32, ; capsule_digest = SHA-256(exact .dkc bytes)
}
; Spec section 31 and 54.
extensions = [1*64 extension]
extension = {
0 => extension-id,
1 => extension-version,
? 2 => extension-data,
}
extension-version = uint .le 4294967295
; Opaque bytes: the base protocol never decodes or validates the content, and
; an extension without data omits key 2. The effective bound is the frame of
; the containing object (spec section 57); 67108864 bytes (64 MiB) is the
; largest frame, SEALED_CONTROL. Each registered extension declares its own
; maximum (spec section 72).
extension-data = bstr .size (1..67108864)
capsule-id = bstr .size 16
access-policy = &(time_only: 0, time_and_key: 1)
access-type = "x25519"
access-material = bstr .size 32 ; for access-type "x25519"
; 2^53-1: every unsigned integer of the protocol is exact as an IEEE 754
; double (spec section 58).
max-safe-uint = 9007199254740991
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; Names of the Provider Profile (spec section 12.1): the alphabets are
; normative, the maximum lengths of 128 and 64 bytes are implementation
; limits of the reference (spec section 74). A violation is
; ERR_UNKNOWN_PROFILE (spec section 57). profile-id also bounds the network
; of a dk1_ DateKey (ERR_DATEKEY_INVALID there), whose canonical JSON has no
; escapes (spec section 18).
profile-id = tstr .regexp "[a-z0-9][a-z0-9:._-]{0,127}"
name = tstr .regexp "[a-z0-9][a-z0-9._-]{0,63}"
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; Spec section 31: at least 1 byte of valid UTF-8, normative; at most 256
; bytes, an implementation limit of the reference (spec section 74).
extension-id = tstr .size (1..256)
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; Implementation limits of the reference implementation, listed in spec
; section 74, which leaves definitive field limits open.
public-key = bstr .size (1..1024) ; spec section 12.1: 48 or 96 bytes by scheme
period = 1..86400 ; at most one day; spec section 11: 1..max-safe-uint
; Spec section 18 and 19: "dk1_" + unpadded Base64URL of the canonical JSON
; {"version":1,"network":<profile-id>,"round":<round>}, round in 1..2^53-1.
Spec v0.8.2 refinements: error precedence, trust model, strict order Approved refinements, each recorded with its reproducible case in the §76 v0.8.2 subsection: - §69.1: layered error model with normative precedence (frame, type tag and version, CBOR profile and CDDL, then fields with their own code in ascending key order; across steps the §63 order decides), with a scope paragraph for the optional steps 5, 6 and 8. - §55.1: normative trust table per section (who can write it, from which step it is bound, what it never proves); §72: security-relevant claims go in CONTROL_CBOR or under a signature, .dkk data is advisory. - §31/§54: extension arrays in strictly ascending unsigned byte order of extension_id (one rule for order and uniqueness). - Gaps a second implementation needed: §28.1 malformed age headers, §15/§19 latest unlock time and dk1_ reading rules, §22/§23/§57 length lower bounds, §63 step 8 tlock argument comparison and step 9 order, §12.1 profile validation with the drand chain-hash formula, §74 table of implementation limits. Reference alignment: .dkk errors only at step 9.a (new OpenOptions.AccessKeyFile, used by the CLI), CR/LF in dk1_ is ERR_DATEKEY_INVALID, BODY_LEN 0 is ERR_INTEGRITY, nil identities are not credentials, and AccessIdentity tries every identity on every stanza so its verdict does not depend on their order. dk1.json gains three vectors; every other testdata file is byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 weeks ago
; Spec section 15 further bounds the round time of the round to
; 9999-12-31T23:59:59Z under the pinned profile (step 7 of section 63). A
; violation is ERR_DATEKEY_INVALID or ERR_DATEKEY_NON_CANONICAL (spec section
; 19), checked with the fields, not ERR_NON_CANONICAL_CBOR.
compact-datekey = tstr .regexp "dk1_[A-Za-z0-9_-]+"

Powered by TurnKey Linux.