Skip to content

Commit

Permalink
make newtypes for the different kinds of wrappers needed
Browse files Browse the repository at this point in the history
  • Loading branch information
incertia committed Apr 18, 2024
1 parent 614353f commit 5af0437
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 33 deletions.
34 changes: 17 additions & 17 deletions dhkem/src/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::{DhKem, DhKemProxy};
use elliptic_curve::ecdh::{EphemeralSecret, SharedSecret};
use crate::{Decapsulator, DhKem, EncapsulatedKey, Encapsulator, SharedSecret};
use elliptic_curve::ecdh::{EphemeralSecret, SharedSecret as EcdhSecret};
use elliptic_curve::{CurveArithmetic, PublicKey};
use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;
use std::marker::PhantomData;

pub struct ArithmeticKem<C: CurveArithmetic>(PhantomData<C>);

impl<C> Encapsulate<DhKemProxy<PublicKey<C>>, DhKemProxy<SharedSecret<C>>>
for DhKemProxy<PublicKey<C>>
impl<C> Encapsulate<EncapsulatedKey<PublicKey<C>>, SharedSecret<EcdhSecret<C>>>
for Encapsulator<PublicKey<C>>
where
C: CurveArithmetic,
{
Expand All @@ -17,54 +17,54 @@ where
fn encapsulate(
&self,
rng: &mut impl CryptoRngCore,
) -> Result<(DhKemProxy<PublicKey<C>>, DhKemProxy<SharedSecret<C>>), Self::Error> {
) -> Result<(EncapsulatedKey<PublicKey<C>>, SharedSecret<EcdhSecret<C>>), Self::Error> {
// ECDH encapsulation involves creating a new ephemeral key pair and then doing DH
let sk = EphemeralSecret::random(rng);
let pk = sk.public_key();
let ss = sk.diffie_hellman(&self.0);

Ok((DhKemProxy(pk), DhKemProxy(ss)))
Ok((EncapsulatedKey(pk), SharedSecret(ss)))
}
}

impl<C> Decapsulate<DhKemProxy<PublicKey<C>>, DhKemProxy<SharedSecret<C>>>
for DhKemProxy<EphemeralSecret<C>>
impl<C> Decapsulate<EncapsulatedKey<PublicKey<C>>, SharedSecret<EcdhSecret<C>>>
for Decapsulator<EphemeralSecret<C>>
where
C: CurveArithmetic,
{
type Error = ();

fn decapsulate(
&self,
encapsulated_key: &DhKemProxy<PublicKey<C>>,
) -> Result<DhKemProxy<SharedSecret<C>>, Self::Error> {
encapsulated_key: &EncapsulatedKey<PublicKey<C>>,
) -> Result<SharedSecret<EcdhSecret<C>>, Self::Error> {
let ss = self.0.diffie_hellman(&encapsulated_key.0);

Ok(DhKemProxy(ss))
Ok(SharedSecret(ss))
}
}

impl<C> DhKem for ArithmeticKem<C>
where
C: CurveArithmetic,
{
type DecapsulatingKey = DhKemProxy<EphemeralSecret<C>>;
type EncapsulatingKey = DhKemProxy<PublicKey<C>>;
type EncapsulatedKey = DhKemProxy<PublicKey<C>>;
type SharedSecret = DhKemProxy<SharedSecret<C>>;
type DecapsulatingKey = Decapsulator<EphemeralSecret<C>>;
type EncapsulatingKey = Encapsulator<PublicKey<C>>;
type EncapsulatedKey = EncapsulatedKey<PublicKey<C>>;
type SharedSecret = SharedSecret<EcdhSecret<C>>;

fn random_keypair(
rng: &mut impl CryptoRngCore,
) -> (Self::DecapsulatingKey, Self::EncapsulatingKey) {
let sk = EphemeralSecret::random(rng);
let pk = PublicKey::from(&sk);

(DhKemProxy(sk), DhKemProxy(pk))
(Decapsulator(sk), Encapsulator(pk))
}
}

