Skip to content

BeeKEM

Defined in: packages/core/src/beekem/beekem.ts:128

BeeKEM: Binary ratchet tree for decentralized group key agreement.

Based on Ink & Switch’s Keyhive specification. Tree paths are logarithmic. V2 updates additionally carry a linear public snapshot and an exact parent commitment; every transition must be applied in order, or the member must recover from persisted current ratchet state or a fresh authenticated Welcome/remove-rejoin. An ordinary encrypted document load cannot reconstruct private tree state.

Tree layout uses left-balanced binary tree indexing:

  • Leaf nodes (even indices) hold member ECDH key pairs
  • Internal nodes (odd indices) hold derived key pairs
  • The root node’s key material is the shared group secret

new BeeKEM(): BeeKEM

BeeKEM

get generation(): number | null

Defined in: packages/core/src/beekem/beekem.ts:910

Monotonic generation, or null before initialization.

number | null


get memberCount(): number

Defined in: packages/core/src/beekem/beekem.ts:900

Number of leaves in the tree (including blanked positions).

number


get myLeafIndex(): number

Defined in: packages/core/src/beekem/beekem.ts:905

Our leaf index in the tree.

number

addMember(memberPublicKey): Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; welcome: BeeKEMWelcomeV2; }>

Defined in: packages/core/src/beekem/beekem.ts:188

Add a new member to the group. Creates a new leaf and derives keys along the path to root. Returns a path update message to broadcast and a welcome for the new member.

CryptoKey

Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; welcome: BeeKEMWelcomeV2; }>

If a live leaf already owns memberPublicKey.


addMemberTransactionally<T>(memberPublicKey, commit): Promise<T>

Defined in: packages/core/src/beekem/beekem.ts:203

Add a member and run a caller-supplied commit inside the same tree transaction. If the commit rejects, every BeeKEM mutation is restored.

T

CryptoKey

(result) => Promise<T>

Promise<T>


clone(): BeeKEM

Defined in: packages/core/src/beekem/beekem.ts:138

Copy stable tree state for a document membership transaction.

BeeKEM


compact(): void

Defined in: packages/core/src/beekem/beekem.ts:1035

Remove blanked leaf nodes and their parent path nodes from the tree when an entire subtree is blanked. This reclaims memory for nodes that can never contribute to key derivation.

void


compactAsync(): Promise<void>

Defined in: packages/core/src/beekem/beekem.ts:1045

Queue compaction behind any active BeeKEM transition.

Promise<void>


findLeafByPublicKey(publicKey): Promise<number | undefined>

Defined in: packages/core/src/beekem/beekem.ts:983

Find the node index of the unique live leaf whose public key matches publicKey, or undefined if no such leaf exists or the key appears in more than one non-blanked leaf.

Used by PeerborneDocument as the canonical source of truth for live leaf-index lookup during reader revocation and writer promotion. The writer’s in-memory leaf-index cache can be missing, so role transitions must be able to recover an unambiguous assignment from tree state alone.

Comparison is done over the raw exported ECDH public key bytes:

  • CryptoKey inputs are exported via crypto.subtle.exportKey('raw', ...) so the caller doesn’t need to pre-export.
  • Uint8Array inputs must be genuine, unshared, exactly ECIES_P256_PUBLIC_KEY_LENGTH (65) byte SEC1-uncompressed P-256 keys, the same shape stored on the wire and accepted by addMember / PeerborneDocument._prepareBeeKEMReaderRegistration. They are copied before any await, so later caller mutation cannot redirect the lookup.

Blanked leaves (publicKey === null) are skipped: their slot index is meaningless to a “find this member” query, and a match against a blanked leaf would let stale public-key references re-resolve to an already-removed slot.

Returns the node index (even-indexed tree slot), which is the form removeMember consumes. Callers that need the dense leaf-position form should convert via TreeMath.nodeToLeafIndex.

