lib-q-hpke
RFC 9180–aligned Hybrid Public Key Encryption using post-quantum-only primitives (ML-KEM family for the HPKE KEM role in the default provider path; no classical KEM or classical signatures in that path).
Overview
lib-q-hpke implements HPKE for the lib-q stack: protocol logic and types in this crate, with KEM/AEAD/hash work delegated through lib-q-kem, lib-q-aead, and lib-q-hash. The high-level HpkeContext holds a lib_q_core::CryptoProvider for KemContext and an Arc<dyn HpkeCryptoProvider + Send + Sync> (default PostQuantumProvider) for encapsulation, KDF, AEAD, and exporter operations. Use HpkeContext::with_hpke_crypto to swap the HPKE backend; with_provider only replaces the inner KemContext crypto. Today the default provider wires ML-KEM only for HPKE KEM (other PQ KEMs may exist in the workspace but are not in the HpkeKem catalog yet).
Interoperability
Profiles, a mode×suite matrix, and fixture provenance are documented under the workspace interoperability.md and hpke-architecture.md. For code, see lib_q_hpke::interop. Run the integrator-oriented example (requires std):
cargo run -p lib-q-hpke --example hpke_interop_negotiation --features std
Supported Algorithms
Key Encapsulation Mechanisms (KEM)
- ML-KEM-512 (Level 1 security)
- ML-KEM-768 (Level 3 security)
- ML-KEM-1024 (Level 5 security)
Key Derivation Functions (KDF)
- HKDF-SHAKE128
- HKDF-SHAKE256
- HKDF-SHA3-256
- HKDF-SHA3-512
Authenticated Encryption (AEAD)
- Saturnin-256 (32-byte key, 16-byte nonce, 32-byte tag)
- SHAKE256-based AEAD (16-byte tag)
- Keccak duplex-sponge AEAD via
lib-q-aead— enable Cargo featureduplex-sponge-aeadon this crate (when using the umbrellalib-qcrate, enablehpke-duplex-aead) - Export-only mode (
HpkeAead::Export) for exporter-secret usage without message encryption
Quick Start
use ;
use HpkeContext;
use LibQCryptoProvider;
HPKE Modes
Base Mode
Standard HPKE without additional authentication.
let mut sender_ctx = hpke_ctx.setup_sender?;
let ciphertext = sender_ctx.seal?;
PSK Mode
Pre-shared key authentication.
let psk = b"shared-secret-key";
let psk_id = b"psk-identifier";
let mut sender_ctx = hpke_ctx.setup_sender_psk?;
Auth Mode
Sender authentication using asymmetric keys.
let mut sender_ctx = hpke_ctx.setup_sender_auth?;
AuthPSK Mode
Combined PSK and sender authentication.
let mut sender_ctx = hpke_ctx.setup_sender_auth_psk?;
PSK / AuthPSK wire format
For PSK and AuthPSK modes, the default is HpkePskWireFormat::Rfc9180 (RFC 9180 on-the-wire layout). Both peers may set HpkePskWireFormat::LibQCommitmentSuffix with HpkeContext::set_psk_wire_format to reject wrong (psk, psk_id) or a mismatched primary KEM ciphertext before decapsulation; that suffix is not interoperable with strict third-party RFC 9180 implementations.
Cargo features (summary)
| Feature | Purpose |
|---|---|
std |
Standard library support |
alloc |
Required for normal operation (enforced by the crate) |
ml-kem |
ML-KEM through lib-q-kem (default) |
hash |
HKDF hash backends via lib-q-hash (default) |
saturnin / shake256 |
AEAD algorithms (defaults) |
duplex-sponge-aead |
Duplex-sponge AEAD in HpkeAead::DuplexSpongeAead |
wasm |
wasm32 bindings and helpers |
secure-rng |
OS-backed RNG where applicable (default) |
See Cargo.toml for the full feature matrix and optional dev dependencies.
Documentation
- Architecture overview — workspace-level HPKE design (PQ-only path, PSK wire format, interoperability)
- API Reference — public API
- Security Considerations — security analysis and best practices
- Architecture details — module layout and provider wiring in this crate
Testing
The implementation includes comprehensive test coverage:
# Run all tests
# Run specific test suites
Wire sizes (KEM)
Public key and encapsulated ciphertext lengths match HpkeKem (public_key_len / enc_len):
| KEM | NIST category (approx.) | Public key | Encapsulated ciphertext |
|---|---|---|---|
| ML-KEM-512 | 1 | 800 B | 768 B |
| ML-KEM-768 | 3 | 1184 B | 1088 B |
| ML-KEM-1024 | 5 | 1568 B | 1568 B |
AEAD ciphertext expansion is plaintext length plus the AEAD tag (e.g. 32 bytes for Saturnin-256); see HpkeAead::tag_len in src/types.rs.
Dependencies
lib-q-core- Core cryptographic types and interfaceslib-q-kem- Key encapsulation mechanism implementationslib-q-hash- Hash function implementationslib-q-aead- Authenticated encryption implementationslib-q(Rust importlibq) —LibQCryptoProviderfor demos; production integrations may use narrower providers
License
This project is licensed under the same terms as the lib-q project.