1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7)]
8
9mod expander;
33
34pub use expander::{Expander, InvalidLength};
35pub use kem::{self, Decapsulator, Encapsulate, Generate, Kem, TryDecapsulate};
36
37#[cfg(feature = "ecdh")]
38mod ecdh_kem;
39#[cfg(feature = "x25519")]
40mod x25519_kem;
41
42#[cfg(feature = "ecdh")]
43pub use ecdh_kem::{EcdhDecapsulationKey, EcdhEncapsulationKey, EcdhKem};
44#[cfg(feature = "x25519")]
45pub use x25519_kem::{X25519DecapsulationKey, X25519EncapsulationKey, X25519Kem};
46
47#[cfg(feature = "ecdh")]
48use elliptic_curve::{
49 CurveArithmetic, PublicKey, bigint,
50 sec1::{self, FromSec1Point, ToSec1Point},
51};
52
53#[cfg(feature = "zeroize")]
54use zeroize::{Zeroize, ZeroizeOnDrop};
55
56#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
58pub struct DecapsulationKey<DK, EK> {
59 dk: DK,
61 ek: EncapsulationKey<EK>,
63}
64
65impl<DK, EK> DecapsulationKey<DK, EK> {
66 pub fn into_inner(self) -> DK {
68 self.dk
69 }
70}
71
72impl<DK, EK> AsRef<EncapsulationKey<EK>> for DecapsulationKey<DK, EK> {
73 fn as_ref(&self) -> &EncapsulationKey<EK> {
74 &self.ek
75 }
76}
77
78impl<DK, EK> From<DK> for DecapsulationKey<DK, EK>
79where
80 EK: for<'a> From<&'a DK>,
81{
82 fn from(dk: DK) -> Self {
83 let ek = EncapsulationKey(EK::from(&dk));
84 Self { dk, ek }
85 }
86}
87
88#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
90pub struct EncapsulationKey<EK>(EK);
91
92impl<EK> EncapsulationKey<EK> {
93 pub fn into_inner(self) -> EK {
95 self.0
96 }
97}
98
99impl<EK> From<EK> for EncapsulationKey<EK> {
100 fn from(inner: EK) -> Self {
101 Self(inner)
102 }
103}
104
105#[cfg(feature = "ecdh")]
106impl<C> FromSec1Point<C> for EcdhEncapsulationKey<C>
107where
108 C: CurveArithmetic,
109 C::FieldBytesSize: sec1::ModulusSize,
110 PublicKey<C>: FromSec1Point<C>,
111{
112 fn from_sec1_point(point: &sec1::Sec1Point<C>) -> bigint::CtOption<Self> {
113 PublicKey::<C>::from_sec1_point(point).map(Into::into)
114 }
115}
116
117#[cfg(feature = "ecdh")]
118impl<C> ToSec1Point<C> for EcdhEncapsulationKey<C>
119where
120 C: CurveArithmetic,
121 C::FieldBytesSize: sec1::ModulusSize,
122 PublicKey<C>: ToSec1Point<C>,
123{
124 fn to_sec1_point(&self, compress: bool) -> sec1::Sec1Point<C> {
125 self.0.to_sec1_point(compress)
126 }
127}
128
129#[cfg(feature = "zeroize")]
130impl<DK: Zeroize, EK> Zeroize for DecapsulationKey<DK, EK> {
131 fn zeroize(&mut self) {
132 self.dk.zeroize();
133 }
134}
135
136#[cfg(feature = "zeroize")]
137impl<DK: ZeroizeOnDrop, EK> ZeroizeOnDrop for DecapsulationKey<DK, EK> {}
138
139#[cfg(feature = "p256")]
141pub type NistP256Kem = EcdhKem<p256::NistP256>;
142#[cfg(feature = "p256")]
144pub type NistP256DecapsulationKey = EcdhDecapsulationKey<p256::NistP256>;
145#[cfg(feature = "p256")]
147pub type NistP256EncapsulationKey = EcdhEncapsulationKey<p256::NistP256>;
148
149#[cfg(feature = "p384")]
151pub type NistP384Kem = EcdhKem<p384::NistP384>;
152#[cfg(feature = "p384")]
154pub type NistP384DecapsulationKey = EcdhDecapsulationKey<p384::NistP384>;
155#[cfg(feature = "p384")]
157pub type NistP384EncapsulationKey = EcdhEncapsulationKey<p384::NistP384>;
158
159#[cfg(feature = "p521")]
161pub type NistP521Kem = EcdhKem<p521::NistP521>;
162#[cfg(feature = "p521")]
164pub type NistP521DecapsulationKey = EcdhDecapsulationKey<p521::NistP521>;
165#[cfg(feature = "p521")]
167pub type NistP521EncapsulationKey = EcdhEncapsulationKey<p521::NistP521>;
168
169#[cfg(feature = "p521")]
171pub type Secp256k1Kem = EcdhKem<k256::Secp256k1>;
172#[cfg(feature = "k256")]
174pub type Secp256k1DecapsulationKey = EcdhDecapsulationKey<k256::Secp256k1>;
175#[cfg(feature = "k256")]
177pub type Secp256k1EncapsulationKey = EcdhEncapsulationKey<k256::Secp256k1>;