Skip to main content

MlsContext

Struct MlsContext 

Source
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: OpenMlsRustCrypto

OpenMLS crypto provider.

§signer: SignatureKeyPair

Signing key pair for this member.

§group: MlsGroup

Current MLS group.

§credential: CredentialWithKey

Credential 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

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn finalize_pending_commit(&mut self) -> Result<(), MlsError>

Merges any pending commit. Handles both:

Idempotent: if there is nothing to merge, returns Ok. Called from the GBP control plane in response to EXECUTE_TRANSITION.

Source

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.

Source

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).

Source

pub fn accept_welcome(&mut self, welcome_bytes: &[u8]) -> Result<(), MlsError>

Replaces the local group with the one described by the given Welcome message.

Source

pub fn epoch(&self) -> u64

Returns the current group epoch.

Source

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).

Source

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.

Source

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.

Source

pub fn export_stream_key( &self, label: StreamLabel, ) -> Result<[u8; 32], MlsError>

Exports a 32-byte secret under the given stream label.

Source

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.

Source

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.

Source

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§

Source§

impl Sealer for MlsContext

Source§

fn seal( &mut self, st: StreamType, seq: u32, pt: &[u8], ) -> Result<Vec<u8>, MlsError>

Encrypts pt for the given stream and per-stream sequence number.
Source§

fn open( &mut self, st: StreamType, seq: u32, ct: &[u8], ) -> Result<Vec<u8>, MlsError>

Decrypts ct for the given stream and per-stream sequence number.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Classify for T

Source§

type Classified = T

Source§

fn classify(self) -> T

Source§

impl<T> Declassify for T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more