Sovereign topology, resolved wherever claimant intersection allows.
.me refs and keys can derive
the route. Everything else stays invisible — pure emergent, sovereign
topology.
ME; one root seed, one secret-derivation chainSemanticPath — ordered sequence of string segments_("key"); data under it encrypted from that scope's key material~("nonce"); cuts secret-derivation inheritance (A3)(encKey, macKey, pathContext) from deriveBlobV3Keys()A ⊆ { kernel identityHash }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
identityHash is returned by me.prove({ expression, rootNamespace }),
not by a me.identityHash() method.
P256_pub_K — encryption target, shareable.
identityHash(K) — membership identifier.
(identityHash, P256_pub) — the kernel's public audience credential.
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
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.
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.
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.
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.
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.
"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.
_-scoped paths, root stays invisibleSwrapped entries join the memory hash chain
wrapSecretV1 requires the sender to already know
P256_pub(K_recipient) — a distribution problem the kernel does
not solve itself.
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.