p2panda_encryption/data_scheme/mod.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Data encryption for groups with post-compromise security and optional forward secrecy.
4//!
5//! This "Data Encryption" scheme allows peers to encrypt any data with a secret, symmetric key for
6//! a group. This will be useful for building applications where users who enter a group late will
7//! still have access to previously-created content, for example private knowledge or wiki
8//! applications or a booking tool for rehearsal rooms.
9//!
10//! A member will not learn about any newly-created data after they are removed from the group,
11//! since the key gets rotated on member removal or manual key update. This should accommodate for
12//! many use-cases in p2p applications which rely on basic group encryption with post-compromise
13//! security (PCS) and forward secrecy (FS) during key agreement.
14//!
15//! ## Messages
16//!
17//! Every group operation ([create](EncryptionGroup::create) or [update](EncryptionGroup::update)
18//! group, [add](EncryptionGroup::add) or [remove](EncryptionGroup::remove) member) results in a
19//! [`ControlMessage`] which is broadcast to the network for each group member, along with a set of direct messages.
20//!
21//! A [`DirectMessage`] is sent to a specific group member and contains the group secrets encrypted
22//! towards them for key agreement.
23//!
24//! Application messages contain the ciphertexts and parameters required to decrypt it.
25//!
26//! ## Key agreement and encryption
27//!
28//! The "Data Encryption" group API is mostly a wrapper around the [2SM (Two-Party Secure
29//! Messaging) key agreement protocol](crate::two_party). On creating or updating a group and
30//! removing a member, a new, random [`GroupSecret`] is [generated](SecretBundle::generate). Every
31//! secret is identified with a unique [`GroupSecretId`] and has a UNIX timestamp indicating when
32//! it was created.
33//!
34//! Peers maintain a [`SecretBundle`] with all group secrets inside. Secrets are added to the
35//! bundle when local group operations took place or when learning about a new secret from another
36//! member after receiving a control message.
37//!
38//! When sending new data into the group we [look up the latest secret](SecretBundleState::latest)
39//! in the bundle (via comparing timestamps) and use XChaCha20Poly1305 as an AEAD to [encrypt the
40//! payload](encrypt_data) with a random nonce. Next to each ciphertext the used nonce and group
41//! secret id is mentioned so other members of the group can [decrypt the data](decrypt_data).
42//!
43//! Members who have been added to the group will learn about the whole secret bundle included in a
44//! direct "welcome" message encrypted towards them using the 2SM protocol. Through this the added
45//! member will be able to decrypt all previously-created content as they will learn about all
46//! used secrets.
47//!
48//! ## Optional forward secrecy
49//!
50//! Applications can remove group secrets for forward secrecy based on their own logic. For
51//! removing group secrets implementers can use the [`EncryptionGroup::update_secrets`] method.
52//!
53//! For stronger forward secrecy guarantees have a look at the ["Message
54//! Encryption"](crate::message_scheme) scheme.
55//!
56//! ## Key bundles
57//!
58//! For initial key agreement (X3DH) peers need to publish key bundles into the network to allow
59//! others to invite them into groups. For the "Data Encryption" scheme we're using long-term
60//! pre-keys with lifetimes specified by the application.
61//!
62//! More on key bundles can be read [here](crate::key_bundle).
63//!
64//! ## Usage
65//!
66//! Check out the [`EncryptionGroup`] API for establishing and maintaining groups using the "Data
67//! Encryption" scheme.
68//!
69//! [`GroupSecret`] and [`SecretBundle`] are always explicitly passed into every group operation
70//! ("add member", "remove member", etc.) to allow full control over the managed keys for
71//! applications.
72//!
73//! Developers need to bring their own data types with [group message
74//! interfaces](crate::traits::GroupMessage), [decentralised group
75//! membership](crate::traits::GroupMembership) (DGM) and [ordering](crate::traits::Ordering)
76//! implementations when using this crate directly. For easier use without this overhead it's
77//! recommended to look into higher-level integrations using the p2panda stack.
78mod data;
79pub mod dcgka;
80pub mod group;
81pub mod group_secret;
82#[cfg(any(test, feature = "test_utils"))]
83pub mod test_utils;
84#[cfg(test)]
85mod tests;
86
87pub use data::{decrypt_data, encrypt_data};
88pub use dcgka::{ControlMessage, DirectMessage, DirectMessageContent, DirectMessageType};
89pub use group::{EncryptionGroup, GroupError, GroupOutput, GroupResult, GroupState};
90pub use group_secret::{
91 GROUP_SECRET_SIZE, GroupSecret, GroupSecretError, GroupSecretId, SecretBundle,
92 SecretBundleState,
93};