Canonicalization
Canonicalization converts supported JSON-compatible values into a deterministic byte sequence. Independent implementations hash the canonical bytes to derive identical protocol identities from equivalent supported input.
Canonical Model
Equivalent values can have different serialized representations. ALX applies the recursive-json-sort-v1 algorithm before deriving contentHash or blockHash, ensuring equivalent supported protocol input produces equivalent canonical bytes and therefore equivalent hashes.
Canonical Rules
Canonicalization applies the following rules:
| Input | Canonical Representation |
|---|---|
null, undefined | "null" |
| Boolean | "true" or "false" |
| Safe integer | Decimal representation; -0 becomes 0 |
| Finite float | IEEE-754 shortest representation matching JavaScript JSON.stringify() |
| String | JSON-escaped, double-quoted UTF-8 |
| Array | Original order preserved; undefined elements become null |
| Object | Keys sorted by UTF-16 code units; undefined properties omitted |
Rejected Values
Canonicalization rejects:
BigIntSymbol- Non-finite numbers
- Unsafe integers
- Unsupported value types
Rejected input does not produce a canonical protocol representation and therefore cannot produce a valid protocol identity.
Unicode
Strings are JSON-escaped and encoded as UTF-8 without Unicode normalization. Implementations preserve the input code points so equivalent inputs produce identical canonical byte sequences.
When to Canonicalize
Canonicalization is required whenever protocol identity depends on structured data.
Block creation canonicalizes content before deriving contentHash. Block identity derivation canonicalizes the protocol-defined structure containing content and normalized parentHashes before deriving blockHash. Verification repeats the same process to recompute and compare the resulting identities.