feat: replace deprecated ExpandedKeyEncoding with seed serialization, derive ZeroizeOnDrop

- Add ZeroizeOnDrop bound to Hash trait
- Replace manual Drop impls on Ke2Builder and KemKe2Builder with derive_where
- Migrate KEM decapsulation key serialization from expanded form to 64-byte seed (KeyInit/KeyExport)
- Fix voprf deserialization to pass exact-length slices
- Bump voprf-vx to 1.0.0-rc.1
- Regenerate test vectors
This commit is contained in:
2026-07-03 09:53:22 +02:00
parent b9b8699ee7
commit f00e96c724
10 changed files with 191 additions and 4440 deletions
+3 -36
View File
@@ -14,7 +14,6 @@ use generic_array::typenum::{IsLess, Le, NonZero, Sum, U256};
use generic_array::{ArrayLength, GenericArray};
use rand::{CryptoRng, Rng};
use subtle::{ConstantTimeEq, CtOption};
use zeroize::{Zeroize, ZeroizeOnDrop};
use super::{
Deserialize, GenerateKe1Result, GenerateKe2Result, GenerateKe3Result, KeyExchange, Serialize,
@@ -69,7 +68,7 @@ pub struct Ke2State<H: OutputSizeUser> {
serialize = "H: serde::Serialize, PublicKey<G>: serde::Serialize",
))
)]
#[derive_where(Clone)]
#[derive_where(Clone, ZeroizeOnDrop)]
#[derive_where(Debug, Eq, Hash, PartialEq; H, PublicKey<G>)]
pub struct Ke2Builder<G: Group, H: Hash>
where
@@ -80,7 +79,9 @@ where
{
server_nonce: GenericArray<u8, NonceLen>,
transcript_hasher: H,
#[derive_where(skip(Zeroize))]
client_e_pk: PublicKey<G>,
#[derive_where(skip(Zeroize))]
server_e_pk: PublicKey<G>,
shared_secret_1: GenericArray<u8, G::PkLen>,
shared_secret_3: GenericArray<u8, G::PkLen>,
@@ -352,40 +353,6 @@ where
}
}
/// TODO: implement via derive after `Hash` gets `Zeroize` support.
impl<G: Group, H: Hash> Drop for Ke2Builder<G, H>
where
H::Core: ProxyHash,
<<H as CoreProxy>::Core as SmallBlockSizeUser>::_BlockSize: IsLess<U256>,
Le<<<H as CoreProxy>::Core as SmallBlockSizeUser>::_BlockSize, U256>: NonZero,
OutputSize<H>: ArrayLength,
{
fn drop(&mut self) {
let Self {
server_nonce,
transcript_hasher,
client_e_pk: _,
server_e_pk: _,
shared_secret_1,
shared_secret_3,
} = self;
server_nonce.zeroize();
digest::Reset::reset(transcript_hasher);
shared_secret_1.zeroize();
shared_secret_3.zeroize();
}
}
impl<G: Group, H: Hash> ZeroizeOnDrop for Ke2Builder<G, H>
where
H::Core: ProxyHash,
<<H as CoreProxy>::Core as SmallBlockSizeUser>::_BlockSize: IsLess<U256>,
Le<<<H as CoreProxy>::Core as SmallBlockSizeUser>::_BlockSize, U256>: NonZero,
OutputSize<H>: ArrayLength,
{
}
impl<G: Group, H: Hash> Deserialize for Ke2Message<G, H>
where
H::Core: ProxyHash,