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