pqc_kem/lib.rs
1//! # pqc-kem — Post-Quantum Key Encapsulation Mechanisms
2//!
3//! A pure Rust, `no_std`-capable library implementing post-quantum KEM
4//! algorithms, meant to be imported into other builds — not built or run on
5//! its own. (For the WASM/JS bindings and the standalone `.wasm` artifact,
6//! see the sibling `pqc-kem-wasm` crate.)
7//!
8//! - **ML-KEM** (NIST FIPS 203) — Primary standard, pure Rust, WASM-native
9//! - [`fips203::MlKem512Keypair`] — Security Level 1
10//! - [`fips203::MlKem768Keypair`] — Security Level 3 (recommended)
11//! - [`fips203::MlKem1024Keypair`] — Security Level 5
12//! - [`fips203::HybridKemKeypair`] — X25519 + ML-KEM-768 hybrid (primary construction)
13//!
14//! - **HQC** (NIST 2025) — Code-based alternative, gated behind `hqc` feature.
15//! Real implementation via `liboqs` (native targets only, not WASM).
16//! - `hqc::Hqc128Keypair`, `hqc::Hqc192Keypair`, `hqc::Hqc256Keypair` (only
17//! compiled with `--features hqc`; plain code spans here, not links, so
18//! `cargo doc --no-deps` stays warning-free with default features, where
19//! these types do not exist)
20//!
21//! ## Quick Start
22//!
23//! ```rust,no_run
24//! use pqc_kem::fips203::HybridKemKeypair;
25//! use rand::rngs::OsRng;
26//!
27//! // Recipient generates keypair
28//! let recipient = HybridKemKeypair::generate(&mut OsRng).unwrap();
29//! let pub_key = recipient.public_key();
30//!
31//! // Sender encapsulates
32//! let x25519_pub = pub_key.x25519_bytes().unwrap();
33//! let mlkem_pub = pub_key.mlkem_bytes().unwrap();
34//! let x25519_arr: [u8; 32] = x25519_pub.try_into().unwrap();
35//! let (ciphertext, sender_ss) = HybridKemKeypair::encapsulate(
36//! &mut OsRng,
37//! &x25519_arr,
38//! &mlkem_pub,
39//! ).unwrap();
40//!
41//! // Recipient decapsulates
42//! let recipient_ss = recipient.decapsulate(&ciphertext).unwrap();
43//! assert_eq!(sender_ss.bytes, recipient_ss.bytes);
44//! ```
45//!
46//! ## WASM Target Support
47//!
48//! This crate builds cleanly as an ordinary library dependency for
49//! `wasm32-unknown-unknown` (e.g. from inside a `wasm-bindgen`/`wasm-pack`
50//! project of your own) — no special feature needed; the `getrandom`
51//! backend required for that target is wired in automatically (see
52//! Cargo.toml). It does **not** ship JS bindings or build as a `.wasm`
53//! artifact itself — that packaging lives in the sibling `pqc-kem-wasm`
54//! crate, which depends on this one.
55//!
56//! ## `no_std` Support
57//!
58//! This crate is `no_std`-compatible with `alloc`, and is **always** just a
59//! library — it never defines `#[global_allocator]` or `#[panic_handler]`
60//! itself (a library crate can't validly infer from its own feature flags
61//! whether the program linking it has `std` elsewhere; only the final
62//! binary knows that, and only it should supply those). Disable the `std`
63//! feature to use the `no_std` path:
64//! ```toml
65//! pqc-kem = { version = "0.2", default-features = false }
66//! ```
67//! The program embedding this crate is responsible for supplying its own
68//! allocator and panic handler if it, in turn, has no `std` either.
69//!
70//! ---
71//!
72//! ## The 0x307 crate family
73//!
74//! `pqc-kem` is one of six open-source crates from [0x307](https://0x307.com/crates), held to one
75//! audit and stability standard.
76//!
77//! | Crate | Tier | What it does |
78//! |---|---|---|
79//! | [pqc-sig](https://crates.io/crates/pqc-sig) | Production | ML-DSA, SLH-DSA and FN-DSA signatures (FIPS 204/205/206) |
80//! | [pqc-kem](https://crates.io/crates/pqc-kem) (this crate) | Production | ML-KEM (FIPS 203), the X25519 + ML-KEM-768 hybrid, X-Wing, and sealed boxes |
81//! | [aethel-core](https://crates.io/crates/aethel-core) | Production | Post-quantum anonymous identity: a separate identifier per context, context-bound ML-DSA signing |
82//! | [aethel-sdk](https://crates.io/crates/aethel-sdk) | Preview | The SDK over aethel-core, and the place to start |
83//! | [aethel-vault](https://crates.io/crates/aethel-vault) | Preview | Agent-held wallet: policy-gated x402 / EIP-3009 signing with ML-DSA-65 spend records |
84//! | [pqc-privacy](https://crates.io/crates/pqc-privacy) | Lab | Research bundle, kept off every identity and payment path |
85//!
86//! **Production** crates are thin, standards-bound libraries meant to be depended on today. **Preview** crates work and are published, with APIs still settling. **Lab** crates are research, never on an identity or payment path.
87//!
88//! **Runnable examples:** [0x307/examples](https://github.com/0x307/examples), one program per
89//! crate, pinned to the published versions.
90//!
91//! **Audit status:** None of these crates has been independently audited, and none holds a CMVP / FIPS 140-3 validation. "FIPS 203/204/205/206" means the algorithms follow those standards, not that the code is certified. Known issues for this crate are in
92//! [SECURITY.md](https://github.com/0x307/pqc-kem/blob/main/SECURITY.md). Versioning and yanks:
93//! [STABILITY.md](https://github.com/0x307/pqc-kem/blob/main/STABILITY.md).
94//!
95
96#![cfg_attr(not(feature = "std"), no_std)]
97#![forbid(unsafe_code)]
98
99#[cfg(not(feature = "std"))]
100extern crate alloc;
101
102// ── Public Modules ────────────────────────────────────────────────────────────
103
104/// Error types for all KEM operations.
105pub mod error;
106
107/// Wire types: public keys, ciphertexts, shared secrets, algorithm identifiers.
108pub mod types;
109
110/// ML-KEM (NIST FIPS 203) — pure Rust, WASM-native.
111pub mod fips203;
112
113/// HQC (NIST 2025 standard) — gated behind `hqc` feature. Real implementation
114/// via `liboqs`, native targets only (not WASM).
115pub mod hqc;
116
117/// KEM shared secret → HKDF-SHA256 → AEAD-sealed payload, in one path.
118/// Gated behind the non-default `aead-wrap` feature.
119#[cfg(feature = "aead-wrap")]
120pub mod aead_wrap;
121
122// ── Top-Level Re-exports ──────────────────────────────────────────────────────
123
124pub use error::{KemError, KemResult};
125pub use types::{
126 HybridKemCiphertext,
127 HybridProfile,
128 HybridPublicKey,
129 KemAlgorithm,
130 KemCiphertext,
131 KemPublicKey,
132 KemSecretKey,
133 SharedSecret,
134};
135
136// Primary recommended types — re-exported at crate root for convenience
137pub use fips203::{
138 HybridKemKeypair,
139 MlKem512Keypair,
140 MlKem768Keypair,
141 MlKem1024Keypair,
142 XWingKeypair,
143};
144
145// ── Version ───────────────────────────────────────────────────────────────────
146
147/// Crate version string.
148pub const VERSION: &str = env!("CARGO_PKG_VERSION");
149
150/// Algorithm suite identifier for the primary hybrid construction.
151pub const PRIMARY_ALGORITHM: &str = "X25519+ML-KEM-768";
152
153/// HKDF info string used in the hybrid KEM construction (profile v1).
154pub const HYBRID_KEM_INFO: &str = "pqc-kem-hybrid-v1";
155
156// ── Named Hybrid KEM Profiles (K-5, WP5) ───────────────────────────────────────
157//
158// See `docs/hybrid-profiles.md` for the full normative spec of both
159// profiles: canonical byte layouts, combiners, and test vectors.
160
161/// Profile identifier for this crate's original hybrid combiner
162/// (`fips203::HybridKemKeypair`) — wire-compatible with every prior 0.x
163/// release. `HKDF-SHA256(x25519_ss ‖ mlkem_ss, info="pqc-kem-hybrid-v1")`;
164/// does not bind ciphertext/public key into the KDF.
165pub const HYBRID_PROFILE_V1: &str = "HybridKem-X25519-MLKEM768-v1";
166
167/// Profile identifier for X-Wing (`fips203::XWingKeypair`,
168/// `draft-connolly-cfrg-xwing-kem`) — `SHA3-256`-based combiner that binds
169/// `ct_X`/`pk_X`. **Recommended for new deployments.**
170pub const HYBRID_PROFILE_V2: &str = "HybridKem-X25519-MLKEM768-v2";
171
172/// Alias for [`HYBRID_PROFILE_V1`], kept for wire/API compatibility with
173/// existing deployments that already treat this constant as identifying
174/// `PRIMARY_ALGORITHM`'s hybrid construction. Points at v1, not v2 — see
175/// `docs/hybrid-profiles.md` for the rationale and migration guidance.
176pub const HYBRID_PROFILE_ID: &str = HYBRID_PROFILE_V1;