Expand description
§Clatter 🔊
no_std compatible, pure Rust implementation of the Noise framework
with support for Post Quantum (PQ) extensions 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 three types:
NqHandshake- Classical, non-post-quantum Noise handshakePqHandshake- Post-quantum Noise handshakeDualLayerHandshake- Dual layer handshake, which combines two Noise handshakes
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 messageHandshaker::read_message- Read next handshake messageHandshaker::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.
§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 | |
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 unsecure) PQ handshake pattern and no handshake payload data at all:
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 NqHandshakeCore and PqHandshakeCore types and
must implement your own custom RNG provides that implements the traits defined by
crate::traits::Rng.
Re-exports§
pub use traits::Handshaker;pub use rand_core;
Modules§
- bytearray
- Generic array utilities used throughout the crate
- cipherstate
- Cipherstate implementation
- constants
- Common constants and hard limits
- crypto
- Concrete crypto implementations
- error
- Error types used by Clatter
- handshakepattern
- Pre-made Noise handshake patterns and tools for defining new ones
- traits
- Common traits used throughout the crate
- transportstate
- Transport state implementation
Structs§
- Dual
Layer Handshake - Dual layer handshake
- KeyPair
- A zeroize-on-drop container for keys
- NqHandshake
Core - Non-post-quantum Noise handshake core with a generic RNG provider
- PqHandshake
Core - Post-quantum Noise handshake core with a generic RNG provider
Type Aliases§
- NqHandshake
getrandom - Non-post-quantum Noise handshake
- PqHandshake
getrandom - Post-quantum Noise handshake