Skip to main content

Module envelope_encryption

Module envelope_encryption 

Source
Expand description

Real envelope encryption for the accountability commons payload — the crypto that makes ConsentCredential’s “revoke destroys the wrapped key ⇒ no key, no payload” a fact, not a model with opaque placeholder bytes.

Two layers, both real (built on the already-tested qualia_core_db::crypto::sanctuary_audit primitives — X25519 sealed boxes + XChaCha20-Poly1305 AEAD; no new crate, no simulation):

  1. Payload layer (symmetric). A random data-encryption key (DEK) encrypts the plaintext with an AEAD (wrap_key); the ciphertext is content-addressed (commitment = SHA-256(ciphertext)), giving the EncryptedCommonsPayload that many parties may replicate. Opening verifies the commitment (the bytes are the committed bytes) then AEAD-decrypts (tamper ⇒ failure).
  2. Key layer (asymmetric, per recipient). The DEK is sealed to a recipient’s public key (seal_to) — an anonymous ephemeral-DH box only that recipient’s secret can open. This sealed DEK is the credential’s wrapped_key. So access is genuinely per-holder, and revocation = destroying that sealed DEK (ConsentCredential::revoke): the recipient can no longer recover the DEK, and the ciphertext — wherever replicated — is opaque to them. When no live credential holds a sealed DEK for a payload, the DEK is unrecoverable and the payload is crypto-shredded (permanently unreadable though the bytes survive), exactly as the model promised.

Native-only (the sealed-box primitives are not(wasm32); the desktop owns keys), matching wellfair::sanctuary_vault.

What this does not yet do (named honestly, not deferred behind a lane): distribute a remote agent’s X25519 public key — that comes from the peer’s published key material in the connection/identity layer (social_peers / DID document), so a worker on their own device can be sealed to and decrypt independently. Until that is wired, the host seals to the owner’s envelope keypair by default (the owner can always open their own data), and can seal to any supplied recipient public key.

Structs§

EnvelopeKeypair
An X25519 envelope keypair for a party (the owner, or an agent). The secret opens sealed DEKs; the public is what a DEK is sealed to.

Constants§

OWNER_ENVELOPE_DOMAIN
Domain tag for deriving the owner’s envelope keypair from their ed25519 signing-key seed.

Functions§

open_payload
Open a payload with the DEK — verifies the content-address commitment (the bytes are the committed bytes) then AEAD-decrypts. Any tamper (to ciphertext or a swapped payload) fails.
open_payload_with_wrapped
Open a payload directly from a recipient’s secret + the credential’s wrapped DEK. The end-to-end decrypt path: unwrap the sealed DEK, then open the payload. If the wrapped DEK is absent (revoked), the caller has nothing to pass here — that is the crypto-enforced revocation.
seal_payload
Seal a plaintext payload. Generates a random DEK, AEAD-encrypts under it, and content-addresses the ciphertext. Returns the replicable EncryptedCommonsPayload and the DEK (to be sealed per recipient by wrap_dek_to, then dropped — do not persist it in the clear).
unwrap_dek
Unwrap a DEK with the recipient’s secret key. Fails for the wrong recipient or a tampered blob.
wrap_dek_to
Seal (wrap) a DEK to a recipient’s public key — the credential’s wrapped_key. Only the holder of the matching secret can unwrap_dek it; destroying this blob (revocation) removes that access.

Type Aliases§

DataKey
A 32-byte data-encryption key. Secret: seal it to a recipient, never store it in the clear.