pq_safe_kyber/lib.rs
1//! # Kyber
2//!
3//! A rust implementation of the Kyber algorithm
4//!
5//! This library:
6//! * Is no_std compatible and uses no allocations, suitable for embedded devices.
7//! * The reference files contain no unsafe code.
8//! * Compiles to WASM using wasm-bindgen.
9//!
10//! ## Features
11//! If no security level is set then kyber768 is used, this is roughly equivalent to AES-196. See below for setting other levels.
12//! A compile-time error is raised if more than one level is specified. Besides that all other features can be mixed as needed:
13//!
14//! | Feature | Description |
15//! |-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
16//! | kyber512 | Enables kyber512 mode, with a security level roughly equivalent to AES-128. |
17//! | kyber1024 | Enables kyber1024 mode, with a security level roughly equivalent to AES-256. |
18//! | wasm | For compiling to WASM targets. |
19//! | zeroize | This will zero out the key exchange structs on drop using the [zeroize](https://docs.rs/zeroize/latest/zeroize/) crate |
20//! | std | Enable the standard library |
21//!
22//! ## Usage
23//!
24//!
25//! ```
26//! use pq_safe_kyber::*;
27//! ```
28//!
29//! ##### Key Encapsulation
30//! ```
31//! # use pq_safe_kyber::*;
32//! # fn main() -> Result<(),KyberError> {
33//! # let mut rng = rand::rng();
34//! // Generate Keypair
35//! let keys_bob = keypair(&mut rng);
36//!
37//! // Alice encapsulates a shared secret using Bob's public key
38//! let (ciphertext, shared_secret_alice) = encapsulate(&keys_bob.public, &mut rng)?;
39//!
40//! // Bob decapsulates a shared secret using the ciphertext sent by Alice
41//! let shared_secret_bob = decapsulate(&ciphertext, &keys_bob.secret)?;
42//!
43//! assert_eq!(shared_secret_alice, shared_secret_bob);
44//! # Ok(()) }
45//! ```
46//!
47//! Higher level functions offering unilateral or mutual authentication
48//!
49//! #### Unilaterally Authenticated Key Exchange
50//! ```
51//! # use pq_safe_kyber::*;
52//! # fn main() -> Result<(),KyberError> {
53//! let mut rng = rand::rng();
54//!
55//! // Initialize the key exchange structs
56//! let mut alice = Uake::new();
57//! let mut bob = Uake::new();
58//!
59//! // Generate Keypairs
60//! let alice_keys = keypair(&mut rng);
61//! let bob_keys = keypair(&mut rng);
62//!
63//! // Alice initiates key exchange
64//! let client_init = alice.client_init(&bob_keys.public, &mut rng);
65//!
66//! // Bob authenticates and responds
67//! let server_send = bob.server_receive(
68//! client_init, &bob_keys.secret, &mut rng
69//! )?;
70//!
71//! // Alice decapsulates the shared secret
72//! alice.client_confirm(server_send)?;
73//!
74//! // Both key exchange structs now have the shared secret
75//! assert_eq!(alice.shared_secret, bob.shared_secret);
76//! # Ok(()) }
77//! ```
78//!
79//! #### Mutually Authenticated Key Exchange
80//! Follows the same workflow except Bob requires Alice's public key
81//!
82//! ```
83//! # use pq_safe_kyber::*;
84//! # fn main() -> Result<(),KyberError> {
85//! # let mut rng = rand::rng();
86//! let mut alice = Ake::new();
87//! let mut bob = Ake::new();
88//!
89//! let alice_keys = keypair(&mut rng);
90//! let bob_keys = keypair(&mut rng);
91//!
92//! let client_init = alice.client_init(&bob_keys.public, &mut rng);
93//!
94//! let server_send = bob.server_receive(
95//! client_init, &alice_keys.public, &bob_keys.secret, &mut rng
96//! )?;
97//!
98//! alice.client_confirm(server_send, &alice_keys.secret)?;
99//!
100//! assert_eq!(alice.shared_secret, bob.shared_secret);
101//! # Ok(()) }
102//! ```
103//!
104//!
105//! ## Errors
106//! The [KyberError](enum.KyberError.html) enum handles errors. It has two variants:
107//!
108//! * **InvalidInput** - One or more byte inputs to a function are incorrectly sized. A likely cause of
109//! this is two parties using different security levels while trying to negotiate a key exchange.
110//!
111//! * **Decapsulation** - The ciphertext was unable to be authenticated. The shared secret was not decapsulated
112
113#![cfg_attr(not(feature ="std"), no_std)]
114#![allow(clippy::many_single_char_names)]
115
116// Prevent usage of mutually exclusive features
117#[cfg(all(feature = "kyber1024", feature = "kyber512"))]
118compile_error!("Only one security level can be specified");
119
120mod reference;
121use reference::*;
122
123#[cfg(feature = "wasm")]
124mod wasm;
125
126mod api;
127mod error;
128mod kem;
129mod kex;
130mod params;
131mod rng;
132mod symmetric;
133
134pub use api::*;
135pub use kex::*;
136pub use params::*;
137pub use error::KyberError;
138pub use rand_core::{Rng, CryptoRng, TryRng, TryCryptoRng, Infallible};
139
140// Feature hack to expose private functions for the Known Answer Tests
141// and fuzzing. Will fail to compile if used outside `cargo test` or
142// the fuzz binaries.
143#[cfg(any(kyber_kat, fuzzing, feature = "benchmarking"))]
144pub use kem::*;