Add &self receiver to KEM trait methods

This commit is contained in:
Jan Winkelmann (keks)
2025-02-26 15:06:01 +01:00
parent d61b137761
commit 949a3e4d23
10 changed files with 44 additions and 24 deletions

View File

@@ -133,23 +133,31 @@ use thiserror::Error;
/// Key Encapsulation Mechanism
///
/// The KEM interface defines three operations: Key generation, key encapsulation and key
/// decapsulation.
/// decapsulation. The parameters are made available as associated constants for convenience.
pub trait Kem<const SK_LEN: usize, const PK_LEN: usize, const CT_LEN: usize, const SHK_LEN: usize> {
/// The length of the secret (decapsulation) key.
const SK_LEN: usize = SK_LEN;
/// The length of the public (encapsulation) key.
const PK_LEN: usize = PK_LEN;
/// The length of the ciphertext.
const CT_LEN: usize = CT_LEN;
/// The legnth of the resulting shared key.
const SHK_LEN: usize = SHK_LEN;
/// Generate a keypair consisting of secret key (`sk`) and public key (`pk`)
///
/// `keygen() -> sk, pk`
fn keygen(sk: &mut [u8; SK_LEN], pk: &mut [u8; PK_LEN]) -> Result<(), Error>;
fn keygen(&self, sk: &mut [u8; SK_LEN], pk: &mut [u8; PK_LEN]) -> Result<(), Error>;
/// From a public key (`pk`), generate a shared key (`shk`, for local use)
/// and a cipher text (`ct`, to be sent to the owner of the `pk`).
///
/// `encaps(pk) -> shk, ct`
fn encaps(
&self,
shk: &mut [u8; SHK_LEN],
ct: &mut [u8; CT_LEN],
pk: &[u8; PK_LEN],
@@ -159,7 +167,12 @@ pub trait Kem<const SK_LEN: usize, const PK_LEN: usize, const CT_LEN: usize, con
/// (`shk`)
///
/// `decaps(sk, ct) -> shk`
fn decaps(shk: &mut [u8; SHK_LEN], sk: &[u8; SK_LEN], ct: &[u8; CT_LEN]) -> Result<(), Error>;
fn decaps(
&self,
shk: &mut [u8; SHK_LEN],
sk: &[u8; SK_LEN],
ct: &[u8; CT_LEN],
) -> Result<(), Error>;
}
#[derive(Debug, Error)]

View File

@@ -16,5 +16,7 @@ fuzz_target!(|input: Input| {
let mut ciphertext = [0u8; EphemeralKem::CT_LEN];
let mut shared_secret = [0u8; EphemeralKem::SHK_LEN];
EphemeralKem::encaps(&mut shared_secret, &mut ciphertext, &input.pk).unwrap();
EphemeralKem
.encaps(&mut shared_secret, &mut ciphertext, &input.pk)
.unwrap();
});

View File

@@ -11,5 +11,5 @@ fuzz_target!(|input: [u8; StaticKem::PK_LEN]| {
let mut shared_secret = [0u8; StaticKem::SHK_LEN];
// We expect errors while fuzzing therefore we do not check the result.
let _ = StaticKem::encaps(&mut shared_secret, &mut ciphertext, &input);
let _ = StaticKem.encaps(&mut shared_secret, &mut ciphertext, &input);
});

View File

@@ -36,7 +36,7 @@ macro_rules! oqs_kem {
#[doc = "// Both parties end up with the same shared key"]
#[doc = "assert!(rosenpass_constant_time::compare(shk_enc.secret_mut(), shk_dec.secret_mut()) == 0);"]
#[doc = "```"]
pub enum [< $name:camel >] {}
pub struct [< $name:camel >];
pub const SK_LEN: usize = ::oqs_sys::kem::[<OQS_KEM _ $name:snake _ length_secret_key >] as usize;
pub const PK_LEN: usize = ::oqs_sys::kem::[<OQS_KEM _ $name:snake _ length_public_key >] as usize;
@@ -56,7 +56,7 @@ macro_rules! oqs_kem {
/// bigger. However, from a correctness point of view it does not make sense to
/// allow bigger buffers.
impl kem::Kem<SK_LEN, PK_LEN, CT_LEN, SHK_LEN> for [< $name:camel >] {
fn keygen(sk: &mut [u8; SK_LEN], pk: &mut [u8; PK_LEN]) -> Result<(), kem::Error> {
fn keygen(&self, sk: &mut [u8; SK_LEN], pk: &mut [u8; PK_LEN]) -> Result<(), kem::Error> {
unsafe {
oqs_call!(
::oqs_sys::kem::[< OQS_KEM _ $name:snake _ keypair >],
@@ -68,7 +68,7 @@ macro_rules! oqs_kem {
Ok(())
}
fn encaps(shk: &mut [u8; SHK_LEN], ct: &mut [u8; CT_LEN], pk: &[u8; PK_LEN]) -> Result<(), kem::Error> {
fn encaps(&self, shk: &mut [u8; SHK_LEN], ct: &mut [u8; CT_LEN], pk: &[u8; PK_LEN]) -> Result<(), kem::Error> {
unsafe {
oqs_call!(
::oqs_sys::kem::[< OQS_KEM _ $name:snake _ encaps >],
@@ -81,7 +81,7 @@ macro_rules! oqs_kem {
Ok(())
}
fn decaps(shk: &mut [u8; SHK_LEN], sk: &[u8; SK_LEN], ct: &[u8; CT_LEN]) -> Result<(), kem::Error> {
fn decaps(&self, shk: &mut [u8; SHK_LEN], sk: &[u8; SK_LEN], ct: &[u8; CT_LEN]) -> Result<(), kem::Error> {
unsafe {
oqs_call!(
::oqs_sys::kem::[< OQS_KEM _ $name:snake _ decaps >],
@@ -94,7 +94,12 @@ macro_rules! oqs_kem {
Ok(())
}
}
}
impl Default for [< $name:camel >] {
fn default() -> Self {
Self
}
}
pub use [< $name:snake >] :: [< $name:camel >];

View File

@@ -43,7 +43,7 @@ fn hs(ini: &mut CryptoServer, res: &mut CryptoServer) -> Result<()> {
fn keygen() -> Result<(SSk, SPk)> {
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem.keygen(sk.secret_mut(), pk.deref_mut())?;
Ok((sk, pk))
}

View File

@@ -609,7 +609,7 @@ impl CliArgs {
pub fn generate_and_save_keypair(secret_key: PathBuf, public_key: PathBuf) -> anyhow::Result<()> {
let mut ssk = crate::protocol::SSk::random();
let mut spk = crate::protocol::SPk::random();
StaticKem::keygen(ssk.secret_mut(), spk.deref_mut())?;
StaticKem.keygen(ssk.secret_mut(), spk.deref_mut())?;
ssk.store_secret(secret_key)?;
spk.store(public_key)
}

View File

@@ -3338,14 +3338,14 @@ impl HandshakeState {
const KEM_PK_LEN: usize,
const KEM_CT_LEN: usize,
const KEM_SHK_LEN: usize,
T: Kem<KEM_SK_LEN, KEM_PK_LEN, KEM_CT_LEN, KEM_SHK_LEN>,
T: Default + Kem<KEM_SK_LEN, KEM_PK_LEN, KEM_CT_LEN, KEM_SHK_LEN>,
>(
&mut self,
ct: &mut [u8; KEM_CT_LEN],
pk: &[u8; KEM_PK_LEN],
) -> Result<&mut Self> {
let mut shk = Secret::<KEM_SHK_LEN>::zero();
T::encaps(shk.secret_mut(), ct, pk)?;
T::default().encaps(shk.secret_mut(), ct, pk)?;
self.mix(pk)?.mix(shk.secret())?.mix(ct)
}
@@ -3374,7 +3374,7 @@ impl HandshakeState {
const KEM_PK_LEN: usize,
const KEM_CT_LEN: usize,
const KEM_SHK_LEN: usize,
T: Kem<KEM_SK_LEN, KEM_PK_LEN, KEM_CT_LEN, KEM_SHK_LEN>,
T: Default + Kem<KEM_SK_LEN, KEM_PK_LEN, KEM_CT_LEN, KEM_SHK_LEN>,
>(
&mut self,
sk: &[u8; KEM_SK_LEN],
@@ -3382,7 +3382,7 @@ impl HandshakeState {
ct: &[u8; KEM_CT_LEN],
) -> Result<&mut Self> {
let mut shk = Secret::<KEM_SHK_LEN>::zero();
T::decaps(shk.secret_mut(), sk, ct)?;
T::default().decaps(shk.secret_mut(), sk, ct)?;
self.mix(pk)?.mix(shk.secret())?.mix(ct)
}
@@ -3584,7 +3584,7 @@ impl CryptoServer {
ih.sidi.copy_from_slice(&hs.core.sidi.value);
// IHI3
EphemeralKem::keygen(hs.eski.secret_mut(), &mut *hs.epki)?;
EphemeralKem.keygen(hs.eski.secret_mut(), &mut *hs.epki)?;
ih.epki.copy_from_slice(&hs.epki.value);
// IHI4
@@ -4013,11 +4013,11 @@ pub mod testutils {
impl ServerForTesting {
pub fn new(protocol_version: ProtocolVersion) -> anyhow::Result<Self> {
let (mut sskm, mut spkm) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sskm.secret_mut(), spkm.deref_mut())?;
StaticKem.keygen(sskm.secret_mut(), spkm.deref_mut())?;
let mut srv = CryptoServer::new(sskm, spkm);
let (mut sskt, mut spkt) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sskt.secret_mut(), spkt.deref_mut())?;
StaticKem.keygen(sskt.secret_mut(), spkt.deref_mut())?;
let peer = srv.add_peer(None, spkt.clone(), protocol_version)?;
let peer_keys = (sskt, spkt);
@@ -4162,7 +4162,7 @@ mod test {
fn keygen() -> Result<(SSk, SPk)> {
// TODO: Copied from the benchmark; deduplicate
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem.keygen(sk.secret_mut(), pk.deref_mut())?;
Ok((sk, pk))
}
@@ -4530,7 +4530,7 @@ mod test {
fn keypair() -> Result<(SSk, SPk)> {
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem.keygen(sk.secret_mut(), pk.deref_mut())?;
Ok((sk, pk))
}

View File

@@ -114,7 +114,7 @@ struct TestServer {
impl TestServer {
fn new(termination_queue: mpsc::Receiver<()>) -> anyhow::Result<Self> {
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
StaticKem.keygen(sk.secret_mut(), pk.deref_mut())?;
let keypair = Some((sk, pk));
let addrs = vec![

View File

@@ -295,12 +295,12 @@ impl RosenpassSimulator {
fn new(protocol_version: ProtocolVersion) -> anyhow::Result<Self> {
// Set up the first server
let (mut peer_a_sk, mut peer_a_pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(peer_a_sk.secret_mut(), peer_a_pk.deref_mut())?;
StaticKem.keygen(peer_a_sk.secret_mut(), peer_a_pk.deref_mut())?;
let mut srv_a = CryptoServer::new(peer_a_sk, peer_a_pk.clone());
// …and the second server.
let (mut peer_b_sk, mut peer_b_pk) = (SSk::zero(), SPk::zero());
StaticKem::keygen(peer_b_sk.secret_mut(), peer_b_pk.deref_mut())?;
StaticKem.keygen(peer_b_sk.secret_mut(), peer_b_pk.deref_mut())?;
let mut srv_b = CryptoServer::new(peer_b_sk, peer_b_pk.clone());
// Generate a PSK and introduce the Peers to each other.

View File

@@ -66,7 +66,7 @@ pub fn genkey(private_keys_dir: &Path) -> Result<()> {
if !pqsk_path.exists() && !pqpk_path.exists() {
let mut pqsk = SSk::random();
let mut pqpk = SPk::random();
StaticKem::keygen(pqsk.secret_mut(), pqpk.deref_mut())?;
StaticKem.keygen(pqsk.secret_mut(), pqpk.deref_mut())?;
pqpk.store(pqpk_path)?;
pqsk.store_secret(pqsk_path)?;
} else {