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