Skip to main content

Module canonical

Module canonical 

Source
Expand description

Canonical, deterministic, length-prefixed binary encoding for attestation preimages (T-3.D.0, ADR 0010 §1b, ADR 0014 §“Signed preimage”).

§Why a custom binary encoder

ADR 0010 §1b says: “Verifiers MUST fail closed on unknown or malformed schema_version (no partial verify, no ‘best effort’ decode).” That requires the bytes that go into the Ed25519 signature to be identical across operating systems, serde versions, and language implementations. serde_json does not give that property: object key ordering depends on the preserve_order feature, integer-vs-float coercion can drift, and whitespace policy differs.

We therefore use the same framing pattern as cortex-ledger::hash::event_hash (T-1.B.6): a 1-byte domain tag followed by length-prefixed fields in a fixed order. The encoder lives in cortex-core so every crate that needs to verify a signature gets the same bytes.

§Framing

signing_input = DOMAIN_TAG_ATTESTATION_PREIMAGE          // 1 byte: 0x10
             || schema_version (u16, BE)                  // 2 bytes
             || lp(event_source_variant_tag)              // 1 + N
             || lp(source_field_1) || lp(source_field_2)  // each 8 + N
                ...                                       // (variant-specific)
             || lp(event_id)                              // 8 + N
             || lp(payload_hash)                          // 8 + N
             || lp(session_id)                            // 8 + N
             || lp(ledger_id)                             // 8 + N
             || lp(chain_position OR previous_hash)       // 8 + N
             || lp(signed_at_iso8601)                     // 8 + N
             || lp(key_id)                                // 8 + N

where lp(x) = (x.len() as u64).to_be_bytes() || x.bytes. Big-endian is used for both the schema_version and length prefixes; this is architecture-independent on every CI target.

§Domain tag allocation

cortex-ledger::hash reserves 0x01 for event_hash. The header comment in that module also reserved 0x02 for “audit” and 0x03 for “trace seal” as future-use slots; none of those reservations have shipped. To avoid any chance of collision with that documented reservation block we allocate the attestation preimage tag at 0x10 (decimal 16), opening a fresh domain for cryptographic attestations. Future attestation variants (e.g. rotation envelope) take subsequent values in this block.

Structs§

AttestationPreimage
All material that goes into the Ed25519 signature for an attestation.

Enums§

LineageBinding
Lineage binding for the preimage (ADR 0014 §Replay: “preimage MUST include chain_position or previous_hash).
SourceIdentity
Source-specific identity material that participates in the signed preimage (ADR 0014 §“Signed preimage”: EventSource variant tag + all source-specific fields”).

Constants§

DOMAIN_TAG_ATTESTATION_PREIMAGE
Domain tag for attestation preimage framing. Reserved: 0x10.
DOMAIN_TAG_ROTATION_ENVELOPE
Domain tag for identity-rotation envelope framing. Reserved: 0x11.
SCHEMA_VERSION_ATTESTATION
Schema version for the attestation preimage encoding.

Functions§

canonical_rotation_input
Encode an identity-rotation envelope as a deterministic byte string (separate domain tag — see DOMAIN_TAG_ROTATION_ENVELOPE).
canonical_signing_input
Encode an AttestationPreimage as a deterministic byte string.