1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Core p2panda data type offering distributed, secure and efficient data transfer between peers.
//!
//! Operations are used to carry any data from one peer to another (distributed), while assuming no
//! reliable network connection (offline-first) and untrusted machines (cryptographically secure).
//! The author of an operation uses it's [`SigningKey`](crate::SigningKey) to cryptographically sign
//! every operation. This can be verified and used for authentication by any other peer.
//!
//! Every operation consists of a [`Header`] and an optional [`Body`]. The body holds arbitrary
//! bytes (up to the application to decide what should be inside). The header is used to
//! cryptographically secure & authenticate the body and for providing ordered collections of
//! operations when required.
//!
//! Operations have a `backlink` and `seq_num` field in the header. These are used to form a linked
//! list of operations, where every subsequent operation points to the previous one by referencing
//! its cryptographically secured hash.
//!
//! Header extensions can be used to add additional information, like "pruning" points for removing
//! old or unwanted data, "tombstones" for explicit deletion, capabilities or group encryption
//! schemes or custom application-related features etc.
//!
//! Operations are encoded in CBOR format and use Ed25519 key pairs for digital signatures and
//! BLAKE3 for hashing.
//!
//! ## Examples
//!
//! ### Construct and sign a header
//!
//! ```
//! use p2panda_core::{Header, SigningKey};
//!
//! let signing_key = SigningKey::generate();
//!
//! let header = Header::builder()
//! .body(b"Hello, Icebear!")
//! .build(&signing_key, ());
//! ```
//!
//! ### Custom extensions
//!
//! ```
//! use p2panda_core::{Body, Header, SigningKey, PruneFlag};
//! use serde::{Serialize, Deserialize};
//!
//! let signing_key = SigningKey::generate();
//!
//! #[derive(Clone, Debug, Default, Serialize, Deserialize)]
//! struct CustomExtensions {
//! prune_flag: PruneFlag,
//! }
//!
//! let extensions = CustomExtensions {
//! prune_flag: PruneFlag::new(true),
//! };
//!
//! let body = Body::from_bytes("Prune from here please!".as_bytes());
//! let header = Header::builder()
//! .body(&body)
//! .build(&signing_key, extensions);
//!
//! assert!(header.extensions.prune_flag.is_set())
//! ```
pub use ;
pub use Body;
pub use Builder;
pub use ;
pub use ;
pub use ;
pub use ;