pub struct MlsContext {
pub provider: OpenMlsRustCrypto,
pub signer: SignatureKeyPair,
pub group: MlsGroup,
pub credential: CredentialWithKey,
pub identity: Vec<u8>,
pub pending_staged: Option<StagedCommit>,
}Expand description
MLS context for a single group member.
Owns the OpenMLS provider, the signing key, the credential and the
current MlsGroup. Ratcheting forward is performed by MlsContext::invite
and MlsContext::accept_welcome.
Fields§
§provider: OpenMlsRustCryptoOpenMLS crypto provider.
signer: SignatureKeyPairSigning key pair for this member.
group: MlsGroupCurrent MLS group.
credential: CredentialWithKeyCredential with the public signing key.
identity: Vec<u8>Member identity (opaque application-defined bytes).
pending_staged: Option<StagedCommit>Staged commit produced by MlsContext::process_message but not
yet merged. Held until MlsContext::finalize_pending_commit (on
EXECUTE_TRANSITION) so that the local epoch only advances together
with the rest of the group, never earlier — otherwise this side’s
READY frame would be sealed under an epoch the coordinator can’t
open.
Implementations§
Source§impl MlsContext
impl MlsContext
Sourcepub fn new_member(
identity: &[u8],
) -> Result<(MlsContext, KeyPackageBundle), MlsError>
pub fn new_member( identity: &[u8], ) -> Result<(MlsContext, KeyPackageBundle), MlsError>
Creates a new context with a single-member group, returning the
context together with a KeyPackageBundle that other members can
use to invite this one.
Sourcepub fn invite_full(
&mut self,
key_packages: &[KeyPackage],
) -> Result<(Vec<u8>, Vec<u8>), MlsError>
pub fn invite_full( &mut self, key_packages: &[KeyPackage], ) -> Result<(Vec<u8>, Vec<u8>), MlsError>
Result of MlsContext::invite_full: the Commit message that
existing members must apply via MlsContext::process_message,
plus the Welcome that the new joiner must apply via
MlsContext::accept_welcome.
RFC 9420 §11/§12.4 — Welcome is for the joiner only; existing members MUST receive the Commit to advance their epoch.
IMPORTANT: this call does not merge the pending commit. The
caller MUST call MlsContext::finalize_pending_commit only after
they are confident the Commit/Welcome have been distributed (e.g.
the GBP coordinator has observed READY quorum). If the distribution
fails, call MlsContext::clear_pending_commit to roll back.
Sourcepub fn invite(
&mut self,
key_packages: &[KeyPackage],
) -> Result<Vec<u8>, MlsError>
pub fn invite( &mut self, key_packages: &[KeyPackage], ) -> Result<Vec<u8>, MlsError>
Backwards-compatible wrapper. Builds the Commit, eagerly merges, and returns only the Welcome bytes. Kept for callers that distribute the Commit out-of-band and don’t need atomic abort semantics.
Sourcepub fn remove_members(
&mut self,
leaf_indices: &[u32],
) -> Result<Vec<u8>, MlsError>
pub fn remove_members( &mut self, leaf_indices: &[u32], ) -> Result<Vec<u8>, MlsError>
Removes members identified by their MLS LeafIndex via a Remove commit
and returns the TLS-serialised Commit message that remaining members
must apply via MlsContext::process_message.
Like MlsContext::invite_full, the caller is responsible for
calling MlsContext::finalize_pending_commit after successful
distribution, or MlsContext::clear_pending_commit on failure.
RFC 9420 §12.3.
Sourcepub fn finalize_pending_commit(&mut self) -> Result<(), MlsError>
pub fn finalize_pending_commit(&mut self) -> Result<(), MlsError>
Merges any pending commit. Handles both:
- a self-issued commit produced by
MlsContext::invite_full/MlsContext::remove_members(merged viamerge_pending_commit); - a staged commit deposited by
MlsContext::process_message(merged viamerge_staged_commit, consumed fromMlsContext::pending_staged).
Idempotent: if there is nothing to merge, returns Ok. Called from
the GBP control plane in response to EXECUTE_TRANSITION.
Sourcepub fn clear_pending_commit(&mut self) -> Result<(), MlsError>
pub fn clear_pending_commit(&mut self) -> Result<(), MlsError>
Discards any pending commit (self-issued and/or staged) without
applying it. Used on ABORT_TRANSITION.
Sourcepub fn process_message(
&mut self,
msg_bytes: &[u8],
) -> Result<ProcessedKind, MlsError>
pub fn process_message( &mut self, msg_bytes: &[u8], ) -> Result<ProcessedKind, MlsError>
Applies a Commit (or staged Proposal) message to the group. Existing
members invoke this after receiving the Commit broadcast embedded in
PREPARE_TRANSITION args.
IMPORTANT: a Commit is staged but not merged here. It must be
merged via MlsContext::finalize_pending_commit in response to the
matching EXECUTE_TRANSITION, so that this side’s MLS epoch
advances together with the rest of the group — never earlier.
Calling this twice without an intervening finalize/clear discards
the previously staged commit (the second call wins).
Sourcepub fn accept_welcome(&mut self, welcome_bytes: &[u8]) -> Result<(), MlsError>
pub fn accept_welcome(&mut self, welcome_bytes: &[u8]) -> Result<(), MlsError>
Replaces the local group with the one described by the given
Welcome message.
Sourcepub fn group_id_16(&self) -> [u8; 16]
pub fn group_id_16(&self) -> [u8; 16]
Returns the 16-byte group identifier (truncated or zero-padded if the underlying MLS group_id has a different length).
Sourcepub fn export_state(&self) -> Result<Vec<u8>, MlsError>
pub fn export_state(&self) -> Result<Vec<u8>, MlsError>
Serialises the full local MLS state into an opaque blob that
MlsContext::restore_state can reconstruct verbatim. Lets a client
persist the context (disk / IndexedDB) so a chat survives a restart
without re-establishing the group — the basis for deterministic,
reload-surviving secret chats.
The blob bundles four length-prefixed (u32-LE) sections:
[provider storage | signer | identity | group_id]. It contains
private key material — callers MUST store it encrypted at rest.
Sourcepub fn restore_state(blob: &[u8]) -> Result<MlsContext, MlsError>
pub fn restore_state(blob: &[u8]) -> Result<MlsContext, MlsError>
Reconstructs a context from a blob produced by
MlsContext::export_state. The restored context is at the same epoch
with the same group state, signer and identity, and can immediately
send / receive again.
Sourcepub fn export_stream_key(
&self,
label: StreamLabel,
) -> Result<[u8; 32], MlsError>
pub fn export_stream_key( &self, label: StreamLabel, ) -> Result<[u8; 32], MlsError>
Exports a 32-byte secret under the given stream label.
Sourcepub fn export_raw(
&self,
label: &str,
context: &[u8],
len: usize,
) -> Result<Vec<u8>, MlsError>
pub fn export_raw( &self, label: &str, context: &[u8], len: usize, ) -> Result<Vec<u8>, MlsError>
Exports len bytes under an arbitrary label and context.
Used by external crates (e.g. hush-sframe) that need custom KDF
labels without depending on OpenMLS directly.
Sourcepub fn seal(
&self,
label: StreamLabel,
seq: u32,
plaintext: &[u8],
) -> Result<Vec<u8>, MlsError>
pub fn seal( &self, label: StreamLabel, seq: u32, plaintext: &[u8], ) -> Result<Vec<u8>, MlsError>
Encrypts plaintext with ChaCha20-Poly1305 using the stream-labelled
AEAD key and a nonce derived from the per-stream seq.
Sourcepub fn open(
&self,
label: StreamLabel,
seq: u32,
ciphertext: &[u8],
) -> Result<Vec<u8>, MlsError>
pub fn open( &self, label: StreamLabel, seq: u32, ciphertext: &[u8], ) -> Result<Vec<u8>, MlsError>
Decrypts ciphertext with the same parameters as MlsContext::seal.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for MlsContext
impl RefUnwindSafe for MlsContext
impl Send for MlsContext
impl Sync for MlsContext
impl Unpin for MlsContext
impl UnsafeUnpin for MlsContext
impl UnwindSafe for MlsContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more