Skip to main content

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::*;