Creating groups

There are two ways to create a group: Either by building an MlsGroup directly, or by using an MlsGroupCreateConfig. The former is slightly simpler, while the latter allows the creating of multiple groups using the same configuration. See Group configuration for more details on group parameters.

In addition to the group configuration, the client should define all supported and required extensions for the group. The negotiation mechanism for extension in MLS consists in setting an initial list of extensions at group creation time and choosing key packages of subsequent new members accordingly.

In practice, the supported and required extensions are set by adding them to the initial KeyPackage of the creator:

    // Create the key package
    KeyPackage::builder()
        .key_package_extensions(extensions)
        .build(ciphersuite, provider, signer, credential_with_key)
        .unwrap()

After that, the group can be created either using a config:

    let mut alice_group = MlsGroup::new(
        provider,
        &alice_signature_keys,
        &mls_group_create_config,
        alice_credential.clone(),
    )
    .expect("An unexpected error occurred.");

... or using the builder pattern:

        let mut alice_group = MlsGroup::builder()
            .padding_size(100)
            .sender_ratchet_configuration(SenderRatchetConfiguration::new(
                10,   // out_of_order_tolerance
                2000, // maximum_forward_distance
            ))
            .ciphersuite(ciphersuite)
            .use_ratchet_tree_extension(true)
            .build(provider, &alice_signature_keys, alice_credential.clone())
            .expect("An unexpected error occurred.");

Note: Every group is assigned a random group ID during creation. The group ID cannot be changed and remains immutable throughout the group's lifetime. Choosing it randomly makes sure that the group ID doesn't collide with any other group ID in the same system.

If someone else already gave you a group ID, e.g., a provider server, you can also create a group using a specific group ID:

        // Some specific group ID generated by someone else.
        let group_id = GroupId::from_slice(b"123e4567e89b");

        let mut alice_group = MlsGroup::new_with_group_id(
            provider,
            &alice_signature_keys,
            &mls_group_create_config,
            group_id,
            alice_credential.clone(),
        )
        .expect("An unexpected error occurred.");

The Builder provides methods for setting required capabilities and external senders. The information passed into these lands in the group context, in the form of extensions. Should the user want to add further extensions, they can use the with_group_context_extensions method:

        // we are adding an external senders list as an example.
        let extensions =
            Extensions::from_vec(vec![Extension::ExternalSenders(external_senders_list)])
                .expect("failed to create extensions list");

        let mut alice_group = MlsGroup::builder()
            .padding_size(100)
            .sender_ratchet_configuration(SenderRatchetConfiguration::new(
                10,   // out_of_order_tolerance
                2000, // maximum_forward_distance
            ))
            .with_group_context_extensions(extensions) // NB: the builder method returns a Result
            .expect("failed to apply group context extensions")
            .use_ratchet_tree_extension(true)
            .build(provider, &alice_signature_keys, alice_credential.clone())
            .expect("An unexpected error occurred.");