A long-lived E2EE channel derived from an X3DH shared secret.
Key representations coexist: the raw root material (32B) lives
in module-private internals (WeakMap) for message-key
derivation and rotation; a non-extractable CryptoKey is
derived from it for AEAD operations. The raw material is
wiped only at rotation.
Sequence counters are managed by the APPLICATION (immutable
design — React-friendly).
The channel's internal state (rootKeyMaterial, lastDecryptedSeq)
is stored in a module-private WeakMap keyed by the Channel object
reference. The application never sees or touches internals.
hex(SHA-256(sharedSecret ‖ salt)) — identical on both sides.
epoch
epoch:number
role
role:"initiator" | "recipient"
Direction role: affects nothing cryptographically (X3DH is
symmetric), but useful for application-side audit. Set on
establish, preserved through rotation.
A long-lived E2EE channel derived from an X3DH shared secret.
Key representations coexist: the raw root material (32B) lives in module-private internals (WeakMap) for message-key derivation and rotation; a non-extractable CryptoKey is derived from it for AEAD operations. The raw material is wiped only at rotation.
Sequence counters are managed by the APPLICATION (immutable design — React-friendly).
The channel's internal state (rootKeyMaterial, lastDecryptedSeq) is stored in a module-private WeakMap keyed by the Channel object reference. The application never sees or touches internals.
Example