Conformance & parity
The protocol is implemented several times — the Rust producer, the host, the
dig-client-wasmverifier, the DIG Browser C++, the SDK/extension JS. They stay interchangeable only because of a parity discipline: every shared constant has one definition, and frozen goldens fail the build the moment any implementation drifts.
The C8 parity invariant
Every cryptographic constant has ONE definition shared across producer, host, and verifier. There is no per-layer reimplementation of the read-crypto: producer, host-serve, and the browser verifier all call digstore_core::crypto + digstore_core::resource_leaf (parity test dig-client-wasm/tests/parity.rs).
What every reimplementation MUST pass
| Surface | Frozen by | What it pins |
|---|---|---|
URN canonical() + retrieval_key() | digstore-core/tests/urn.rs:107-126; dighub-core recomputes SHA-256 independently | the exact canonical-string bytes and their hash, for all four parsers |
| Crypto (HKDF + GCM-SIV) | C8 KAT fixtures (kdf_kat.rs) | a distinct (URN, salt) ⇒ a distinct 32-byte key; tag failure on wrong key |
| BLS host↔guest | host-signed fixtures the guest must accept (tests/bls_fixtures.rs) | AugScheme cross-impl parity + the five role DSTs |
| Merkle leaf/proof | resource_leaf shared by producer + verifier | D5 leaf = SHA-256(ciphertext); D8 proof length ≤ ceil(log2 n) |
| dig RPC | OpenRPC documents generated from the implementation, CI-diffable against live server responses | the method set, the chunk object (incl. chunk_lens, no decoy), -32004 |
| Peer network | peer_id = SHA-256(TLS SPKI DER); the RLY-001..RLY-007 relay JSON wire; the peer RPC methods in openrpc-node.json | that any node, relay, and NAT implementation derive the same peer identity, speak the same relay wire, and prefer direct-over-relay identically |