Expand description
§vr-jcs
RFC 8785 JSON Canonicalization Scheme (JCS) for Rust.
Produces canonical JSON suitable for deterministic digest computation, content hashing, and stable serialization boundaries. Implements the RFC 8785 rules that materially affect wire compatibility:
- UTF-16 code-unit sorting for object property names
- ECMAScript-compatible primitive serialization
- UTF-8 output without insignificant whitespace
- duplicate-property rejection on raw JSON parse paths
- I-JSON string / number validation
§API
§Strict path (for untrusted JSON)
to_canon_bytes_from_slice— Parse untrusted JSON, apply strict admission checks, emit canonical bytesto_canon_string_from_str— Parse untrusted JSON string, apply strict admission checks, emit canonical string
§Typed path (caller-controlled construction only, deprecated)
to_canon_bytes— Serialize anySerializetype to canonical JSON bytesto_canon_string— Serialize anySerializetype to a canonical JSON string
§In-place
canonicalize— Sort object keys recursively in aserde_json::Value
§Canonical digest
Canonicalization is a schema decision; digest algorithm choice (BLAKE3 vs. keyed BLAKE3 vs. domain-separated BLAKE3 vs. SHA-256 vs. …) is a separate cryptographic / governance decision. The digest surface reflects that split:
Strategy-bearing (primary) path — for any site whose digest algorithm is or may become a policy variable:
DigestAlgorithm— the algorithm enum.DigestStrategy— an algorithm plus any future policy knobs.CanonicalDigest— typed output that remembers which algorithm produced it.to_canon_digest_with— canonicalizevalue, digest understrategy.
BLAKE3 fixed-policy convenience — for sites where receipt policy has explicitly frozen the algorithm to plain BLAKE3:
to_canon_blake3_digest—&Value→[u8; 32].to_canon_blake3_digest_from_slice— strict-parse&[u8]→[u8; 32].
These convenience wrappers are equivalent to calling
to_canon_digest_with with DigestStrategy::blake3_untagged and
extracting bytes.
The lexical invariant is: canonicalization and digest must travel together
through one call. Receipt-bound and constitutional code paths MUST use the
strategy-bearing or fixed-BLAKE3 wrappers instead of pairing
to_canon_bytes_* with blake3::hash manually.
§Usage
let json = vr_jcs::to_canon_string_from_str(r#"{"z_field":1,"a_field":2}"#)?;
assert_eq!(json, r#"{"a_field":2,"z_field":1}"#);Structs§
- Canonical
Bytes - Newtype wrapper over canonical JCS output bytes.
- Canonical
Digest - Typed output of a canonical digest computation.
- Digest
Strategy - A digest strategy bundles the algorithm with any future policy knobs (output truncation, pre-hash prefix, etc.). Today it’s a thin newtype; the wrapper exists so extensions don’t churn call sites.
Enums§
- Digest
Algorithm - Digest algorithm variant.
- JcsError
- Error type for canonical JSON operations.
- JcsError
Info - Stable downstream projection of
JcsError.
Constants§
- MAX_
NESTING_ DEPTH - Maximum permitted nesting depth for JSON structures (128).
Functions§
- canonical_
bytes_ from_ slice - Parse untrusted JSON, apply strict admission checks, and return the
canonical RFC 8785 bytes inside a
CanonicalByteswrapper. - canonicalize
- Recursively sort all object keys in a JSON value for canonical representation.
- to_
canon_ blake3_ digest - BLAKE3 fixed-policy convenience. Canonicalize
valueand returnblake3::hash(canonical_bytes)as a 32-byte array. - to_
canon_ blake3_ digest_ from_ slice - Strict-parse sibling of
to_canon_blake3_digestfor untrusted JSON bytes. - to_
canon_ bytes Deprecated - Serialize any
Serializetype to canonical JSON bytes. - to_
canon_ bytes_ from_ slice - Parse untrusted JSON, apply strict admission checks, and emit canonical RFC 8785 bytes.
- to_
canon_ digest_ with - Canonicalize a trusted
serde_json::Valueand digest the canonical bytes under the given strategy. - to_
canon_ string Deprecated - Serialize any
Serializetype to a canonical JSON string. - to_
canon_ string_ from_ str - Parse untrusted JSON text, apply strict admission checks, and emit a canonical RFC 8785 string.