Skip to main content

Module sanctuary_audit

Module sanctuary_audit 

Source
Expand description

Sanctuary audit primitives (vault v2, first slice) — the crypto under the decoy-mirroring design.

Three isolated, independently-tested primitives. Nothing here touches the vault yet; the vault wiring is a later slice. See docs/plans/adr-sanctuary-vault-v2-cbor-decoy-mirroring.md.

  1. Blind write-only audit channel — an X25519 sealed box (anonymous ECIES): a decoy session, holding only the audit public key, can seal_to a record so that only the holder of the audit secret (the real lane) can open_sealed it. The writer cannot read back what it wrote, and cannot forge or tamper without detection. This is how a coercer’s actions get logged into a channel they can append to but never read.
  2. One-way key wrappingwrap_key/unwrap_key: the real lane key wraps the decoy lane key (and the audit secret), so a real session can reach down into the decoy to curate it, but the decoy can never reach up.
  3. Hash-chained content addressingchain_hash: an append-only, tamper-evident DAG link (BLAKE3 over parent ‖ payload); rewriting or dropping a record breaks every link after it.

Symmetric AEAD is XChaCha20-Poly1305 (24-byte nonce). Sealed-box key/nonce are derived from the ECDH shared secret via BLAKE3 derive_key (domain-separated); each seal uses a fresh ephemeral key, so sealing is non-deterministic (no plaintext-equality leak) and nonce reuse is impossible.

Structs§

AuditKeypair
An audit keypair. The public key is exposed to any session (including the decoy) so it can append sealed records; the secret lives only in the real lane (wrapped under the real key) and is the sole means of reading them.

Enums§

SanctuaryAuditError

Constants§

GENESIS_PARENT
Genesis parent for a fresh hash chain / DAG branch.

Functions§

chain_hash
One append-only DAG link: BLAKE3(parent ‖ payload). Rewriting or reordering any record changes its hash and breaks the parent link of everything after it (tamper-evidence). Start a branch from GENESIS_PARENT.
open_sealed
Open a sealed box produced by seal_to. Requires the recipient secret; the public key alone cannot open it (that is the whole point — the decoy session writes but cannot read).
seal_to
Seal plaintext so that only the holder of the secret matching recipient_public can open it. Anonymous: the sealer needs no identity, only the recipient’s public key. Output layout: ephemeral_public(32) ‖ ciphertext ‖ tag(16). Non-deterministic (fresh ephemeral key per call).
unwrap_key
Unwrap a blob produced by wrap_key. Fails on the wrong key, wrong AAD, or tampering.
wrap_key
Wrap key_material under wrapping_key (AEAD). Output: nonce(24) ‖ ciphertext ‖ tag(16). Used for the one-way hierarchy: the real lane key wraps the decoy key + the audit secret.