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