Skip to content

rozbb/rust-hpke

Repository files navigation

rust-hpke

Version Docs CI

This is an implementation of the HPKE hybrid encryption standard (RFC 9180).

What It Implements

This implementation complies with the HPKE standard (RFC 9180). It also implements the pure post-quantum KEMs defined in draft-ietf-hpke-pq-04, and the hybrid post-quantum KEMs defined in draft-connolly-cfrg-xwing-kem-10, draft-irtf-cfrg-concrete-hybrid-kems-03, and draft-irtf-cfrg-hybrid-kems-11 (this is all quite confusing, see Filippo's summary of it).

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

  • Classical KEMs
    • DHKEM(Curve25519, HKDF-SHA256)
    • DHKEM(Curve448, HKDF-SHA512)
    • DHKEM(P-256, HKDF-SHA256)
    • DHKEM(P-384, HKDF-SHA384)
    • DHKEM(P-521, HKDF-SHA512)
  • Post-quantum and hybrid KEMs
    • ML-KEM-768
    • ML-KEM-1024
    • MLKEM768-X25519, aka X-Wing
    • MLKEM768-P256
    • MLKEM1024-P384
  • KDFs
    • HKDF-SHA256
    • HKDF-SHA384
    • HKDF-SHA512
    • SHAKE128
    • SHAKE256
    • TurboSHAKE128
    • TurboSHAKE256
  • AEADs
    • AES-GCM-128
    • AES-GCM-256
    • ChaCha20Poly1305

Crate Features

The feature flags in this crate allow end-users to avoid pulling in dependencies they don't want. We thus take an additive approach to features: if you want hybrid post-quantum KEMs, you need to pull in the individual features it relies on. All is explained below.

Feature Flags

Default features flags: getrandom, alloc, chacha, x25519, mlkem. Note this combination means that XWing is enabled by default, as well as all (Turbo)SHAKE KDFs.

  • alloc - Exposes allocating methods like AeadCtxR::open() and AeadCtxS::seal()
  • getrandom (default) - Enables top-level functions that use getrandom for random number generation, rather than taking in an explicit RNG
  • AEADs:
    • chacha — Enables ChaCha20-Poly1305
    • aes — Enables AES-GCM-128/256
  • KEMs:
    • x25519 — Enables the X25519 DHKEM (also enables hkdfsha2)
    • nistp — Enables the ECDH-NIST P-256, P-384, and P-521 DHKEMs (also enables hkdfsha2)
    • mlkem — Enables the ML-KEM-768 and ML-KEM-1024 post-quantum KEMs (also enables shake)
  • KDFs:
    • hkdfsha2 — Enables HKDF-SHA256/384/512
    • shake — Enables SHAKE128/256 and TurboSHAKE128/256
  • kat - Used only to enabled known-answer tests, which require std. Only use with cargo test

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

Feature Combinations

We list the additional functionality that certain feature combinations enable:

  • x25519,mlkem (default) — Enables the ML-KEM-768+X25519 (aka XWing) hybrid post-quantum KEM
  • nistp,mlkem — Enables the ML-KEM + NIST-P hybrid post-quantum KEMs

Usage Examples

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

Breaking Changes

All changes in the last few versions can be found in CHANGELOG.md. We highlight recent ones below. This crate adheres to Semantic Versioning for all modules except for danger. We reserve the right to break the danger API with patch version updates. So if you are using the danger API, pin hpke to the patch version, e.g., by specifying =0.14.0.

Important Breaking Changes in v0.14.0

  • Completely overhauled feature flags (see feature flags section above)
  • Switched all *_in_place algorithms to _inout, and replaced &mut [u8] with inout::InOut<'_, '_, u8>
  • Renamed every function that took an RNG to *_with_rng, and removed the rng parameter from the function with the original name (gated by getrandom)
  • Replaced generic-array with hybrid-array

Important Breaking Changes in v0.12

The serde_impls feature was removed. If you were using this and require backwards compatible serialization/deserialization, see the wiki page here.

MSRV

The current minimum supported Rust version (MSRV) is 1.85.0 (2025-02-20).

Tests

To run all tests, execute cargo test --all-features. This includes known-answer tests.

Classical (i.e., non-post-quantum) ciphersuites test against test-vectors/origrfc-COMMIT_ID.json,where COMMIT_ID is the short commit of the version of the spec that the test vectors came from. The finalized spec uses commit 5f503c5. See the reference implementation for information on how to generate a test vector.

Post-quantum ciphersuites (including hybrid), test against test-vectors/pq-COMMIT_ID.json in the same way. The commit ID refers to the reference implementation repo of the PQ extension standard.

Hybrid ciphersuites are additionally tested against test-vectors/hybrid-COMMIT_ID.json. The commit ID refers to the concrete hybrid HPKE spec repo.

Benchmarks

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:

  • Classical NIST Ciphersuite with 128-bit security: AES-GCM-128, HKDF-SHA256, ECDH-P256
  • Classical Non-NIST Ciphersuite with 128-bit security: ChaCha20-Poly1305, HKDF-SHA256, X25519
  • Pure-PQ NIST Ciphersuite with 128-bit security: AES-GCM-128, SHAKE128, MLKEM768
  • Pure-PQ NIST Ciphersuite with 256-bit security: AES-GCM-256, SHAKE256, MLKEM1024
  • Hybrid-PQ NIST Ciphersuite with 128-bit security: AES-GCM-128, SHAKE128, MLKEM768-P256
  • Hybrid-PQ NIST Ciphersuite with 256-bit security: AES-GCM-256, SHAKE256, MLKEM1024-P384
  • Hybrid-PQ Non-NIST Ciphersuite with 128-bit security: ChaCha20-Poly1305, TurboSHAKE128, XWing

Functions benchmarked in each ciphersuite:

  • Kem::gen_keypair
  • setup_sender with OpModes of Base, Auth, Psk, and AuthPsk (Auth* modes omitted if unsupported)
  • setup_receiver with OpModes of Base, Auth, Psk, and AuthPsk (Auth* modes omitted if unsupported)
  • AeadCtxS::seal with plaintext length 64 and AAD length 64
  • AeadCtxR::open with ciphertext length 64 and AAD length 64

Audit History

To the authors' knowledge, nobody has performed a paid audit of this crate. However, Cloudflare did a security review of version 0.8, saying:

The HPKE implementation we decided on comes with the caveat of not yet being formally audited, so we performed our own internal security review. We analyzed the cryptography primitives being used and the corresponding libraries. Between the composition of said primitives and secure programming practices like correctly zeroing memory and safe usage of random number generators, we found no security issues.

Runtime Ciphersuite Selection

This crate forces the user to decide at compile time which ciphersuite they wish to use. We do it this way for the sake of simplicity, and for the added static guarantees that you get when you use the type system.

If you do not know in advance which ciphersuites you will be using, e.g., for a protocol that does ciphersuite negotiation, then you should use the hpke-dispatch crate. This crates allows ciphersuite selection at runtime (this feature is sometimes known as "agility"). Purely for the sake of demonstration, we also have a sample implementation in the examples folder.

License

Licensed under either of

at your option.

About

An implementation of the HPKE hybrid encryption standard (RFC 9180)

Topics

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

97 stars

Watchers

3 watching

Forks

Contributors

Languages