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