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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// only enables the `doc_cfg` feature when
// the `docsrs` configuration attribute is defined
//! # Clatter 🔊
//!
//! `no_std` compatible, pure Rust implementation of the [**Noise framework**](https://noiseprotocol.org/noise.html)
//! with support for [**Post Quantum (PQ) extensions**](https://doi.org/10.1145/3548606.3560577) as presented by
//! Yawning Angel, Benjamin Dowling, Andreas Hülsing, Peter Schwabe, and Fiona Johanna Weber.
//!
//! ⚠️ **Warning** ⚠️
//!
//! Clatter is a low-level crate that does not provide much guidance on the security aspects of the protocol(s)
//! you develop using it. Clatter itself is safe and sound but can easily be used in many unreliable ways.
//! Solid understanding of cryptography is required.
//!
//! From user perspective, everything in this crate is built around the available handshake types:
//!
//! * [`NqHandshake`] - Classical, non-post-quantum Noise handshake
//! * [`PqHandshake`] - Post-quantum Noise handshake
//! * [`HybridHandshake`] - *true hybrid* handshake which combines both NQ and PQ security in the same handshake messages
//! * [`HybridDualLayerHandshake`] - *outer-encrypts-inner* style piped handshake with cryptographic binding between the layers
//! * [`DualLayerHandshake`] - *outer-encrypts-inner* style piped handshake with fully independent layers
//!
//! Users will pick and instantiate the desired handshake state machine with the crypto primitives
//! and [`handshakepattern::HandshakePattern`] they wish to use and complete the handshake using the
//! methods provided by the common [`Handshaker`] trait:
//!
//! * [`Handshaker::write_message`] - Write next handshake message
//! * [`Handshaker::read_message`] - Read next handshake message
//! * [`Handshaker::is_finished`] - Is the handshake ready?
//! * [`Handshaker::finalize`] - Move to transport state
//!
//! Handshake messages are exchanged by the peers until the handshake is completed.
//! After completion, [`Handshaker::finalize`] is called and the handshake state machine
//! is consumed into a [`transportstate::TransportState`] instance, which can be used
//! to encrypt and decrypt communication between the peers.
//!
//! ## Handshake Patterns
//!
//! Selected fundamental Noise and PQNoise patterns are available pre-made in the [`handshakepattern`] module.
//! Utilities in that module can also be used to craft additional handshake patterns.
//!
//! Pre-made hybrid patterns for the [`HybridHandshake`] type are also available. These patterns are constructed
//! by combining the classic Noise NQ patterns with PQNoise patterns in a way which preserves the relative ordering
//! of `DH`, `KEM` and key transmission operations.
//!
//! ## Crypto Vendors
//!
//! Currently Clatter has frozen the available selection of DH, Cipher and Hash algorithms, but users
//! of Clatter can select from multiple KEM vendors.
//!
//! Concrete implementations of the crypto algorithms are in the [`crypto`] module and it is even
//! possible to use custom implementations using the definitions in the [`traits`] module.
//!
//! ## Features
//!
//! To improve build times and produce more optimized binaries, Clatter can be heavily configured by
//! enabling and disabling crate features. Below is a listing of the available features:
//!
//! | Feature flag | Description | Default | Details |
//! | --- | --- | --- | --- |
//! | `use-25519` | Enable X25519 DH | yes | |
//! | `use-aes-gcm` | Enable AES-GCM cipher | yes | |
//! | `use-chacha20poly1305` | Enable ChaCha20-Poly1305 cipher | yes | |
//! | `use-sha` | Enable SHA-256 and SHA-512 hashing | yes | |
//! | `use-blake2` | Enable BLAKE2 hashing | yes | |
//! | `use-rust-crypto-ml-kem` | Enable ML-KEM (Kyber) KEMs by RustCrypto | yes | |
//! | `use-pqclean-ml-kem` | Enable ML-KEM (Kyber) KEMs by PQClean | yes | Requires `getrandom` |
//! | `std` | Enable standard library support | yes | Enables `std` for supported dependencies |
//! | `alloc` | Enable allocator support | yes | Enables dynamically sized buffer types in [`crate::bytearray`] |
//! | `getrandom` | Enable automatic system RNG support via [`getrandom`] | yes | Can be used without `std` |
//!
//! ## Example
//!
//! Simplified example with the most straightforward (and insecure) PQ handshake pattern and
//! no handshake payload data at all:
//!
//! ```rust
//! use clatter::crypto::cipher::ChaChaPoly;
//! use clatter::crypto::hash::Sha512;
//! use clatter::crypto::kem::pqclean_ml_kem::MlKem1024;
//! // We can mix and match KEMs from different vendors
//! use clatter::crypto::kem::rust_crypto_ml_kem::MlKem512;
//! use clatter::handshakepattern::noise_pqnn;
//! use clatter::traits::Handshaker;
//! use clatter::PqHandshake;
//!
//!
//! let mut alice = PqHandshake::<MlKem512, MlKem1024, ChaChaPoly, Sha512>::new(
//! noise_pqnn(),
//! &[],
//! true,
//! None,
//! None,
//! None,
//! None,
//! )
//! .unwrap();
//!
//! let mut bob = PqHandshake::<MlKem512, MlKem1024, ChaChaPoly, Sha512>::new(
//! noise_pqnn(),
//! &[],
//! false,
//! None,
//! None,
//! None,
//! None,
//! )
//! .unwrap();
//!
//! // Handshake message buffers
//! let mut buf_alice = [0u8; 4096];
//! let mut buf_bob = [0u8; 4096];
//!
//! // First handshake message from initiator to responder
//! // e -->
//! let n = alice.write_message(&[], &mut buf_alice).unwrap();
//! let _ = bob.read_message(&buf_alice[..n], &mut buf_bob).unwrap();
//!
//! // Second handshake message from responder to initiator
//! // <-- ekem
//! let n = bob.write_message(&[], &mut buf_bob).unwrap();
//! let _ = alice.read_message(&buf_bob[..n], &mut buf_alice).unwrap();
//!
//! // Handshake should be done
//! assert!(alice.is_finished() && bob.is_finished());
//!
//! // Finish handshakes and move to transport mode
//! let mut alice = alice.finalize().unwrap();
//! let mut bob = bob.finalize().unwrap();
//!
//! // Send a message from Alice to Bob
//! let msg = b"Hello from initiator";
//! let n = alice.send(msg, &mut buf_alice).unwrap();
//! let n = bob.receive(&buf_alice[..n], &mut buf_bob).unwrap();
//!
//! println!(
//! "Bob received from Alice: {}",
//! str::from_utf8(&buf_bob[..n]).unwrap()
//! );
//! ```
//!
//! ## `no_std` targets
//!
//! `std` feature is enabled by default. Disable default features and pick only the ones
//! you require when running on `no_std` targets.
//!
//! The only real platform service Clatter requires is the RNG. Clatter includes full
//! support for the [`getrandom`] crate (via the `getrandom` feature flag) which can be
//! enabled without `std` features. If your platform is not already supported by
//! `getrandom`, the most straightforward way to use Clatter is to create `getrandom`
//! bindings for your custom platform backend. Detailed instructions and examples can be
//! found in the [`getrandom`] crate documentation.
//!
//! If you do not add `getrandom` support, Clatter can still be used. In this case you
//! are restricted to the lower-level handshake core types, such as [`NqHandshakeCore`]
//! and [`PqHandshakeCore`] and must implement your own custom RNG provider that implements
//! the traits defined by [`crate::traits::Rng`].
extern crate alloc;
pub use DualLayerHandshake;
pub use ;
pub use HybridDualLayerHandshake;
pub use NqHandshakeCore;
pub use PqHandshakeCore;
pub use rand_core;
pub use Handshaker;
use ;
pub use ;
/// Concrete crypto implementations
/// A zeroize-on-drop container for keys