Network Working Group M. Alhemeiri Internet-Draft MBQ Intended status: Experimental 29 October 2026 Expires: 2 May 2027 Post-Quantum Evidence Records with Algorithm Agility (Wathīqa Profile) draft-alhemeiri-wathiqa-pqc-ers-02 Abstract This document describes an evidence-record format for the long-term, verifiable preservation of digitally-signed data across the migration to post-quantum cryptography. It builds on the Evidence Record Syntax (ERS) of RFC 4998 and adds an explicit *algorithm-agility* extension: a record is a chain of signed attestations in which each link re-witnesses the data under a fresh signature primitive and commits to the prior link, so that the authenticity of the data survives the cryptographic break of any single primitive. It specifies the canonical hashing that makes a record reproducibly verifiable across independent implementations, the exact binary encoding a decoder accepts, the authenticated temporal binding that places each link in time (an append-only transparency log à la RFC 6962, whose signed inclusion receipt is _not-after_ evidence), and the verification procedure. A per-link beacon anchor records _not- before_ evidence: from wire version 3 it is authenticated against the beacon's hash chain, with the beacon's classical pulse signature as defence in depth; the Security Considerations say which assumption each check rests on. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 2 May 2027. Alhemeiri Expires 2 May 2027 [Page 1] Internet-Draft PQC Evidence Records October 2026 Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3 1.2. Relationship to RFC 4998 . . . . . . . . . . . . . . . . 3 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4 3. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 5 4. Data Structures . . . . . . . . . . . . . . . . . . . . . . . 6 4.1. Logical structure . . . . . . . . . . . . . . . . . . . . 6 4.2. Canonical chain hash (normative) . . . . . . . . . . . . 7 4.3. ASN.1 DER form (RFC 4998 alignment) . . . . . . . . . . . 8 4.4. Witness receipt . . . . . . . . . . . . . . . . . . . . . 9 4.5. Encoding (normative) . . . . . . . . . . . . . . . . . . 9 4.6. Content address . . . . . . . . . . . . . . . . . . . . . 11 5. Verification . . . . . . . . . . . . . . . . . . . . . . . . 11 6. Signing contexts and the v2 evidence message . . . . . . . . 13 7. Algorithm Identifiers . . . . . . . . . . . . . . . . . . . . 14 8. Security Considerations . . . . . . . . . . . . . . . . . . . 14 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 10.1. Normative References . . . . . . . . . . . . . . . . . . 16 10.2. Informative References . . . . . . . . . . . . . . . . . 17 Appendix A. Implementation status . . . . . . . . . . . . . . . 18 Appendix B. Document History . . . . . . . . . . . . . . . . . . 18 B.1. Changes in -02 . . . . . . . . . . . . . . . . . . . . . 18 B.2. Changes in -01 . . . . . . . . . . . . . . . . . . . . . 19 B.3. Changes in -00 . . . . . . . . . . . . . . . . . . . . . 20 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 Alhemeiri Expires 2 May 2027 [Page 2] Internet-Draft PQC Evidence Records October 2026 1. Introduction A signature proves authenticity _now_. Preserving that proof for decades raises two problems RFC 4998 (ERS) [RFC4998] already addresses — the signing key or algorithm may weaken, and the timestamp authority may change — and one it does not: the signature algorithm itself may be *catastrophically broken* by a quantum computer. NIST's FIPS 203/204/205 [FIPS203] [FIPS204] [FIPS205] (and draft 206) standardise post-quantum primitives, but a record signed today only with a classical or single post-quantum algorithm has no path forward if that algorithm falls. This document profiles ERS for that setting. The core idea, following RFC 4998's Archive Timestamp chain, is to keep extending a record under fresh primitives _before_ the old one is broken, with each extension cryptographically bound to its predecessor, so a verifier can establish an unbroken sequence in which every link was sound at the time it was made. This document describes a format with a complete reference implementation, but the security argument has not undergone independent cryptographic review. 1.1. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 1.2. Relationship to RFC 4998 This profile preserves ERS's central abstraction — an ordered chain of timestamps over a data object, each renewing the evidence — and departs from it in three deliberate ways: 1. *Primitive agility is part of every link.* An ERS ArchiveTimestamp renews evidence chiefly to outrun hash weakening; here each link _also_ changes the signature primitive and records which primitive was in force, so the chain spans a primitive break, not only a hash-strength downgrade. Alhemeiri Expires 2 May 2027 [Page 3] Internet-Draft PQC Evidence Records October 2026 2. *Two serialisations.* The normative interchange form is CBOR [RFC8949]; an alternative ASN.1 DER serialisation, aligned with RFC 4998's ASN.1 structures, carries the same chain for implementations that work in ASN.1 (Section 4.3). The *chain hash* is computed over a canonical JSON form (Section 4.2), independent of either, so cross-implementation byte-equality does not depend on CBOR/DER encoder quirks. 3. *Explicit temporal binding.* Each link's _authenticated_ temporal evidence is an append-only transparency-log inclusion receipt (a signed tree head plus inclusion proof — _not-after_ evidence), verifiable offline and enforced by the verifier when a witness- trust policy is supplied (Section 5). A per-link beacon anchor records _not-before_ evidence: from wire version 3 it carries the beacon pulse record, the certificate it was signed under and, optionally, the successor pulse, and the verifier authenticates it against the beacon's hash chain with the beacon's classical pulse signature as defence in depth (Section 5, Section 8). Wire versions 1 and 2 carry the anchor unauthenticated; a verifier reports that distinctly and never upgrades it. This document is a profile and extension within the ERS family, not a new evidence format. [RFC4998] defines the Evidence Record Syntax whose Archive Timestamp chain the agility extension above builds on. [RFC6283] (XMLERS) is the XML serialisation of that same syntax; the two-serialisation approach here — a CBOR interchange form beside a DER form (Section 4.3) — follows its precedent of one evidence model carried in more than one encoding. [RFC5276] specifies how evidence records are conveyed by the Server-Based Certificate Validation Protocol (SCVP); this profile leaves that transport untouched, and a record in the DER form of Section 4.3 is a candidate payload for it. The EvidenceRecord type referenced in Section 4.3 is the ERS type whose current ASN.1 module is [RFC9169], a restatement of the RFC 4998 and RFC 5276 modules in modern ASN.1 syntax with identical wire encoding; implementers working from ASN.1 tooling take the type from that module. Outside the IETF, BSI TR-03125 (TR-ESOR) [TR-03125] is a national technical guideline for preservation services whose evidence handling is built on ERS; a record in this profile is intended to be usable by such a service as an ERS evidence record carrying an additional, explicitly labelled agility extension, rather than as a competing format. 2. Terminology * *HASH.* SHA3-256 [FIPS202]. Every hash in this document is HASH unless it is named otherwise (the beacon's own values are SHA- 512). Alhemeiri Expires 2 May 2027 [Page 4] Internet-Draft PQC Evidence Records October 2026 * *Content address.* The pair (root, byte_length) identifying the protected data (Section 4.6). * *Chain entry / link.* One renewal layer: a signature over the content address under a stated primitive, an anchor, the hash of the prior link, and an optional witness receipt. * *Anchor.* Per-link _not-before_ evidence: beacon id, epoch, root, self-bound to the link by witnessed_hash == HASH(signature.bytes), and, from wire version 3, one or more _beacon witnesses_ (the pulse record, its certificate, and optionally the successor pulse) against which the verifier authenticates it (Section 5). In wire versions 1 and 2 the anchor is unauthenticated metadata and is reported as such (Section 8). * *Beacon witness.* One beacon's evidence for a link: the full pulse record with the output hashes it commits to, the DER certificate named by the pulse's certificateId, and optionally the next pulse of the same chain, whose previous field commits forward to the anchored pulse. * *Witness receipt.* A signed transparency-log tree head plus an inclusion proof showing the link's signature was logged — the authenticated _not-after_ temporal evidence, enforced when a witness-trust policy is supplied. * *Pinned.* Supplied to the verifier out of band by the relying party. A key, certificate or set carried inside the object being verified is never pinned by being carried. 3. Architecture data ──► content address ──► chain entry v1 (primitive A, anchor, witness) │ prior_chain_hash ▼ chain entry v2 (primitive B, anchor, witness) │ ▼ … extend before A breaks A record is { content_address, chain[] }. Verification (Section 5) walks the chain from v1 outward, requiring each link's signer key to be pinned, each link's signature to verify over the content address under its stated primitive, each non-initial link to commit to its predecessor's chain hash, and (when a trust policy is supplied) each link to carry a valid witness receipt from a trusted witness with monotonic time. Alhemeiri Expires 2 May 2027 [Page 5] Internet-Draft PQC Evidence Records October 2026 4. Data Structures 4.1. Logical structure EvidenceRecord = { content_address: { root: bstr .size 32, byte_length: uint }, chain: [ * ChainEntry ] ; empty: refused at verification } ChainEntry = { version: uint, ; 1 = initial, >1 = extension signature: Signature, anchor: { beacon_id: tstr, epoch: uint, witnessed_at_unix: uint, beacon_root: bstr .size 32, witnessed_hash: bstr .size 32, ; = HASH(signature.bytes) ? chain_index: uint, ; present iff wire_v >= 2 ? certificate_id: tstr, ; present iff wire_v >= 2 ? witnesses: [+ BeaconWitness] ; present iff wire_v == 3 }, prior_chain_hash: bstr .size 32 / null, ; null iff initial ? wire_v: 2 / 3, ; absent for wire version 1 ? not_before: NotBefore / null, ; present iff wire_v >= 2 ? inclusion: WitnessReceipt ; absent when there is none } Signature = { algorithm: tstr, ; see Algorithm Identifiers algorithm_version: uint, bytes: bstr, public_key: bstr, signed_at_unix: uint } NotBefore = { chain_index: uint, pulse_index: uint, output_value: bstr .size 64 } BeaconWitness = { source: tstr, ; e.g. "nist-beacon-v2" pulse: Pulse, ; the full beacon v2 pulse record certificate_der: bstr, ; the certificate the pulse names successor: Pulse / null ; next pulse of the same chain } Alhemeiri Expires 2 May 2027 [Page 6] Internet-Draft PQC Evidence Records October 2026 The CDDL lists every map's fields in the order an encoder writes them, which Section 4.5 makes normative. certificate_id is the SHA-512, in lower-case hex, of the DER certificate the pulse names; not_before is the pulse bound in the signed message (Section 6), and is null on a wire version 2 or 3 link that binds no pulse; a Pulse is the beacon's v2 pulse record, re- expressed as a CBOR map with its hex fields in lower case; certificate_der lets the classical check be repeated offline. witnesses is REQUIRED on a wire version 3 link and MUST NOT appear on any other: a decoder MUST reject a lower-version link that carries it (a legacy anchor presented as authenticated) and a version 3 link without it, or with an empty list. The witness at index 0, the primary witness, is the pulse the signed message binds (Section 6); any further witness is an independent beacon and is OPTIONAL. The signature is computed over a domain-separated message (Section 6) binding the content address, the signing time, and the algorithm identifier, so a signature made for one protocol context cannot be replayed in another. 4.2. Canonical chain hash (normative) prior_chain_hash for link _n+1_ is HASH of the *canonical JSON* encoding of link _n_. The canonical JSON form is RECOMMENDED for all cross-implementation hashing and is defined as: * a JSON object with keys sorted lexicographically, no insignificant whitespace ("," and ":" separators); * octet-string fields encoded as lower-case hex with a _hex key suffix; * exactly these fields per link: { "anchor":{"beacon_id":,"beacon_root_hex":, "epoch":,"witnessed_at_unix":, "witnessed_hash_hex":}, "prior_chain_hash_hex":, "signature":{"algorithm":,"algorithm_version":, "bytes_hex":,"public_key_hex":, "signed_at_unix":}, "version": } Alhemeiri Expires 2 May 2027 [Page 7] Internet-Draft PQC Evidence Records October 2026 A wire version 2 link adds, in the same sorted-key form, "wire_v":2, "not_before" ({"chain_index","output_value_hex","pulse_index"} or null) and "certificate_id"/"chain_index" inside "anchor". A wire version 3 link adds those same keys with "wire_v":3 and, inside "anchor", "witnesses_hex": the HASH of the deterministic CBOR ([RFC8949] Section 4.2) of the array [[source, pulse-json, successor- json-or-null, certificate_der], ...] where each pulse is its canonical JSON (sorted keys, no whitespace, lower-case hex) carried as a text string. The witness list is therefore committed by the chain hash and cannot be exchanged after the link is chained. An implementation MUST produce byte-identical canonical JSON for the same link; this is what lets independent verifiers compute the same chain hash. Note the witness receipt (inclusion) is *not* part of the chain hash — it is supplementary evidence bound to the link by witnessed_hash = HASH(signature.bytes), so attaching or detaching it does not alter the chain. 4.3. ASN.1 DER form (RFC 4998 alignment) An alternative ASN.1 DER serialisation, aligned with RFC 4998's ASN.1 structures, is defined here for implementations that work in ASN.1. The evidence record is carried in a ContentInfo-style wrapper that identifies it by the Wathīqa enterprise OID (Section 7): WathiqaEvidenceRecord ::= SEQUENCE { contentType OBJECT IDENTIFIER, -- 1.3.6.1.4.1.66038.1.1 content EvidenceRecord } -- SEQUENCE { version, -- contentAddress…, chain } The inner EvidenceRecord carries the post-quantum AlgorithmIdentifier OIDs of Section 7 and a leading version INTEGER giving the DER profile. An encoder emits profile 4, whose chain entries carry wire_v, the anchor's chain_index and certificate_id, and an OPTIONAL NotBefore SEQUENCE. A decoder accepts the wrapped form with inner profile 4 or 3 and the legacy bare form (no wrapper) with profile 1 or 2, distinguishing the two by the tag of the leading inner element (OBJECT IDENTIFIER vs INTEGER). A decoder MUST reject a record whose contentType is not the Wathīqa evidence OID, a wrapped record whose inner profile is not the one its shape decodes as, a bare record claiming profile 3 or later, a non-minimal length or INTEGER, and trailing bytes. The DER form carries the signed chain only. It does not carry witness receipts (inclusion) or beacon witnesses, and profile 4 accepts wire versions 1 and 2 only: a record containing a wire version 3 link has no DER form in this revision. For a record without receipts whose links are all wire version 1 or 2, the DER Alhemeiri Expires 2 May 2027 [Page 8] Internet-Draft PQC Evidence Records October 2026 form round-trips with the CBOR form. The detailed ASN.1 module is tracked in the implementation (asn1_der.py, authoritative; Rust der.rs in lock-step); a future revision will inline it. 4.4. Witness receipt WitnessReceipt = { schema: "wathiqa.witness_receipt.v1", witnessed_hash: bstr .size 32, ; = HASH(link signature.bytes) leaf_index: uint, sth: SignedTreeHead, inclusion_proof: [ * bstr .size 32 ] } SignedTreeHead = { schema: "wathiqa.sth.v1", log_id: tstr, tree_size: uint, root: bstr .size 32, timestamp_unix: uint, signature: Signature ; as in a chain entry } The Merkle tree follows [RFC6962] hashing (leaf = HASH(0x00 || data), node = HASH(0x01 || left || right)), with HASH as the hash; the logged data of a link is its witnessed_hash. The tree head's signature is made over the content address (Section 4.6) of the octets "wathiqa.sth.v1" || 0x00 || len(log_id)(4, BE) || log_id-utf8 || tree_size(8, BE) || root(32) || timestamp_unix(8, BE) under the signing context wathiqa.sth.v1 (Section 6). A receipt verifies offline: check that the tree head's signer key is pinned, check the tree head's signature, then check that the inclusion proof connects witnessed_hash at leaf_index to the tree head's root. 4.5. Encoding (normative) Every structure of this document is carried in exactly one byte form. A decoder MUST accept that form and refuse every other, so that one sequence of bytes can never be read as two records, and two encodings of one record can never both be accepted. Alhemeiri Expires 2 May 2027 [Page 9] Internet-Draft PQC Evidence Records October 2026 *Field-order family.* The evidence record and everything inside it (the content address, chain entries, signature, anchor, not-before claim and beacon witnesses with their pulses), the witness receipt and the signed tree head (Section 4.4), whether standalone or inside a record, are encoded with: * each map's fields in the order Section 4.1 and Section 4.4 list them, an optional field taking its place in that order when present; * the deterministic rules of [RFC8949] Section 4.2.1 other than key order: every argument in its shortest form and every length definite; * text-string map keys only; * no tags anywhere; * no simple value other than null, and no floating-point value. *Bytewise family.* The same implementations carry other structures that this document does not define (signing envelopes, trust-anchor bundles, attestations, provenance manifests, the pulses of the implementation's own beacon service). These use the key order of [RFC8949] Section 4.2.1: keys sorted by the bytewise lexical order of their deterministic encodings, a tag only where that structure's own format defines one, on the outermost item, and no simple values. Where the bytes sit fixes the family: a witness receipt or tree head carried inside a bytewise-family structure is encoded in that family, and a NIST pulse inside an evidence record is a field-order map. *The round-trip rule.* For either family a decoder MUST, after reading the structure, re-encode it with the encoding rules above and compare the result with its input; if the bytes differ, the input is refused. This one rule enforces both families, and it is the rule Section 8 ("Canonical-form attacks") relies on. A decoder MUST refuse, before reading any field as a value: * a map with two keys whose encodings are identical, whatever their type; * a tag the format does not define at that position; tag 55799 (self-described CBOR) is never defined, at any position; * a non-shortest argument, an indefinite-length item, or bytes after the top-level item. Alhemeiri Expires 2 May 2027 [Page 10] Internet-Draft PQC Evidence Records October 2026 The exact form also fixes what is absent and what is present: * inclusion is absent when a link has no witness receipt. It is never null; a link carrying "inclusion": null MUST be refused. * wire_v is absent for wire version 1 and present for versions 2 and 3; a link carrying "wire_v": 1 MUST be refused. * not_before, anchor.chain_index and anchor.certificate_id are absent for wire version 1 and present for versions 2 and 3 (not_before possibly null). * A map holding a field the exact form does not write (an unknown field) MUST be refused, as must a map missing a field the exact form writes, or holding null where the field is omitted. Extensions to these structures come with a new version number (a new wire_v value, a new schema string), never as extra fields in an existing version: an existing decoder refuses the extended object rather than reading past what it does not understand. An implementation MAY refuse an encoded structure larger than 16 MiB or nested more than 256 levels deep; the reference implementation does both. 4.6. Content address The data is split into 4096-byte chunks; the last chunk is padded with zero octets to 4096 octets. Each chunk's leaf hash is HASH(0x00 || chunk) and the leaves form an [RFC6962] Merkle tree (interior node HASH(0x01 || left || right), split at the largest power of two below the leaf count, so an unpaired node is carried up, never duplicated). root is that tree's root and byte_length the data's length in octets before padding. Empty data has the single leaf HASH(0x00), which is its root, and byte_length 0. Both values are bound into every signature (Section 6). 5. Verification A verifier is given the protected data D, the record, a set of pinned signer public keys S, and OPTIONALLY a set of pinned witness public keys W. It MUST: 1. Recompute the content address of D (Section 4.6) and check it equals record.content_address. 2. Refuse a record whose chain is empty. Alhemeiri Expires 2 May 2027 [Page 11] Internet-Draft PQC Evidence Records October 2026 3. Check that the public key of every link is in S, before any signature is verified. A record with any link outside S is refused, and the refusal names the links. A verifier given no S checks each link under the key the link carries; that is a self- consistency check, not a verdict, and the verifier MUST report that no signer was pinned instead of reporting acceptance. 4. For each link, in chain order, with prev = the link before it (none at position 0): (a) Verify signature over the content address under signature.algorithm and the signing context of the link's wire version (Section 6). Reject on failure. (b) By position, not by the version field: the link at position 0 MUST have version == 1 and prior_chain_hash == null; every later link MUST have a version strictly greater than prev.version and prior_chain_hash == HASH(canonicalJSON(prev)). (c) If W is supplied (temporal-binding enforcement): require inclusion to be present and valid (Section 4.4); require inclusion.witnessed_hash == HASH(signature.bytes); require the tree head's signer key to be in W; and require tree-head timestamps to be non-decreasing along the chain. (d) Beacon anchor. Require anchor.witnessed_hash == HASH(signature.bytes). If wire_v == 3, check each witness in order. A witness whose source has no pinned certificate set is SOURCE_UNPINNED, before any pulse check: a pulse is never checked against the certificate the witness carries alone. Otherwise require ALL of: the pulse is well-formed; certificateId == SHA- 512(certificate_der) and that certificate is in the source's pinned set; the pulse signature verifies under it; and outputValue == SHA-512(serialization || signatureValue). For the primary witness further require that anchor.epoch equals the pulse index; anchor.chain_index (when not 0) and anchor.certificate_id (when not empty) equal the pulse's; anchor.beacon_root == HASH(outputValue || pulseIndex), with the pulse index as ASCII decimal digits; anchor.witnessed_at_unix is the pulse's timestamp in Unix seconds; and the link's not_before is not null and names exactly this pulse (chain index, pulse index, outputValue). Any further witness MUST lie within one beacon period of anchor.witnessed_at_unix. If a witness carries a successor, require it to authenticate under the same certificate, to be the next index of the same chain, to have its previous value equal the anchored outputValue, and to have a timestamp no earlier than the pulse's. Report one verdict per link: INVALID if any witness fails a check; otherwise Alhemeiri Expires 2 May 2027 [Page 12] Internet-Draft PQC Evidence Records October 2026 SOURCE_UNPINNED if any witness is unpinned; otherwise AUTHENTICATED if every witness carries an authenticated successor, AUTHENTICATED_NO_SUCCESSOR if not, and CHAIN_CONFIRMED where an optional online re-fetch of the primary pulse agreed (a re-fetch that disagrees is INVALID). If wire_v < 3, report LEGACY_UNAUTHENTICATED and perform no further anchor check. An INVALID or SOURCE_UNPINNED anchor MUST fail the link whatever the policy; a LEGACY_UNAUTHENTICATED anchor MUST NOT be upgraded and fails the link only under a policy that requires authenticated anchors. 5. Accept iff every link passed. Acceptance means: there exists an unbroken sequence of attestations, each made by a signer the relying party pinned, in which each primitive was applied while sound, the data was unchanged throughout, and (under a trust policy) each step was publicly logged by a trusted witness in monotonic time. Which primitives a relying party still trusts at verification time is the relying party's policy input, not a property of the record. 6. Signing contexts and the v2 evidence message Every signature commits to a context tag so a signature for one protocol cannot be replayed in another. The base message layout is: context-utf8 || 0x00 || algorithm-utf8 || 0x00 || root(32) || byte_length(8, big-endian) || signed_at_unix(8, big-endian) || extra extra is empty for every v1 context. Evidence-record links produced from wire profile v0.3 onward sign under wathiqa.evidence.v2 with a fixed-width extra tail: signer_id(32) -- HASH of the signer's public key prior_flag(1) || prior(32) -- 0x00 + zeros = genesis; 0x01 + hash = link nb_flag(1) || nb_chain(8, BE) || nb_pulse(8, BE) || nb_output(64) -- 0x00 + zeros = no not-before binding; -- 0x01 = NIST Beacon 2.0 pulse claim A chain entry declares its rule on the wire via wire_v: absent = 1, the legacy rule under wathiqa.evidence.v1, which verifiers MUST support indefinitely; 2 = the rule above; 3 = the same signed message as 2, with the anchor's beacon witnesses as verifier-side evidence bound through the not-before claim (no new signing context). Any other value MUST be rejected at decode. Mixed chains are legal: a v1 Alhemeiri Expires 2 May 2027 [Page 13] Internet-Draft PQC Evidence Records October 2026 record extended under v0.3 gains v2 entries. The not-before pulse claim is a signed CLAIM; on a wire version 3 link it is authenticated by step 4d of Section 5. Other contexts are unchanged: wathiqa.evidence.v1 (legacy record links), wathiqa.sth.v1 (transparency-log tree heads), wathiqa.witness_roster.v1 (witness-key succession), and others per protocol. 7. Algorithm Identifiers The algorithm strings an implementation of this profile recognises are SLH-DSA-SHAKE-256s ([FIPS205]), ML-DSA-87 ([FIPS204]) and Falcon-1024 (the pre-standard Falcon, pending FIPS 206). In the DER form (Section 4.3) SLH-DSA and ML-DSA are identified by their NIST CSOR OIDs (2.16.840.1.101.3.4.3.30 and 2.16.840.1.101.3.4.3.19); Falcon-1024 is carried under an experimental OID (1.3.9999.3.6) that is not for interchange and will be replaced when FIPS 206 assigns FN- DSA its identifier. The Wathīqa-specific structures are identified under the IANA Private Enterprise Number arc 1.3.6.1.4.1.66038 (PEN 66038, registered at IANA to "Wathiqa PQC"). An implementation MUST treat the algorithm string and the OID as equivalent identifiers of the same primitive and MUST fail a link whose algorithm it does not recognise (rather than accepting it unverified). 8. Security Considerations * *Agility window.* The scheme protects data only if each link is added _before_ the prior primitive is broken; an operational renewal policy (out of scope for this document) is REQUIRED. A record left un-renewed past a primitive's break is no stronger than that primitive. * *Whose key signed.* Every link carries the public key it was signed with, so a record that verifies under its own keys says nothing about who made it: anyone can replace a document and its record and sign both with a key of their own. The signed message binds the key (Section 6); only the relying party's pinned set S says whose it is. This is why step 3 of Section 5 is not optional, and why every renewal link, not only the initial one, is checked against S. * *Temporal trust over decades.* The witness keys in W must themselves survive rotation; this profile recommends a quorum- authorised, append-only witness-key succession pinned to a single long-lived anchor. Without it, W is unmaintainable on a century scale. Alhemeiri Expires 2 May 2027 [Page 14] Internet-Draft PQC Evidence Records October 2026 * *Beacon anchor: what it proves, and under which assumption.* A wire version 3 link carries an _authenticated_ beacon anchor (Section 4.1): the full beacon pulse record with the five output hashes it commits to, the certificate the pulse was signed under, and optionally the successor pulse. The link's signed message binds the pulse's outputValue (Section 6), a 512-bit value that was unpredictable before the pulse was released, so the signature is _not-before_ the pulse. Two assumptions are involved and MUST be kept apart. The beacon's own pulse signature is *classical* (RSA, [NIST-BEACON]); verifying it under the pinned certificate is defence in depth at sealing time and a repeatable offline check afterwards, but a post-quantum adversary who breaks RSA can forge a pulse record with any timestamp. The *post-quantum* claim therefore rests on the beacon's hash chain: every pulse's outputValue is the SHA-512 of its signed serialization and signature, every pulse commits to its predecessor's outputValue, and the successor carried in the anchor commits forward to the anchored pulse. What a verifier can establish from the record alone is that the link commits to a pulse value that is internally consistent with a chain context; placing that value in the chain the beacon actually published requires either the classical signature or an independently obtained copy of the chain (a live fetch, or an archive kept by the verifier). Implementations SHOULD keep such a copy for records they expect to verify beyond the life of the beacon's RSA keys, and MUST report the anchor verdict distinctly (Section 5): a legacy unauthenticated anchor MUST be reported as such and MUST NOT be upgraded to authenticated by any verification step. * *Beacon certificate rotation.* A pulse names its certificate by certificateId; a verifier MUST pin certificates out of band, per source name matched exactly, and MUST fail closed when the source has no pinned certificate, when the named certificate is not pinned, or when the signature does not verify under it. On 2026-09-05 the reference implementation observed live pulses that named a newly issued certificate and carried signatures that verified under neither the new nor the previous key; this document does not state a cause. The sealing rule, verify the pulse before binding it and refuse otherwise, covers that situation. * *Fail-closed verification.* A verifier MUST treat any malformed field, unrecognised algorithm, or unverifiable proof as verification failure, never as success. * *Canonical-form attacks.* Because the chain hash is over a canonical form, implementations MUST reject inputs that do not round-trip to that exact form (Section 4.5: non-minimal numbers, duplicate keys, tags, unknown fields), to deny an attacker a Alhemeiri Expires 2 May 2027 [Page 15] Internet-Draft PQC Evidence Records October 2026 second pre-image via encoding ambiguity. Before this rule was enforced at decode, a key given twice, once behind tag 55799, was read as one value by some implementations and as the other by the rest. 9. IANA Considerations The Wathīqa structures of Section 4 are identified under *IANA Private Enterprise Number 66038* (1.3.6.1.4.1.66038), already registered — no further OID registration is requested for them. Still *outstanding* (a separate IANA process, not yet filed): registration of the two media types application/wathiqa-evidence+cbor and application/wathiqa-evidence+der. 10. References 10.1. Normative References [FIPS202] National Institute of Standards and Technology, "SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions", FIPS 202, August 2015, . [FIPS204] National Institute of Standards and Technology, "Module- Lattice-Based Digital Signature Standard", FIPS 204, August 2024, . [FIPS205] National Institute of Standards and Technology, "Stateless Hash-Based Digital Signature Standard", FIPS 205, August 2024, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC4998] Gondrom, T., Brandner, R., and U. Pordesch, "Evidence Record Syntax (ERS)", RFC 4998, DOI 10.17487/RFC4998, August 2007, . [RFC6962] Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . Alhemeiri Expires 2 May 2027 [Page 16] Internet-Draft PQC Evidence Records October 2026 [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [RFC9169] Housley, R. and C. Wallace, "New ASN.1 Modules for the Evidence Record Syntax (ERS)", RFC 9169, DOI 10.17487/RFC9169, December 2021, . 10.2. Informative References [FIPS203] National Institute of Standards and Technology, "Module- Lattice-Based Key-Encapsulation Mechanism Standard", FIPS 203, August 2024, . [NIST-BEACON] National Institute of Standards and Technology, "A Reference for Randomness Beacons: Format and Protocol Version 2", NIST IR 8213 (draft), May 2019, . [RFC5276] Wallace, C., "Using the Server-Based Certificate Validation Protocol (SCVP) to Convey Long-Term Evidence Records", RFC 5276, DOI 10.17487/RFC5276, August 2008, . [RFC6283] Jerman Blazic, A., Saljic, S., and T. Gondrom, "Extensible Markup Language Evidence Record Syntax (XMLERS)", RFC 6283, DOI 10.17487/RFC6283, July 2011, . [TR-03125] Bundesamt für Sicherheit in der Informationstechnik (BSI), "BSI TR-03125 Preservation of Evidence of Cryptographically Signed Documents (TR-ESOR), Version 1.3", BSI TR-03125, n.d., . Alhemeiri Expires 2 May 2027 [Page 17] Internet-Draft PQC Evidence Records October 2026 Appendix A. Implementation status A reference implementation (Python) is authoritative for the wire formats. A TypeScript verifier decodes all three wire versions in the exact form of Section 4.5. A JavaScript SDK and a Rust port read wire versions 1 and 2, refuse wire version 3 at decode, and reproduce the canonical chain hash byte-for-byte for the versions they read. All of them are run against one shared suite of test vectors, including encoding-level negatives (non-shortest arguments, tags, duplicate keys, unknown fields, wrong schema strings), and must reach the same verdict on each. This draft documents the reference implementation's formats; divergences are implementation bugs, not intended profile variation. Appendix B. Document History B.1. Changes in -02 * New Section 4.5: the exact byte form per structure family (field order, or RFC 8949 Section 4.2.1 bytewise order), one round-trip rule for both. * Section 4.5: duplicate keys, undefined tags (55799 included) and unknown fields are refused at decode. * inclusion is absent when there is no receipt, never null (Section 4.1, Section 4.5). * wire_v is absent for wire version 1; "wire_v": 1 is refused. * Extensions come with a version change, never as extra fields. * Section 4.1: fields listed in encoder order (inclusion last). * Section 4.1: chain_index, certificate_id and not_before present exactly from wire version 2. * New Section 4.6: the content address defined (4096-octet chunks, zero padding, RFC 6962 tree, empty data). * Section 4.4: schema strings, field order and the tree head's signed octets added. * Section 5: pinned signer keys S required for a verdict; every link checked against S before any signature. * Section 5: an empty chain is refused. Alhemeiri Expires 2 May 2027 [Page 18] Internet-Draft PQC Evidence Records October 2026 * Section 5: link order checked by position, versions strictly increasing. * Section 5: SOURCE_UNPINNED verdict and the exact anchor checks added. * Section 6: wire version 3 added to the accepted values. * Section 4.3: encoder emits DER profile 4; decoder accepts 3 and 4 wrapped, 1 and 2 bare. * Section 4.3: no receipts, beacon witnesses or wire version 3 in DER. * Section 7: the three algorithm strings and their OIDs listed. * Security Considerations: "Whose key signed" added; pin certificates per source. * Implementation status restated per implementation and wire version. * Sections 1.2, 4.3 and Appendix A reworded: the DER form is an alternative serialisation; Appendix A says how implementations are checked. * PEN 66038 stated as registered to "Wathiqa PQC"; no cause stated for the beacon observation. * Author affiliation MBQ, Abu Dhabi; date and version updated. B.2. Changes in -01 * Authenticated beacon anchors (wire version 3, Section 4.1): the anchor carries the pulse record, its certificate and optionally the successor pulse; the verifier authenticates it (Section 5, step 2d in -01) and reports a distinct verdict; legacy anchors are reported, never upgraded. * Security Considerations rewritten to state which assumption each anchor check rests on: the beacon's pulse signature is classical; the post-quantum not-before claim rests on the hash chain, and on an independently held copy of it for verification beyond the life of the beacon's keys. * Canonical chain hash extended for wire version 3 (Section 4.2). Alhemeiri Expires 2 May 2027 [Page 19] Internet-Draft PQC Evidence Records October 2026 B.3. Changes in -00 -00 was the initial public revision. The following changes were made in the pre-submission revisions that preceded it: * Wire profile v0.3: chain entries carry wire_v (version gate); the v2 signed message binds the signer identity, the prior chain hash, and an optional NIST-pulse not-before claim (Section 6). v1 records remain verifiable indefinitely. * Anchor structure gains chain_index and certificate_id (beacon chain and pulse-certificate pinning for authenticated re- verification). * ASN.1 DER profile v4 (per-entry wire version, optional NotBefore SEQUENCE, extended anchor); v1–v3 remain decodable, only v4 is emitted. * The machine-checked model now proves the strengthened per-link property: acceptance implies an honest attestation of (document, algorithm, POSITION), or a prior primitive break. Author's Address Mohamed Alhemeiri MBQ Abu Dhabi United Arab Emirates Email: Mohamed.Alhemeiri@mail.utoronto.ca Alhemeiri Expires 2 May 2027 [Page 20]