#cryptography #crypto #key-exchange #encryption #aead

no-std hpke

An implementation of the HPKE hybrid encryption standard in pure Rust

16 releases (4 breaking)

new 0.5.0 Feb 22, 2021
0.4.2 Dec 16, 2020
0.4.1 Nov 9, 2020
0.1.8 Jul 17, 2020

#165 in Cryptography

Download history 293/week @ 2020-11-04 302/week @ 2020-11-11 502/week @ 2020-11-18 363/week @ 2020-11-25 158/week @ 2020-12-02 113/week @ 2020-12-09 98/week @ 2020-12-16 7/week @ 2020-12-23 47/week @ 2020-12-30 36/week @ 2021-01-06 26/week @ 2021-01-13 202/week @ 2021-01-20 307/week @ 2021-01-27 97/week @ 2021-02-03 309/week @ 2021-02-10 310/week @ 2021-02-17

682 downloads per month
Used in 2 crates (via odoh-rs)




Version Docs CI Coverage

This is an work-in-progress implementation of the HPKE hybrid encryption standard.

What it implements

This implementation complies with the HPKE draft up to commit de0787a.

Here are all the primitives listed in the spec. The primitives with checked boxes are the ones that are implemented.

  • KEMs
    • DHKEM(Curve25519, HKDF-SHA256)
    • DHKEM(Curve448, HKDF-SHA512)
    • DHKEM(P-256, HKDF-SHA256)
    • DHKEM(P-384, HKDF-SHA384)
    • DHKEM(P-521, HKDF-SHA512)
  • KDFs
    • HKDF-SHA256
    • HKDF-SHA384
    • HKDF-SHA512
  • AEADs
    • AES-GCM-128
    • AES-GCM-256
    • ChaCha20Poly1305

Crate Features

Default features flags: x25519, p256.

Feature flag list:

  • x25519 - Enables X25519-based KEMs
  • p256 - Enables NIST P-256-based KEMs
  • serde_impls - Includes implementations of serde::Serialize and serde::Deserialize for all hpke::Serializable and hpke::Deserializable types
  • std - Necessary for running known-answer tests. No need to enable unless you're debugging this crate.

For info on how to omit or include feature flags, see the cargo docs on features.


To run all tests, execute cargo test --all-features. This includes known-answer tests, which test against test-vector-COMMIT_ID.json,where COMMIT_ID is the short commit of the version of the spec that the test vectors came from. See the reference implementation for information on how to generate a test vector.


To run all benchmarks, execute cargo bench --all-features. If you set your own feature flags, the benchmarks will still work, and run the subset of benches that it is able to. The results of a benchmark can be read as a neat webpage at target/criterion/report/index.html.

Ciphersuites benchmarked:

  • NIST Ciphersuite with 128-bit security: AES-GCM-128, HKDF-SHA256, ECDH-P256
  • Non-NIST Ciphersuite with 128-bit security: ChaCha20-Poly1305, HKDF-SHA256, X25519

Functions benchmarked in each ciphersuite:

  • Kem::gen_keypair
  • setup_sender with OpModes of Base, Auth, Psk, and AuthPsk
  • setup_receiver with OpModes of Base, Auth, Psk, and AuthPsk
  • AeadCtxS::seal with plaintext length 64 and AAD length 64
  • AeadCtxR::open with ciphertext length 64 and AAD length 64

Usage Examples

See the client-server example for an idea of how to use HPKE.


A definition: crypto agility refers to the ability of a cryptosystem or protocol to vary its underlying primitives. For example, TLS has "crypto agility" in that you can run the protocol with many different ciphersuites.

This crate does not support crypto agility out of the box. This is because the cryptographic primitives are encoded as types satisfying certain constraints, and types need to be determined at compile time (broadly speaking). That said, there is nothing preventing you from implementing agility yourself. There is a sample implementation in the examples folder. The sample implementation is messy because agility is messy.

What's next

  • Add support for more KEMs
  • More examples


Licensed under either of

at your option.


This code has not been audited in any sense of the word. Use at your own discretion.


~73K SLoC