1use subtle::ConstantTimeEq;
7use thiserror::Error;
8use zeroize::{Zeroize, ZeroizeOnDrop};
9
10#[derive(Debug, Error)]
12pub enum KEMError {
13 #[error("Key generation failed")]
14 KeyGenerationError,
15 #[error("Encapsulation failed")]
16 EncapsulationError,
17 #[error("Decapsulation failed")]
18 DecapsulationError,
19 #[error("Invalid length")]
20 InvalidLength,
21 #[error("Invalid key format")]
22 InvalidKey,
23 #[error("Internal error")]
24 InternalError,
25}
26
27#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
29pub struct PublicKey(Vec<u8>);
30
31impl PublicKey {
32 pub fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError> {
33 Ok(Self(bytes.to_vec()))
34 }
35
36 pub fn as_bytes(&self) -> &[u8] {
37 &self.0
38 }
39}
40
41impl AsRef<[u8]> for PublicKey {
42 fn as_ref(&self) -> &[u8] {
43 &self.0
44 }
45}
46
47impl PartialEq for PublicKey {
48 fn eq(&self, other: &Self) -> bool {
49 self.0.ct_eq(&other.0).into()
50 }
51}
52
53impl Eq for PublicKey {}
54
55#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
57pub struct SecretKey(Vec<u8>);
58
59impl SecretKey {
60 pub fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError> {
61 Ok(Self(bytes.to_vec()))
62 }
63
64 pub fn as_bytes(&self) -> &[u8] {
65 &self.0
66 }
67}
68
69impl AsRef<[u8]> for SecretKey {
70 fn as_ref(&self) -> &[u8] {
71 &self.0
72 }
73}
74
75impl PartialEq for SecretKey {
76 fn eq(&self, other: &Self) -> bool {
77 self.0.ct_eq(&other.0).into()
78 }
79}
80
81impl Eq for SecretKey {}
82
83#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
85pub struct Ciphertext(Vec<u8>);
86
87impl Ciphertext {
88 pub fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError> {
89 Ok(Self(bytes.to_vec()))
90 }
91
92 pub fn as_bytes(&self) -> &[u8] {
93 &self.0
94 }
95}
96
97impl AsRef<[u8]> for Ciphertext {
98 fn as_ref(&self) -> &[u8] {
99 &self.0
100 }
101}
102
103impl PartialEq for Ciphertext {
104 fn eq(&self, other: &Self) -> bool {
105 self.0.ct_eq(&other.0).into()
106 }
107}
108
109impl Eq for Ciphertext {}
110
111#[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)]
113pub struct SharedSecret(Vec<u8>);
114
115impl SharedSecret {
116 pub fn from_bytes(bytes: &[u8]) -> Result<Self, KEMError> {
117 Ok(Self(bytes.to_vec()))
118 }
119
120 pub fn as_bytes(&self) -> &[u8] {
121 &self.0
122 }
123}
124
125impl AsRef<[u8]> for SharedSecret {
126 fn as_ref(&self) -> &[u8] {
127 &self.0
128 }
129}
130
131impl PartialEq for SharedSecret {
132 fn eq(&self, other: &Self) -> bool {
133 self.0.ct_eq(&other.0).into()
134 }
135}
136
137impl Eq for SharedSecret {}
138
139pub trait KeyEncapsulation {
141 fn keygen() -> Result<(PublicKey, SecretKey), KEMError>;
143
144 fn encapsulate(public_key: &PublicKey) -> Result<(Ciphertext, SharedSecret), KEMError>;
146
147 fn decapsulate(
149 secret_key: &SecretKey,
150 ciphertext: &Ciphertext,
151 ) -> Result<SharedSecret, KEMError>;
152}
153
154#[derive(Debug, ZeroizeOnDrop)]
156pub struct KeyPair {
157 pub public_key: Vec<u8>,
158 pub secret_key: Vec<u8>,
159}
160
161impl Default for KeyPair {
162 fn default() -> Self {
163 Self::new()
164 }
165}
166
167impl KeyPair {
168 pub fn new() -> Self {
170 Self {
171 public_key: vec![0u8; 32], secret_key: vec![0u8; 32], }
174 }
175
176 pub fn public_key(&self) -> &[u8] {
178 &self.public_key
179 }
180
181 pub fn secret_key(&self) -> &[u8] {
183 &self.secret_key
184 }
185}