Statement

Resolution is cryptographic wherever the exact claimant intersection allows it. Only monads holding the mutual .me refs and keys can derive the route. Everything else stays invisible — pure emergent, sovereign topology.

Definitions

kernel
an instance of ME; one root seed, one secret-derivation chain
seed
64-hex namespace authority key; never leaves the kernel
path
SemanticPath — ordered sequence of string segments
secret scope
a path marked _("key"); data under it encrypted from that scope's key material
noise boundary
a path marked ~("nonce"); cuts secret-derivation inheritance (A3)
blob key
(encKey, macKey, pathContext) from deriveBlobV3Keys()
audience
A ⊆ { kernel identityHash }

Kernel Identity as Audience Element

seed(who, secret) = keccak256("me.seed/compound:v1::" + who + "::" + secret)
identityHash(K)   = keccak256("this.me/identity:v1::" + K.seed)
(P256_priv_K, P256_pub_K) = generateP256KeyPair()   // random, not derived from seed
W = wrapSecretV1(P256_pub_K, secret)                // secrets are wrapped to it
Status in this.me 4.2.1 · Kernel: this.me 4.2.1
Seed and identity formulas as above (see Seed). identityHash is returned by me.prove({ expression, rootNamespace }), not by a me.identityHash() method.
The P-256 key pair is generated randomly; there is no seed-to-P-256 derivation. Secrets reach it by wrapping (Audiences).

P256_pub_K — encryption target, shareable. identityHash(K) — membership identifier. (identityHash, P256_pub) — the kernel's public audience credential.

Existing Primitives

3.1 symmetric, v3, single-owner
collectSecretChainV3(path, mode) → deriveBlobV3Keys(chain, mode, path)
  → { encKey, macKey, pathContext }
encryptBlobV3 / decryptBlobV3 — keccak XOR stream + MAC

3.2 asymmetric, v1
wrapSecretV1(P256_pub, secret)   → { ephemeralPublicKey, iv, ciphertext, tag }
unwrapSecretV1(P256_priv, W)     → secret
kex: ECDH-ES(P-256)  kdf: HKDF-SHA-256  aead: AES-256-GCM

3.3 Ed25519
signEd25519Proof(priv, data)     → signature
verifyEd25519Signature(pub, data, sig) → boolean
— identity proof, not audience encryption

Audience Algebra

Status in this.me 4.2.1 · Kernel: this.me 4.2.1
Union (OR), intersection (AND, XOR shares) and difference (minus, resolved at seal time) are implemented and tested in the 4.2.1 source, and not exported by the npm 4.2.1 package. Threshold-k (Shamir) is not implemented. Status per implementation: Audiences.

Union — A = K₁ ∪ K₂ ∪ ... ∪ Kₙ

S ← random(32)
ciphertext = encryptSymmetric(S, V)
∀ Kᵢ ∈ A:  Wᵢ = wrapSecretV1(P256_pub(Kᵢ), S)
publish { ciphertext, wraps: [(identityHash(Kᵢ), Wᵢ)] }

decrypt(Kⱼ ∈ A):
  Wⱼ ← match identityHash(Kⱼ) in wraps
  S  = unwrapSecretV1(P256_priv(Kⱼ), Wⱼ)
  V  = decryptSymmetric(S, ciphertext)

O(|A|) wrapped keys. Any single member suffices. Removing a member requires re-encryption of S for all remaining members — no backward secrecy otherwise.

Intersection — A = K₁ ∩ K₂ ∩ ... ∩ Kₙ

S₁, ..., Sₙ₋₁ ← random(32) each
Sₙ = S ⊕ S₁ ⊕ ... ⊕ Sₙ₋₁
∀ Kᵢ ∈ A:  Wᵢ = wrapSecretV1(P256_pub(Kᵢ), Sᵢ)
publish { ciphertext, shares: [(identityHash(Kᵢ), Wᵢ)] }

decrypt: requires all Kᵢ
  each Kᵢ unwraps Sᵢ; ⊕ all Sᵢ → S → decrypt(ciphertext)

Requires out-of-band coordination for share assembly. Threshold-k needs Shamir's Secret Sharing, not XOR splitting.

Set Difference — A = K₁ \ K₂

minus(A, K₂) drops every coalition containing K₂ (see Audiences). It is applied at seal time; revoking from existing data means resealing with a fresh S. Tested in the 4.2.1 source; not exported by npm 4.2.1.

Blob Format

interface AudienceEnvelopeV1 {
  version: 1;
  audience: string;              // audienceId of the sealed audience
  epoch: number;                 // revocation = new seal, higher epoch
  ciphertext: EncryptedBlob;     // value under a fresh content key
  tree: AudienceNodeV1;
}

type AudienceNodeV1 =
  | { leaf: string; wrapped: WrappedSecretV1 }   // leaf = identityHash
  | { or: AudienceNodeV1[] }
  | { and: AudienceNodeV1[] };                   // XOR shares

Kernel: this.me 4.2.1 · the sealed format is an envelope tree, not a flat member list (Audiences).

Stored at the target path in the kernel's encrypted branch, alongside or replacing the v3 blob, depending on whether the path is self-owned or audience-scoped.

KDF Domains

"me.seed/compound:v1::"   compound seed
"this.me/identity:v1::"   identityHash
"this.me/audience:v1::"   audienceId
"this.me/audience/v1"     audience KDF salt

Status in this.me 4.2.1: these are the domain strings that exist (Seed, Audiences). No other per-purpose domains are defined.

Axiom Compatibility

Key Exchange Prerequisite

wrapSecretV1 requires the sender to already know P256_pub(K_recipient) — a distribution problem the kernel does not solve itself.

Not solved anywhere in the current stack, checked directly against source. monad's real discovery surface, /__surface, does publish a public key — but it is Ed25519, used for routing-continuity signatures, not paired with identityHash, and not usable for ECDH-ES wrapping. /claims is POST-only — self-declaration, not third-party discovery. NRP's own spec excludes this explicitly: "namespace key distribution across monads" is listed under its own "What Is Not Specified Here." netget resolves network routing only; cleaker binds identity to namespace, not key discovery. This exchange is unencrypted by design once it exists — P256_pub is meant to be public — but no component currently makes it discoverable.