Module openmls::key_packages

source ·
Expand description

Key Packages

Key packages are pre-published public keys that provide some information about a user in order to facilitate the asynchronous addition of clients to a group.

A key package object specifies:

  • A protocol version and ciphersuite that the client supports
  • A public key that others can use for key agreement
  • A credential authenticating the client’s application-layer identity
  • A list of extensions for the key package (see Extensions for details)

Key packages are intended to be used only once and SHOULD NOT be reused except in case of last resort, i.e. if there’s no other key package available. Clients MAY generate and publish multiple KeyPackages to support multiple ciphersuites.

The value for HPKE init key MUST be a public key for the asymmetric encryption scheme defined by ciphersuite, and it MUST be unique among the set of key packages created by this client. The whole structure is signed using the client’s signature key. A key package object with an invalid signature field is considered malformed.

Creating key package bundles

Key package bundles are key packages including their private key. A key package bundle can be created as follows:

use openmls::prelude::*;
use openmls_rust_crypto::OpenMlsRustCrypto;
use openmls_basic_credential::SignatureKeyPair;

let ciphersuite = Ciphersuite::MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;
let backend = OpenMlsRustCrypto::default();

let credential = Credential::new("identity".into(), CredentialType::Basic).unwrap();
let signer =
        .expect("Error generating a signature key pair.");
let credential_with_key = CredentialWithKey {
    signature_key: signer.public().into(),
let key_package = KeyPackage::builder()
        CryptoConfig {
            version: ProtocolVersion::default(),

See KeyPackage for more details and other ways to create key packages.

Loading key packages

When getting key packages from another user the serialized bytes are parsed as follows;

use openmls::prelude::*;
use openmls::test_utils::hex_to_bytes;
use openmls_rust_crypto::OpenMlsRustCrypto;

let backend = OpenMlsRustCrypto::default();
let ciphersuite = Ciphersuite::MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;

let key_package_bytes = hex_to_bytes(

let key_package_in = KeyPackageIn::tls_deserialize(&mut key_package_bytes.as_slice())
    .expect("Could not deserialize KeyPackage");

let key_package = key_package_in
    .validate(backend.crypto(), ProtocolVersion::Mls10)
    .expect("Invalid KeyPackage");

See KeyPackage for more details on how to use key packages.



  • Key Package errors
  • Incoming KeyPackages. This modules contains deserialization and validation of KeyPackages.


  • The key package struct.
  • Builder that helps creating (and configuring) a KeyPackage.
  • The lifetime represents the times between which clients will consider a KeyPackage valid. This time is represented as an absolute time, measured in seconds since the Unix epoch (1970-01-01T00:00:00Z). A client MUST NOT use the data in a KeyPackage for any processing before the not_before date, or after the not_after date.