This guide walks through the end-to-end monitor / auditor workflow with
metamorphic_log: given material published by a transparency log, independently
verify it on the server — byte-identically to the browser and the native core.
All binary values are base64-encoded strings; checkpoint/note bodies and verifier keys are UTF-8 text.
1. Trust a verifier key
A log (and any co-signing witnesses) publishes one or more verifier keys in
the C2SP name+hash+base64key encoding. You decide which to trust:
trusted = [log_vkey, witness_vkey]Two signature types are supported transparently:
- Ed25519 — the classical C2SP type.
- Metamorphic hybrid — ML-DSA + Ed25519 (strict-AND), wedging post-quantum integrity into the same note format.
2. Verify a checkpoint (signed tree head)
{:ok, %MetamorphicLog.Checkpoint{origin: origin, size: size, root: root}} =
MetamorphicLog.Checkpoint.verify(note_text, trusted)verify/2 rejects the note unless a trusted key signed it. Unknown-key
signatures are ignored; a known key that fails to verify rejects the note.
3. Verify inclusion against the verified checkpoint
:ok =
MetamorphicLog.Checkpoint.verify_inclusion(
note_text, trusted, leaf_index, leaf_hash, proof
)proof is a list of base64 sibling hashes. For the mosslet/key-history/v1
record type, compute the leaf_hash from the entry:
{:ok, leaf_hash} = MetamorphicLog.Leaf.key_history_v1_rfc6962_leaf_hash(entry)4. Verify consistency (append-only) between two checkpoints
:ok =
MetamorphicLog.Checkpoint.verify_consistency(
older_note, newer_note, trusted, consistency_proof
)This is the core anti-equivocation check a monitor runs as the log grows.
5. Enforce the namespace policy (declared == observed)
A namespace publishes a signed policy declaring its posture. Verify it, then assert that what you observe matches what the policy declares:
{:ok, policy} = MetamorphicLog.Policy.verify(signed_policy)
# The checkpoint signing key must match the declared posture
:ok = MetamorphicLog.Policy.enforce_checkpoint_signing_key(signed_policy, signing_pub)
# The observed VRF suite / commitment hash must match the declaration
:ok = MetamorphicLog.Policy.enforce_vrf_suite_id(signed_policy, 0x03)
:ok = MetamorphicLog.Policy.enforce_commitment_hash(signed_policy, :sha3_256)This stops an operator from silently downgrading the cryptographic posture.
6. Verify CONIKS key-transparency answers
Given the operator's published VRF public key and directory root, verify what a namespace binds to an identity — or that it binds nothing — without learning about other identities:
{:ok, value} =
MetamorphicLog.Coniks.verify_lookup(namespace, vrf_public, root, identity, proof)
:ok =
MetamorphicLog.Coniks.verify_absence(namespace, vrf_public, root, identity, proof)Cross-target parity
Every function above computes byte-identically to the native Rust core and the
browser WASM SDK; the package's cross-language byte-parity KAT
(test/cross_language_kat_test.exs) locks this against the same vectors used by
the engine. That is what lets a log produced by browser clients be recomputed
and audited, unchanged, by an Elixir monitor.