Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 21 additions & 6 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,34 @@ fn bench_kem(c: &mut Criterion) {
})
});

let mut os = OsRng;
let (sk_r, pk_r) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
let mut os = OsRng;
let (_, enc) = DhKemX25519HkdfSha256::encap(&mut os.unwrap_mut(), &pk_r).unwrap();
g.bench_function("x25519/decap", |b| {
b.iter(|| DhKemX25519HkdfSha256::decap(black_box(&enc), &sk_r).unwrap())
});
}

{
let mut os = OsRng;
let (sk_s, _) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
let (_, pk_r) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
g.bench_function("x25519/auth_encap", |b| {
b.iter(|| {
let mut os = OsRng;
DhKemX25519HkdfSha256::auth_encap(&mut os.unwrap_mut(), black_box(&pk_r), &sk_s)
.unwrap()
})
});

let (sk_r, pk_r) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
let (sk_s, pk_s) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
let (_, enc) =
DhKemX25519HkdfSha256::auth_encap(&mut os.unwrap_mut(), &pk_r, &sk_s).unwrap();
g.bench_function("x25519/auth_decap", |b| {
b.iter(|| DhKemX25519HkdfSha256::auth_decap(black_box(&enc), &sk_r, &pk_s).unwrap())
});
}

g.bench_function("p256/generate", |b| {
b.iter(|| {
let mut os = OsRng;
Expand Down Expand Up @@ -81,7 +100,6 @@ fn bench_setup(c: &mut Criterion) {
});

{
let mut os = OsRng;
let (enc, _ctx) =
X25519Suite::setup_sender_base(&mut os.unwrap_mut(), &pk_r, b"info").unwrap();
g.bench_function("x25519_chacha/setup_receiver_base", |b| {
Expand Down Expand Up @@ -119,7 +137,6 @@ fn bench_seal_open(c: &mut Criterion) {
},
);

let mut os = OsRng;
let (enc, ct) =
X25519Suite::seal_base(&mut os.unwrap_mut(), &pk_r, b"info", b"aad", &pt).unwrap();
g.bench_with_input(
Expand All @@ -135,7 +152,6 @@ fn bench_seal_open(c: &mut Criterion) {
}

{
let mut os = OsRng;
let (_, mut sender) =
X25519Suite::setup_sender_base(&mut os.unwrap_mut(), &pk_r, b"info").unwrap();
for &size in &[64usize, 1024, 16384] {
Expand All @@ -156,7 +172,6 @@ fn bench_export(c: &mut Criterion) {
let mut g = c.benchmark_group("export");
let mut os = OsRng;
let (_sk_r, pk_r) = DhKemX25519HkdfSha256::generate(&mut os.unwrap_mut()).unwrap();
let mut os = OsRng;
let (_enc, ctx) = X25519Suite::setup_sender_base(&mut os.unwrap_mut(), &pk_r, b"info").unwrap();

for &len in &[32usize, 64, 128] {
Expand Down
48 changes: 31 additions & 17 deletions src/kem/dh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rand_core::{CryptoRng, RngCore};
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};

use crate::HpkeError;
use crate::kdf::{Kdf, labeled_expand, labeled_expand_pieces, labeled_extract};
use crate::kdf::{
Kdf, labeled_expand, labeled_expand_pieces, labeled_extract, labeled_extract_pieces,
};
use crate::kem::{AuthKem, Kem};
use crate::sealed::Sealed;

Expand Down Expand Up @@ -198,6 +200,26 @@ fn extract_and_expand<D: DiffieHellman, H: Kdf>(
)
}

fn extract_and_expand_pieces<D: DiffieHellman, H: Kdf>(
dh_pieces: &[&[u8]],
kem_context: &[&[u8]],
) -> Result<Vec<u8>, HpkeError> {
let suite = suite_id::<D>();
let eae_prk = Zeroizing::new(labeled_extract_pieces::<H>(
&[],
&suite,
b"eae_prk",
dh_pieces,
));
labeled_expand_pieces::<H>(
&eae_prk,
&suite,
b"shared_secret",
kem_context,
D::SHARED_SECRET_LEN,
)
}

/// RFC 9180 §7.1.3 `DeriveKeyPair` rejection-sampling loop for NIST P-curves
/// and secp256k1.
///
Expand Down Expand Up @@ -455,14 +477,9 @@ impl<D: DiffieHellman, H: Kdf> AuthKem for DhKem<D, H> {
let pk_e = D::pk_from_bytes(&enc.0)?;
let dh1 = Zeroizing::new(D::dh(&sk_r.sk, &pk_e)?);
let dh2 = Zeroizing::new(D::dh(&sk_r.sk, &pk_s.0)?);
let mut dh = Zeroizing::new(Vec::with_capacity(dh1.len() + dh2.len()));
dh.extend_from_slice(&dh1);
dh.extend_from_slice(&dh2);

// Cached `sk_r.pk_bytes` replaces a per-call base-point scalar mult.
let pk_sender = D::pk_to_bytes(&pk_s.0);
Ok(DhSharedSecret(extract_and_expand::<D, H>(
&dh,
Ok(DhSharedSecret(extract_and_expand_pieces::<D, H>(
&[&dh1, &dh2],
&[&enc.0, &sk_r.pk_bytes, &pk_sender],
)?))
}
Expand All @@ -482,11 +499,11 @@ fn encap_with<D: DiffieHellman, H: Kdf, R: CryptoRng + RngCore>(
None => extract_and_expand::<D, H>(&dh1, &[&enc, &pk_recipient])?,
Some(sk_s) => {
let dh2 = Zeroizing::new(D::dh(&sk_s.sk, &pk_r.0)?);
let mut dh = Zeroizing::new(Vec::with_capacity(dh1.len() + dh2.len()));
dh.extend_from_slice(&dh1);
dh.extend_from_slice(&dh2);
// Cached sender public-key bytes — no `sk_to_pk` round trip.
extract_and_expand::<D, H>(&dh, &[&enc, &pk_recipient, &sk_s.pk_bytes])?
extract_and_expand_pieces::<D, H>(
&[&dh1, &dh2],
&[&enc, &pk_recipient, &sk_s.pk_bytes],
)?
}
};

Expand Down Expand Up @@ -521,14 +538,11 @@ pub(crate) fn auth_encap_with_ikm<D: DiffieHellman, H: Kdf>(
let (sk_e, pk_e) = D::derive(ikm_e)?;
let dh1 = Zeroizing::new(D::dh(&sk_e, &pk_r.0)?);
let dh2 = Zeroizing::new(D::dh(&sk_s.sk, &pk_r.0)?);
let mut dh = Zeroizing::new(Vec::with_capacity(dh1.len() + dh2.len()));
dh.extend_from_slice(&dh1);
dh.extend_from_slice(&dh2);
let enc = D::pk_to_bytes(&pk_e);
let pk_recipient = D::pk_to_bytes(&pk_r.0);
Ok((
DhSharedSecret(extract_and_expand::<D, H>(
&dh,
DhSharedSecret(extract_and_expand_pieces::<D, H>(
&[&dh1, &dh2],
&[&enc, &pk_recipient, &sk_s.pk_bytes],
)?),
DhEncappedKey(enc),
Expand Down
Loading