Canonicalization Rule¶
Deterministic normalization rule — instantiates Round-Trip Code Alignment
Collapses every equivalent encoding of the same content onto one stable canonical form, so things that mean the same encode identically and can be compared, signed, cached, or deduplicated byte-for-byte.
A scheme can be perfectly decodable and still leave the same meaning wearing many different costumes — reordered fields, extra whitespace, 1.0 versus 1, one Unicode character spelled two ways. Canonicalization Rule removes that freedom: it maps the many surface-equivalent encodings of a value onto one stable normal form by fixing an equivalence relation — a deterministic decision about which differences carry meaning and which are noise. Its concern is not whether a receiver can decode, but whether two encodings that mean the same thing look the same down to the byte. That identity of form is the precondition for every operation that compares encodings rather than values: signing, hashing, content-addressing, caching, deduplication, and honest diffs.
Example¶
A service signs the JSON payloads it emits so downstream consumers can verify origin. But two payloads with identical meaning — keys in a different order, a trailing space, 1.0 where another producer wrote 1 — serialize to different bytes, produce different signatures, and fail verification for no real reason. A canonicalization rule fixes the ambiguity: sort object keys, normalize number and string forms, define escaping and whitespace exactly — the approach standardized as the JSON Canonicalization Scheme (RFC 8785), with Canonical XML (C14N) playing the same role for XML. Every producer now normalizes to identical canonical bytes before signing, and verification is stable across implementations. In doing so the rule states, explicitly, which differences are meaningful (the values) and which are ignorable (order, spacing, numeric spelling) — the equivalence relation the whole scheme now shares.
How it works¶
- Fix an equivalence relation. Enumerate the surface variations that do not change meaning and eliminate each with a deterministic choice — canonical ordering, whitespace, number and string normalization, filling of defaults.
- Be total and idempotent. The rule is defined for every valid input and satisfies
canon(canon(x)) = canon(x); agreement across implementations is the entire point, so nondeterminism is the enemy. - Emit a comparison surrogate. The canonical bytes become the stable key that signing, hashing, caching, and deduplication operate on in place of the raw, variable encoding.
Tuning parameters¶
- Equivalence breadth — how many differences you declare irrelevant (order, whitespace, case, Unicode normalization, defaults). Wider collapsing improves deduplication but risks erasing a distinction that actually mattered.
- Determinism strictness — how tightly the normal form is pinned across languages, locales, and floating-point formatting. This is the usual source of "canonical on my machine only."
- Stability over time — whether the canonical form is frozen forever (required for long-lived signatures) or allowed to evolve with the scheme.
- Cost — full normalization versus a cheaper partial pass; heavier normalization spends more CPU on every operation that needs a canonical form.
When it helps, and when it misleads¶
Its strength is turning semantic equality into byte equality — the single precondition that makes signing, content-addressing, caching, deduplication, and meaningful diffs possible at all.
It misleads when the equivalence relation is wrong at either edge. Declare too much irrelevant and two genuinely different values collapse to one canonical form — a canonicalization collision, which for a signature scheme is a security hole rather than a nuisance. Leave any cross-implementation nondeterminism — float formatting, Unicode, locale — and the guarantee silently fails for a fraction of inputs. The classic misuse is bolting canonicalization onto a security scheme after the fact and assuming "canonical" implies "safe"; XML signature-wrapping attacks are the standing cautionary tale.[1] The discipline is to derive the equivalence relation from the task's real invariants, freeze it, and prove its determinism across every implementation — typically with golden vectors.
How it implements the components¶
Canonicalization Rule realizes the normal-form side of the archetype — the components that make equal things encode equally:
encoded_form— it defines the single canonical encoded form among all equivalent encodings; its output is a normalized member of the encoded-form space, chosen so equality of meaning becomes equality of bytes.interpretation_boundary— the equivalence relation is an interpretation boundary: it licenses a receiver to treat normalized-equal encodings as identical and declares exactly which surface differences carry no meaning.
It does not pin concrete reference outputs (that is Golden Test Vectors), does not detect corruption of the encoded form (that is Checksum or Hash Validation), and does not author the scheme contract it normalizes within — that is Codec Specification.
Related¶
- Instantiates: Round-Trip Code Alignment — supplies the stable normal form that lets encodings, not just values, be compared and signed.
- Consumes: Codec Specification — the scheme within which canonical forms are defined.
- Sibling mechanisms: Codec Specification · Golden Test Vectors · Round-Trip Property Test · Decode Error Taxonomy · Checksum or Hash Validation · Parser/Emitter Pair · Compatibility Matrix · Schema Registry · Lossy Compression Profile · Migration Adapter · Version Negotiation Handshake
References¶
[1] Canonical XML (C14N) and its role in XML Signature — a real, widely deployed canonicalization standard. Sound canonicalization is a prerequisite for stable signatures, and weaknesses around it enabled the documented class of XML signature-wrapping vulnerabilities, which is why the equivalence relation must be chosen and frozen with security in mind. ↩