#[cfg(test)]
impl<C> crate::SecretBytes for DhKemProxy<SharedSecret<C>>
impl<C> crate::SecretBytes for SharedSecret<EcdhSecret<C>>
where
C: CurveArithmetic,
{
Expand Down
9 changes: 8 additions & 1 deletion dhkem/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;

pub struct DhKemProxy<X>(X);
/// Newtype for a piece of data that may be encapsulated
pub struct Encapsulator<X>(X);
/// Newtype for a piece of data that may be decapsulated
pub struct Decapsulator<X>(X);
/// Newtype for a shared secret
pub struct SharedSecret<X>(X);
/// Newtype for an encapsulated key
pub struct EncapsulatedKey<X>(X);

#[cfg(test)]
pub trait SecretBytes {
Expand Down
34 changes: 19 additions & 15 deletions dhkem/src/x25519_kem.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,61 @@
use crate::{DhKem, DhKemProxy};
use crate::{Decapsulator, DhKem, EncapsulatedKey, Encapsulator, SharedSecret};
use kem::{Decapsulate, Encapsulate};
use rand_core::CryptoRngCore;
use x25519::{PublicKey, ReusableSecret, SharedSecret};
use x25519::{PublicKey, ReusableSecret, SharedSecret as X25519Secret};

pub struct X25519;

impl Encapsulate<DhKemProxy<PublicKey>, DhKemProxy<SharedSecret>> for DhKemProxy<PublicKey> {
impl Encapsulate<EncapsulatedKey<PublicKey>, SharedSecret<X25519Secret>>
for Encapsulator<PublicKey>
{
type Error = ();

fn encapsulate(
&self,
rng: &mut impl CryptoRngCore,
) -> Result<(DhKemProxy<PublicKey>, DhKemProxy<SharedSecret>), Self::Error> {
) -> Result<(EncapsulatedKey<PublicKey>, SharedSecret<X25519Secret>), Self::Error> {
// ECDH encapsulation involves creating a new ephemeral key pair and then doing DH
let sk = ReusableSecret::random_from_rng(rng);
let pk = PublicKey::from(&sk);
let ss = sk.diffie_hellman(&self.0);

Ok((DhKemProxy(pk), DhKemProxy(ss)))
Ok((EncapsulatedKey(pk), SharedSecret(ss)))
}
}

impl Decapsulate<DhKemProxy<PublicKey>, DhKemProxy<SharedSecret>> for DhKemProxy<ReusableSecret> {
impl Decapsulate<EncapsulatedKey<PublicKey>, SharedSecret<X25519Secret>>
for Decapsulator<ReusableSecret>
{
type Error = ();

fn decapsulate(
&self,
encapsulated_key: &DhKemProxy<PublicKey>,
) -> Result<DhKemProxy<SharedSecret>, Self::Error> {
encapsulated_key: &EncapsulatedKey<PublicKey>,
) -> Result<SharedSecret<X25519Secret>, Self::Error> {
let ss = self.0.diffie_hellman(&encapsulated_key.0);

Ok(DhKemProxy(ss))
Ok(SharedSecret(ss))
}
}

impl DhKem for X25519 {
type DecapsulatingKey = DhKemProxy<ReusableSecret>;
type EncapsulatingKey = DhKemProxy<PublicKey>;
type EncapsulatedKey = DhKemProxy<PublicKey>;
type SharedSecret = DhKemProxy<SharedSecret>;
type DecapsulatingKey = Decapsulator<ReusableSecret>;
type EncapsulatingKey = Encapsulator<PublicKey>;
type EncapsulatedKey = EncapsulatedKey<PublicKey>;
type SharedSecret = SharedSecret<X25519Secret>;

fn random_keypair(
rng: &mut impl CryptoRngCore,
) -> (Self::DecapsulatingKey, Self::EncapsulatingKey) {
let sk = ReusableSecret::random_from_rng(rng);
let pk = PublicKey::from(&sk);

(DhKemProxy(sk), DhKemProxy(pk))
(Decapsulator(sk), Encapsulator(pk))
}
}

#[cfg(test)]
impl crate::SecretBytes for DhKemProxy<SharedSecret> {
impl crate::SecretBytes for SharedSecret<X25519Secret> {
fn as_slice(&self) -> &[u8] {
self.0.as_bytes().as_slice()
}
Expand Down

0 comments on commit 5af0437

Please sign in to comment.