ecdh-omr 0.2.0

ECDH based Oblivious Message Retrieval
Documentation
// SPDX-FileCopyrightText: 2024 eaon <eaon@posteo.net>
// SPDX-License-Identifier: EUPL-1.2

//! Shorthands for compatible elliptic curve implementations.

use rand_core::CryptoRngCore;

use crate::Decoy;

/// An elliptic curve key pair.
///
/// Creates a formal relationship between public and secret types.
pub trait KeyPair {
    /// An ECDH secret key.
    type SecretKey;
    /// An ECDH public key.
    type PublicKey;
}

pub(crate) mod sealed {
    use super::*;

    pub trait RandomSecretKey {
        fn random_secret_key(csprng: &mut impl CryptoRngCore) -> Self;
    }
}

#[cfg(feature = "dalek")]
mod x25519_dalek_aliases {
    use super::*;

    pub(crate) mod dalek {
        pub(crate) type PublicKey = x25519_dalek::PublicKey;
        pub(crate) type StaticSecret = x25519_dalek::StaticSecret;
    }

    /// Alias-ish type for X25519-dalek key pairs.
    #[derive(Debug, Clone)]
    pub struct X25519 {}

    impl KeyPair for X25519 {
        type SecretKey = dalek::StaticSecret;
        type PublicKey = dalek::PublicKey;
    }

    impl Decoy for dalek::PublicKey {
        fn random_decoy(csprng: &mut impl CryptoRngCore) -> Self {
            let mut bytes = [0u8; 32];
            csprng.fill_bytes(&mut bytes);

            dalek::PublicKey::from(bytes)
        }
    }

    impl sealed::RandomSecretKey for dalek::StaticSecret {
        fn random_secret_key(csprng: &mut impl CryptoRngCore) -> Self {
            dalek::StaticSecret::random_from_rng(csprng)
        }
    }
}

#[cfg(feature = "dalek")]
pub use x25519_dalek_aliases::*;

#[cfg(feature = "rustcrypto-ec")]
mod elliptic_curve_aliases {
    use super::*;

    use elliptic_curve::{point::NonIdentity, CurveArithmetic, ProjectivePoint};

    pub(crate) mod rcec {
        pub(crate) type PublicKey<C> = elliptic_curve::PublicKey<C>;
        pub(crate) type SecretKey<C> = elliptic_curve::SecretKey<C>;
    }

    /// Alias-ish type for key pairs of RustCrypto's curve-agnostic ECDH implementation.
    #[derive(Debug, Clone)]
    pub struct EllipticCurve<C> {
        marker: std::marker::PhantomData<C>,
    }

    impl<C: CurveArithmetic> KeyPair for EllipticCurve<C> {
        type SecretKey = rcec::SecretKey<C>;
        type PublicKey = rcec::PublicKey<C>;
    }

    impl<C: CurveArithmetic> Decoy for rcec::PublicKey<C> {
        fn random_decoy(csprng: &mut impl CryptoRngCore) -> Self {
            rcec::PublicKey::<C>::from(NonIdentity::<ProjectivePoint<C>>::random(&mut *csprng))
        }
    }

    impl<C: CurveArithmetic> sealed::RandomSecretKey for rcec::SecretKey<C> {
        fn random_secret_key(csprng: &mut impl CryptoRngCore) -> Self {
            rcec::SecretKey::<C>::random(csprng)
        }
    }
}

#[cfg(feature = "rustcrypto-ec")]
pub use elliptic_curve_aliases::*;