Skip to main content

openmls/group/
mod.rs

1//! Group API for MLS
2//!
3//! This module contains the API to interact with groups.
4
5use std::fmt::Display;
6
7use serde::{Deserialize, Serialize};
8use tls_codec::*;
9
10use crate::extensions::*;
11use openmls_traits::random::OpenMlsRand;
12
13#[cfg(test)]
14use crate::ciphersuite::*;
15#[cfg(all(test, feature = "generate-kats"))]
16use crate::utils::*;
17
18// Crate
19pub(crate) mod errors;
20pub(crate) mod mls_group;
21pub(crate) mod public_group;
22
23// Public
24pub use errors::*;
25pub use group_context::GroupContext;
26pub use mls_group::builder::*;
27pub use mls_group::commit_builder::*;
28pub use mls_group::config::*;
29pub use mls_group::creation::*;
30pub use mls_group::membership::*;
31#[cfg(feature = "extensions-draft")]
32pub use mls_group::processing::{
33    AppDataDictionaryUpdater, AppDataUpdates, UnresolvedAppDataCommit,
34};
35pub use mls_group::proposal_store::*;
36pub use mls_group::staged_commit::StagedCommit;
37pub use mls_group::{Member, *};
38pub use public_group::*;
39
40// Private
41#[cfg(feature = "fork-resolution")]
42mod fork_resolution;
43mod group_context;
44
45// Tests
46#[cfg(any(feature = "test-utils", test))]
47pub(crate) mod tests_and_kats;
48
49/// A group ID. The group ID is chosen by the creator of the group and should be globally unique.
50#[derive(
51    Clone,
52    Debug,
53    PartialEq,
54    Eq,
55    PartialOrd,
56    Ord,
57    Hash,
58    Deserialize,
59    Serialize,
60    TlsDeserialize,
61    TlsDeserializeBytes,
62    TlsSerialize,
63    TlsSize,
64)]
65pub struct GroupId {
66    value: VLBytes,
67}
68
69impl GroupId {
70    /// Create a new (random) group ID.
71    ///
72    /// Group IDs should be random and not be misused as, e.g., a group name.
73    pub fn random(rng: &impl OpenMlsRand) -> Self {
74        Self {
75            value: rng.random_vec(16).expect("Not enough randomness.").into(),
76        }
77    }
78
79    /// Create a group ID from a byte slice.
80    ///
81    /// This should be used only if the group ID is chosen by an entity that ensures uniqueness.
82    pub fn from_slice(bytes: &[u8]) -> Self {
83        GroupId {
84            value: bytes.into(),
85        }
86    }
87
88    /// Returns the group ID as a byte slice.
89    pub fn as_slice(&self) -> &[u8] {
90        self.value.as_slice()
91    }
92
93    /// Returns the group ID as a byte vector.
94    pub fn to_vec(&self) -> Vec<u8> {
95        self.value.clone().into()
96    }
97}
98
99/// Group epoch. Internally this is stored as a `u64`.
100/// The group epoch is incremented with every valid Commit that is merged into the group state.
101#[derive(
102    Clone,
103    Copy,
104    Debug,
105    PartialEq,
106    Eq,
107    PartialOrd,
108    Ord,
109    Hash,
110    Deserialize,
111    Serialize,
112    TlsDeserialize,
113    TlsDeserializeBytes,
114    TlsSerialize,
115    TlsSize,
116)]
117pub struct GroupEpoch(u64);
118
119impl GroupEpoch {
120    /// Increment the group epoch by 1.
121    pub(crate) fn increment(&mut self) {
122        self.0 += 1;
123    }
124
125    /// Returns the group epoch as a `u64`.
126    pub fn as_u64(&self) -> u64 {
127        self.0
128    }
129}
130
131impl From<u64> for GroupEpoch {
132    fn from(val: u64) -> Self {
133        Self(val)
134    }
135}
136
137impl Display for GroupEpoch {
138    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139        f.write_fmt(format_args!("{}", self.0))
140    }
141}