use alloc::vec::Vec;
use rand_core::{CryptoRng, RngCore};
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
use crate::HpkeError;
use crate::sealed::Sealed;
pub mod dh;
#[cfg(feature = "pq")]
pub mod pq;
pub trait Kem: Sealed {
const ID: u16;
const ENCAPPED_KEY_LEN: usize;
const PUBLIC_KEY_LEN: usize;
const PRIVATE_KEY_LEN: usize;
const SHARED_SECRET_LEN: usize;
type PublicKey: AsRef<[u8]> + Clone;
type PrivateKey: Zeroize + ZeroizeOnDrop;
type EncappedKey: AsRef<[u8]> + Clone;
type SharedSecret: AsRef<[u8]> + Zeroize;
fn generate<R: CryptoRng + RngCore>(
rng: &mut R,
) -> Result<(Self::PrivateKey, Self::PublicKey), HpkeError>;
fn derive_key_pair(ikm: &[u8]) -> Result<(Self::PrivateKey, Self::PublicKey), HpkeError>;
fn encap<R: CryptoRng + RngCore>(
rng: &mut R,
pk_r: &Self::PublicKey,
) -> Result<(Self::SharedSecret, Self::EncappedKey), HpkeError>;
fn decap(
enc: &Self::EncappedKey,
sk_r: &Self::PrivateKey,
) -> Result<Self::SharedSecret, HpkeError>;
fn pk_from_bytes(b: &[u8]) -> Result<Self::PublicKey, HpkeError>;
fn sk_from_bytes(b: &[u8]) -> Result<Self::PrivateKey, HpkeError>;
fn enc_from_bytes(b: &[u8]) -> Result<Self::EncappedKey, HpkeError>;
fn pk_to_bytes(pk: &Self::PublicKey) -> Vec<u8>;
fn sk_to_bytes(sk: &Self::PrivateKey) -> Zeroizing<Vec<u8>>;
}
pub trait AuthKem: Kem {
fn auth_encap<R: CryptoRng + RngCore>(
rng: &mut R,
pk_r: &Self::PublicKey,
sk_s: &Self::PrivateKey,
) -> Result<(Self::SharedSecret, Self::EncappedKey), HpkeError>;
fn auth_decap(
enc: &Self::EncappedKey,
sk_r: &Self::PrivateKey,
pk_s: &Self::PublicKey,
) -> Result<Self::SharedSecret, HpkeError>;
}