Uint8Array<ArrayBufferLike> | CryptoKey

Promise<number | undefined>

If a Uint8Array input is not a genuine, unshared 65-byte view, or a CryptoKey input exports to raw bytes of another length.


getRootSecret(): Promise<Uint8Array<ArrayBufferLike>>

Defined in: packages/core/src/beekem/beekem.ts:824

Get the current root secret (shared by all members). Hashes extractable root key material; a single-member tree with the canonical non-extractable KEM key uses a domain-separated ECDH transcript.

Promise<Uint8Array<ArrayBufferLike>>


hasLiveLeafWithPublicKey(publicKey): Promise<boolean>

Defined in: packages/core/src/beekem/beekem.ts:945

Return whether any live leaf owns publicKey, including duplicates.

publicKey follows the same input rules as findLeafByPublicKey.

Uint8Array<ArrayBufferLike> | CryptoKey

Promise<boolean>

If a Uint8Array input is not a genuine, unshared 65-byte view, or a CryptoKey input exports to raw bytes of another length.


hasOnlyLocalLiveLeaf(): boolean

Defined in: packages/core/src/beekem/beekem.ts:922

Return true only when the tree contains exactly one live leaf and that leaf is the local member. Blanked and missing leaf slots do not count.

This is intentionally stricter than checking memberCount === 1 because removed members leave blanked positions behind. Callers use this as proof that no remote member remains when identity-to-leaf caches are absent.

boolean


initialize(privateKey, publicKey): Promise<void>

Defined in: packages/core/src/beekem/beekem.ts:160

Initialize as the first member of a new group. Creates a single-leaf tree with the creator’s key pair.

CryptoKey

CryptoKey

Promise<void>


processPathUpdate(update): Promise<Uint8Array<ArrayBufferLike>>

Defined in: packages/core/src/beekem/beekem.ts:403

Process a path update from another member. Decrypts the relevant encrypted key and derives the new root.

PathUpdateV2

Promise<Uint8Array<ArrayBufferLike>>


processPathUpdateTransactionally<T>(update, commit): Promise<T>

Defined in: packages/core/src/beekem/beekem.ts:420

Internal

Apply an update and a caller-supplied commit as one BeeKEM transaction. If validation, epoch binding, or durable key installation fails in the callback, the ratchet state is restored to its exact prior snapshot. The callback receives duplicate for an exact v2 replay so callers can validate its epoch binding without appending the same durable key again.

Used by the document wire handler to couple tree advancement with installation of the document key derived from the new root.

T

PathUpdateV2

(rootSecret, disposition) => Promise<T>

Promise<T>


processWelcome(welcome, privateKey, publicKey): Promise<Uint8Array<ArrayBufferLike>>

Defined in: packages/core/src/beekem/beekem.ts:693

Process a welcome message to join an existing group. Requires a fresh instance: callers replace a live tree by swapping in a newly joined one.

BeeKEMWelcomeV2

CryptoKey

CryptoKey

Promise<Uint8Array<ArrayBufferLike>>


removeMember(memberLeafIndex): Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; }>

Defined in: packages/core/src/beekem/beekem.ts:282

Remove a member from the group. Blanks the member’s leaf and all nodes on their direct path. Returns a path update with fresh key material.

number

Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; }>


removeMemberTransactionally<T>(memberLeafIndex, commit): Promise<T>

Defined in: packages/core/src/beekem/beekem.ts:296

Remove a member and run a caller-supplied commit inside the same tree transaction. If the commit rejects, every BeeKEM mutation is restored.

T

number

(result) => Promise<T>

Promise<T>


update(): Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; }>

Defined in: packages/core/src/beekem/beekem.ts:372

Perform a self-update that rotates key material along our path. This operation alone does not establish post-compromise security, secret erasure, or recovery after a compromise.

Promise<{ pathUpdate: PathUpdateV2; rootSecret: Uint8Array; }>