Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [0.14.0-pre.2] — 2026-02-25
## [0.14.0] — 2026-07-XX

### Changes

* 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`)
* Feature-gated AES-GCM and ChaCha20Poly1305 behind `aes` and `chacha` features, respectively
* Added zeroizing for more intermediate secrets, and improved no-std support

### Additions

* Implemented the X-Wing (aka MLKEM768-X25519) hybrid post-quantum KEM, gated by the `xwing` feature
* Added `streaming_enc` module for creating streaming encryption contexts, gated by the `hazmat-streaming-enc` feature
### Breaking Changes

## [0.14.0-pre.1] — 2025-11-24
* Bumped MSRV to 1.85.0 (2025-02-20)
* Updated `rand` and `rand_core`
* 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`) ([#97](https://github.com/rozbb/rust-hpke/pull/97))
* Feature-gated AES-GCM and ChaCha20Poly1305 behind `aes` and `chacha` features, respectively ([#91](https://github.com/rozbb/rust-hpke/pull/91))
* Consolidated feature flags ([#106](https://github.com/rozbb/rust-hpke/pull/106))
* Replaced `generic-array` with `hybrid-array` ([#82](https://github.com/rozbb/rust-hpke/pull/82))
* Switched all `_in_place` algorithms to `_inout`, and replaced `&mut [u8]` with `inout::InOut<'_, '_, u8>` ([#82](https://github.com/rozbb/rust-hpke/pull/82))
* Updated RustCrypto crates `aead`, `aes-gcm`, `chacha20poly1305`, `digest`, `hkdf`, `hmac`

### Changes
### Other Changes

* Updated RustCrypto crates `aead`, `aes-gcm`, `chacha20poly1305`, `digest`, `hkdf`, `hmac`
* Updated `rand` and `rand_core`
* Replaced `generic-array` with `hybrid-array`
* Switched all `_in_place` algorithms to `_inout`, and replace `&mut [u8]` with `inout::InOut<'_, '_, u8>`
* Bumped MSRV to 1.85.0 (2025-02-20)
* Added XWing KEM and SHAKE KDFs ([#81](https://github.com/rozbb/rust-hpke/pull/81))
* Added MLKEM-NISP KEMs ([#105](https://github.com/rozbb/rust-hpke/pull/105))
* Added pure-MLKEM KEMs and TurboSHAKE KDF ([#105](https://github.com/rozbb/rust-hpke/pull/105))
* Added `danger::streaming_enc` module for creating streaming encryption contexts
[#107](https://github.com/rozbb/rust-hpke/pull/107)
* Added zeroizing for more intermediate secrets ([#92](https://github.com/rozbb/rust-hpke/pull/92))
* Fixed `no_std` support([#96](https://github.com/rozbb/rust-hpke/pull/96))

## [0.13.0] - 2025-02-19

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ repository = "https://github.com/rozbb/rust-hpke"
documentation = "https://docs.rs/hpke"
description = "An implementation of the HPKE hybrid encryption standard (RFC 9180) in pure Rust"
readme = "README.md"
version = "0.14.0-pre.2"
version = "0.14.0"
authors = ["Michael Rosenberg <michael@mrosenberg.pub>"]
edition = "2021"
edition = "2024"
license = "MIT/Apache-2.0"
keywords = ["cryptography", "crypto", "key-exchange", "encryption", "aead"]
categories = ["cryptography", "no-std"]
Expand Down
18 changes: 5 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,14 @@ See the [client-server](examples/client_server.rs) example for an idea of how to
Breaking changes
----------------

## Breaking changes in v0.14.0-pre.2
This crate adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for all modules except for `danger`. We reserve the right to break the `danger` API with patch version updates. All changes in the last few versions can be found in [CHANGELOG.md](CHANGELOG.md). We highlight recent ones below.
Comment thread
rozbb marked this conversation as resolved.
Outdated

* 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`)
* Feature-gated AES-GCM and ChaCha20Poly1305 behind `aes` and `chacha` features, respectively

## Breaking changes in v0.14.0-pre.1
## Important Breaking in v0.14.0

* Updated `rand` and `rand_core` dependencies
* 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`
* Renamed all `_in_place` symmetric encryption/decryption algorithms to `_inout`. Also replaced `&mut [u8]` inputs in these functions with `inout::InOut<'_, '_, u8>`.
* Bumped MSRV to 1.85.0 (2025-02-20)

### Breaking changes in v0.13

* `PskBundle` now has a constructor that validates that the inputs are either both empty or nonempty.
* `rand_core` was updated to v0.9

### Breaking changes in v0.12

Expand Down
5 changes: 3 additions & 2 deletions benches/benches.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use hpke::{
OpModeR, OpModeS, PskBundle,
aead::{Aead as AeadTrait, AeadCtxR, AeadTag},
inout::InOutBuf,
kdf::Kdf as KdfTrait,
kem::Kem as KemTrait,
setup_receiver, setup_sender, OpModeR, OpModeS, PskBundle,
setup_receiver, setup_sender,
};

use criterion::{criterion_main, Criterion};
use criterion::{Criterion, criterion_main};
use rand::random;
use rand_core::Rng;
use std::time::Instant;
Expand Down
8 changes: 4 additions & 4 deletions examples/agility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
//! of runtime checks.

use hpke::{
Deserializable, HpkeError, OpModeR, OpModeS, PskBundle, Serializable,
aead::{Aead, AeadCtxR, AeadCtxS, AeadTag, AesGcm128, AesGcm256, ChaCha20Poly1305},
inout::InOutBuf,
kdf::{
HkdfSha256, HkdfSha384, HkdfSha512, Kdf as KdfTrait, KdfShake128, KdfShake256,
KdfTurboShake128, KdfTurboShake256,
},
kem::{
DhP256HkdfSha256, DhP384HkdfSha384, DhP521HkdfSha512, Kem as KemTrait, MlKem1024,
MlKem1024P384, MlKem768, MlKem768P256, X25519HkdfSha256, XWing,
DhP256HkdfSha256, DhP384HkdfSha384, DhP521HkdfSha512, Kem as KemTrait, MlKem768,
MlKem768P256, MlKem1024, MlKem1024P384, X25519HkdfSha256, XWing,
},
setup_receiver, setup_sender, Deserializable, HpkeError, OpModeR, OpModeS, PskBundle,
Serializable,
setup_receiver, setup_sender,
};

trait AgileAeadCtxS {
Expand Down
2 changes: 1 addition & 1 deletion examples/client_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
// the user of this library to do the appropriate thing when a function returns an error.

use hpke::{
Deserializable, Kem as KemTrait, OpModeR, OpModeS, Serializable,
aead::{AeadTag, ChaCha20Poly1305},
inout::InOutBuf,
kdf::KdfTurboShake128,
kem::XWing,
Deserializable, Kem as KemTrait, OpModeR, OpModeS, Serializable,
};

const INFO_STR: &[u8] = b"example session";
Expand Down
8 changes: 4 additions & 4 deletions src/aead.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
//! Traits and structs for authenticated encryption schemes

use crate::{
Deserializable, HpkeError, Serializable,
kdf::Kdf as KdfTrait,
kem::Kem as KemTrait,
setup::ExporterSecret,
util::{enforce_equal_len, enforce_outbuf_len, full_suite_id, write_u64_be, FullSuiteId},
Deserializable, HpkeError, Serializable,
util::{FullSuiteId, enforce_equal_len, enforce_outbuf_len, full_suite_id, write_u64_be},
};

use core::{default::Default, marker::PhantomData};

use aead::{
inout::InOutBuf, AeadCore as BaseAeadCore, AeadInOut as BaseAeadInOut, KeyInit as BaseKeyInit,
AeadCore as BaseAeadCore, AeadInOut as BaseAeadInOut, KeyInit as BaseKeyInit, inout::InOutBuf,
};
use hybrid_array::Array;
use zeroize::{Zeroize, ZeroizeOnDrop};
Expand Down Expand Up @@ -492,7 +492,7 @@ mod test {
#[cfg(feature = "chacha")]
use super::ChaCha20Poly1305;

use crate::{test_util::gen_ctx_simple_pair, Deserializable, HpkeError, Serializable};
use crate::{Deserializable, HpkeError, Serializable, test_util::gen_ctx_simple_pair};

use hybrid_array::typenum::Unsigned;

Expand Down
4 changes: 2 additions & 2 deletions src/aead/export_only.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::aead::Aead;

use aead::{
inout::InOutBuf, AeadCore as BaseAeadCore, AeadInOut as BaseAeadInOut, KeyInit as BaseKeyInit,
KeySizeUser as BaseKeySizeUser, TagPosition,
AeadCore as BaseAeadCore, AeadInOut as BaseAeadInOut, KeyInit as BaseKeyInit,
KeySizeUser as BaseKeySizeUser, TagPosition, inout::InOutBuf,
};
use hybrid_array::typenum;

Expand Down
4 changes: 2 additions & 2 deletions src/danger/streaming_enc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
//! ```

use crate::{
Kem as KemTrait,
aead::{Aead, AeadCtx, AeadCtxR, AeadCtxS},
kdf::Kdf as KdfTrait,
Kem as KemTrait,
};

#[doc(inline)]
Expand Down Expand Up @@ -114,7 +114,7 @@ pub fn create_receiver_context<A: Aead, Kdf: KdfTrait, Kem: KemTrait>(
#[cfg(all(test, feature = "alloc"))]
mod test {
use super::{
create_receiver_context, create_sender_context, AeadKey, AeadNonce, ExporterSecret,
AeadKey, AeadNonce, ExporterSecret, create_receiver_context, create_sender_context,
};
use rand_core::Rng;

Expand Down
2 changes: 1 addition & 1 deletion src/dhkex.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{kdf::Kdf as KdfTrait, util::KemSuiteId, Deserializable, Serializable};
use crate::{Deserializable, Serializable, kdf::Kdf as KdfTrait, util::KemSuiteId};

use core::fmt::Debug;

Expand Down
2 changes: 1 addition & 1 deletion src/dhkex/ecdh_nistp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ nistp_dhkex!(
#[cfg(test)]
mod tests {
use crate::{
dhkex::DhKeyExchange, test_util::dhkex_gen_keypair_with_rng, Deserializable, Serializable,
Deserializable, Serializable, dhkex::DhKeyExchange, test_util::dhkex_gen_keypair_with_rng,
};

use super::p256::DhP256;
Expand Down
6 changes: 3 additions & 3 deletions src/dhkex/x25519.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
Deserializable, HpkeError, Serializable,
dhkex::{DhError, DhKeyExchange},
kdf::Kdf as KdfTrait,
util::{enforce_equal_len, enforce_outbuf_len, KemSuiteId},
Deserializable, HpkeError, Serializable,
util::{KemSuiteId, enforce_equal_len, enforce_outbuf_len},
};

use hybrid_array::typenum::{self, Unsigned};
Expand Down Expand Up @@ -168,7 +168,7 @@ impl DhKeyExchange for X25519 {
#[cfg(test)]
mod tests {
use crate::{
dhkex::{x25519::X25519, Deserializable, DhKeyExchange, Serializable},
dhkex::{Deserializable, DhKeyExchange, Serializable, x25519::X25519},
test_util::dhkex_gen_keypair_with_rng,
};
use hybrid_array::typenum::Unsigned;
Expand Down
8 changes: 4 additions & 4 deletions src/kat_tests.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use crate::{
Deserializable, HpkeError, Serializable,
aead::{Aead, AesGcm128, AesGcm256, ChaCha20Poly1305, ExportOnlyAead},
kdf::{
HkdfSha256, HkdfSha384, HkdfSha512, Kdf as KdfTrait, KdfShake128, KdfShake256,
KdfTurboShake128, KdfTurboShake256,
},
kem::{
DhP256HkdfSha256, DhP384HkdfSha384, DhP521HkdfSha512, Kem as KemTrait, MlKem1024,
MlKem1024P384, MlKem768, MlKem768P256, SharedSecret, X25519HkdfSha256, XWing,
DhP256HkdfSha256, DhP384HkdfSha384, DhP521HkdfSha512, Kem as KemTrait, MlKem768,
MlKem768P256, MlKem1024, MlKem1024P384, SharedSecret, X25519HkdfSha256, XWing,
},
op_mode::{OpModeR, PskBundle},
setup::setup_receiver,
Deserializable, HpkeError, Serializable,
};

use std::{fs::File, string::String, vec::Vec};

use ml_kem::KeyExport;
use serde::{de::Error as SError, Deserialize, Deserializer};
use serde::{Deserialize, Deserializer, de::Error as SError};

// For known-answer tests we need to be able to encap with fixed randomness. This allows that.
pub(crate) trait TestableKem: KemTrait {
Expand Down
4 changes: 2 additions & 2 deletions src/kdf.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! Traits and structs for key derivation functions

use crate::{
HpkeError,
aead::{Aead, AeadCtx},
kem::{Kem as KemTrait, SharedSecret},
op_mode::OpMode,
util::KemSuiteId,
HpkeError,
};

use hybrid_array::{
typenum::{U32, U64},
Array, ArraySize,
typenum::{U32, U64},
};
#[cfg(feature = "hkdfsha2")]
use sha2::{Sha256, Sha384, Sha512};
Expand Down
4 changes: 2 additions & 2 deletions src/kdf/one_stage_kdf.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! Helper functions for one-stage KDFs

use crate::{
HpkeError,
aead::{Aead, AeadCtx},
kdf::{KdfTrait, VERSION_LABEL},
kem::{Kem as KemTrait, SharedSecret},
op_mode::OpMode,
setup::ExporterSecret,
util::{full_suite_id, write_u16_be, KemSuiteId},
HpkeError,
util::{KemSuiteId, full_suite_id, write_u16_be},
};

use hybrid_array::{Array, ArraySize};
Expand Down
6 changes: 3 additions & 3 deletions src/kdf/two_stage_kdf.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
//! Helper functions for two-stage KDFs

use crate::{
HpkeError,
aead::{Aead, AeadCtx},
kdf::{KdfTrait, MAX_DIGEST_SIZE, VERSION_LABEL},
kem::{Kem as KemTrait, SharedSecret},
op_mode::OpMode,
setup::ExporterSecret,
util::{full_suite_id, write_u16_be, KemSuiteId},
HpkeError,
util::{KemSuiteId, full_suite_id, write_u16_be},
};

use hkdf::{hmac::EagerHash, Hkdf, HkdfExtract};
use hkdf::{Hkdf, HkdfExtract, hmac::EagerHash};
use hybrid_array::{Array, ArraySize};
use sha2::digest::{Digest, OutputSizeUser};

Expand Down
10 changes: 5 additions & 5 deletions src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ pub use dhkem::*;
#[cfg(all(feature = "mlkem", feature = "nistp"))]
mod mlkem_nistp;
#[cfg(all(feature = "mlkem", feature = "nistp"))]
pub use mlkem_nistp::mlkem1024p384::MlKem1024P384;
#[cfg(all(feature = "mlkem", feature = "nistp"))]
pub use mlkem_nistp::mlkem768p256::MlKem768P256;
#[cfg(all(feature = "mlkem", feature = "nistp"))]
pub use mlkem_nistp::mlkem1024p384::MlKem1024P384;
#[cfg(feature = "mlkem")]
pub(crate) mod mlkem;
#[cfg(feature = "mlkem")]
pub use mlkem::mlkem1024::MlKem1024;
#[cfg(feature = "mlkem")]
pub use mlkem::mlkem768::MlKem768;
#[cfg(feature = "mlkem")]
pub use mlkem::mlkem1024::MlKem1024;
#[cfg(all(feature = "mlkem", feature = "x25519"))]
pub(crate) mod xwing;
#[cfg(all(feature = "mlkem", feature = "x25519"))]
Expand Down Expand Up @@ -180,7 +180,7 @@ impl<Kem: KemTrait> Drop for SharedSecret<Kem> {

#[cfg(test)]
mod tests {
use crate::{kem::Kem as KemTrait, Deserializable, Serializable};
use crate::{Deserializable, Serializable, kem::Kem as KemTrait};

macro_rules! test_encap_correctness {
($test_name:ident, $kem_ty:ty, $use_auth:literal) => {
Expand Down
2 changes: 1 addition & 1 deletion src/kem/mlkem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ define_mlkem!(

#[cfg(test)]
mod tests {
use super::mlkem1024::MlKem1024;
use super::mlkem768::MlKem768;
use super::mlkem1024::MlKem1024;
use crate::{Deserializable, Kem as KemTrait, Serializable};

macro_rules! test_encap_correctness {
Expand Down
6 changes: 3 additions & 3 deletions src/kem/xwing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
//! <https://datatracker.ietf.org/doc/html/draft-ietf-hpke-pq-03>

use crate::{
Deserializable, HpkeError, Serializable,
kdf::one_stage_kdf::labeled_derive,
kem::{KemTrait, SharedSecret},
util::{enforce_equal_len, enforce_outbuf_len, kem_suite_id},
Deserializable, HpkeError, Serializable,
};

use hybrid_array::typenum::{Prod, Sum, Unsigned, U1024, U3, U32, U64};
use hybrid_array::typenum::{Prod, Sum, U3, U32, U64, U1024, Unsigned};
use rand_core::CryptoRng;
use shake::Shake256;
use subtle::{Choice, ConstantTimeEq};
use x_wing::{kem::Decapsulate, Decapsulator, KeyExport, TryKeyInit};
use x_wing::{Decapsulator, KeyExport, TryKeyInit, kem::Decapsulate};
use zeroize::Zeroize;

// Type-level size constants for X-Wing
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub use single_shot::{single_shot_open, single_shot_seal_with_rng};

//-------- Top-level types --------//

use hybrid_array::{typenum::marker_traits::Unsigned, Array, ArraySize};
use hybrid_array::{Array, ArraySize, typenum::marker_traits::Unsigned};

/// Describes things that can go wrong in the HPKE protocol
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down
Loading
Loading