1use libcrux_secrets::U8;
5
6use super::arrayref;
7
8pub trait Kem {
10 fn keygen(ek: &mut [u8], dk: &mut [U8], rand: &[U8]) -> Result<(), KeyGenError>;
14
15 fn encaps(ct: &mut [u8], ss: &mut [U8], ek: &[u8], rand: &[U8]) -> Result<(), EncapsError>;
19
20 fn decaps(ss: &mut [U8], ct: &[u8], dk: &[U8]) -> Result<(), DecapsError>;
22}
23
24#[derive(Debug)]
26pub enum KeyGenError {
27 InvalidRandomness,
29 InvalidRandomnessLength,
31 InvalidEncapsKeyLength,
33 InvalidDecapsKeyLength,
35 Unknown,
37}
38
39#[derive(Debug)]
41pub enum EncapsError {
42 InvalidEncapsKey,
44 InvalidRandomness,
46 InvalidRandomnessLength,
48 InvalidEncapsKeyLength,
50 InvalidCiphertextLength,
52 InvalidSharedSecretLength,
54 Unknown,
56}
57
58#[derive(Debug)]
60pub enum DecapsError {
61 InvalidCiphertext,
63 InvalidDecapsKey,
65 InvalidDecapsKeyLength,
67 InvalidCiphertextLength,
69 InvalidSharedSecretLength,
71 Unknown,
73}
74
75impl From<arrayref::KeyGenError> for KeyGenError {
76 fn from(value: arrayref::KeyGenError) -> Self {
77 match value {
78 arrayref::KeyGenError::InvalidRandomness => KeyGenError::InvalidRandomness,
79 arrayref::KeyGenError::Unknown => KeyGenError::Unknown,
80 }
81 }
82}
83
84impl From<arrayref::EncapsError> for EncapsError {
85 fn from(value: arrayref::EncapsError) -> Self {
86 match value {
87 arrayref::EncapsError::InvalidEncapsKey => EncapsError::InvalidEncapsKey,
88 arrayref::EncapsError::InvalidRandomness => EncapsError::InvalidRandomness,
89 arrayref::EncapsError::Unknown => EncapsError::Unknown,
90 }
91 }
92}
93
94impl From<arrayref::DecapsError> for DecapsError {
95 fn from(value: arrayref::DecapsError) -> Self {
96 match value {
97 arrayref::DecapsError::InvalidCiphertext => DecapsError::InvalidCiphertext,
98 arrayref::DecapsError::InvalidDecapsKey => DecapsError::InvalidDecapsKey,
99 arrayref::DecapsError::Unknown => DecapsError::Unknown,
100 }
101 }
102}
103
104#[macro_export]
105macro_rules! impl_trait {
107 ($type:ty => $ek:expr, $dk:expr, $ct:expr, $ss:expr, $rand_kg:expr, $rand_encaps:expr) => {
108 impl $crate::kem::slice::Kem for $type {
109 fn keygen(ek: &mut [u8], dk: &mut [$crate::libcrux_secrets::U8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::KeyGenError> {
110 let ek : &mut [u8; $ek] = ek
111 .try_into()
112 .map_err(|_| $crate::kem::slice::KeyGenError::InvalidEncapsKeyLength)?;
113 let dk : &mut [$crate::libcrux_secrets::U8; $dk] = dk
114 .try_into()
115 .map_err(|_| $crate::kem::slice::KeyGenError::InvalidDecapsKeyLength)?;
116 let rand : &[$crate::libcrux_secrets::U8; $rand_kg] = rand
117 .try_into()
118 .map_err(|_| $crate::kem::slice::KeyGenError::InvalidRandomnessLength)?;
119
120 <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::keygen(ek, dk, rand).map_err($crate::kem::slice::KeyGenError::from)
121 }
122
123 fn encaps(ct: &mut [u8], ss: &mut [$crate::libcrux_secrets::U8], ek: &[u8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::EncapsError>{
124 let ct : &mut [u8; $ct] = ct
125 .try_into()
126 .map_err(|_| $crate::kem::slice::EncapsError::InvalidCiphertextLength)?;
127 let ss : &mut [$crate::libcrux_secrets::U8; $ss] = ss
128 .try_into()
129 .map_err(|_| $crate::kem::slice::EncapsError::InvalidSharedSecretLength)?;
130 let ek : & [u8; $ek] = ek
131 .try_into()
132 .map_err(|_| $crate::kem::slice::EncapsError::InvalidEncapsKeyLength)?;
133 let rand : &[$crate::libcrux_secrets::U8; $rand_encaps] = rand
134 .try_into()
135 .map_err(|_| $crate::kem::slice::EncapsError::InvalidRandomnessLength)?;
136
137
138 <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::encaps(ct, ss, ek,rand).map_err($crate::kem::slice::EncapsError::from)
139 }
140
141 fn decaps(ss: &mut [$crate::libcrux_secrets::U8], ct: &[u8], dk: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::DecapsError> {
142 let ss : &mut [$crate::libcrux_secrets::U8; $ss] = ss
143 .try_into()
144 .map_err(|_| $crate::kem::slice::DecapsError::InvalidSharedSecretLength)?;
145 let ct : &[u8; $ct] = ct
146 .try_into()
147 .map_err(|_| $crate::kem::slice::DecapsError::InvalidCiphertextLength)?;
148 let dk : &[$crate::libcrux_secrets::U8; $dk] = dk
149 .try_into()
150 .map_err(|_| $crate::kem::slice::DecapsError::InvalidDecapsKeyLength)?;
151
152 <$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::decaps(ss, ct, dk).map_err($crate::kem::slice::DecapsError::from)
153 }
154
155 }
156
157 #[cfg(test)]
158 #[test]
159 fn simple_kem_test(){
160 $crate::kem::tests::simple::<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps, $type>();
161 }
162 };
163
164}
165
166pub use impl_trait;
167
168impl core::fmt::Display for KeyGenError {
169 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170 let text = match self {
171 KeyGenError::InvalidRandomness => "error generating key with provided randomness",
172 KeyGenError::Unknown => "an unknown error occurred",
173 KeyGenError::InvalidRandomnessLength => "the provided randomness has the wrong length",
174 KeyGenError::InvalidEncapsKeyLength => {
175 "the provided encapsulation key has the wrong length"
176 }
177 KeyGenError::InvalidDecapsKeyLength => {
178 "the provided decapsulation key has the wrong length"
179 }
180 };
181
182 f.write_str(text)
183 }
184}
185
186impl core::fmt::Display for EncapsError {
187 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
188 let text = match self {
189 EncapsError::InvalidEncapsKey => "encapsulation key is invalid",
190 EncapsError::InvalidRandomness => "error generating key with provided randomness",
191 EncapsError::Unknown => "an unknown error occurred",
192 EncapsError::InvalidRandomnessLength => "the provided randomness has the wrong length",
193 EncapsError::InvalidEncapsKeyLength => {
194 "the provided encapsulation key has the wrong length"
195 }
196 EncapsError::InvalidCiphertextLength => "the provided ciphertext has the wrong length",
197 EncapsError::InvalidSharedSecretLength => {
198 "the provided shared secret has the wrong length"
199 }
200 };
201
202 f.write_str(text)
203 }
204}
205
206impl core::fmt::Display for DecapsError {
207 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
208 let text = match self {
209 DecapsError::InvalidDecapsKey => "encapsulation key is invalid",
210 DecapsError::InvalidCiphertext => "ciphertext is invalid",
211 DecapsError::Unknown => "an unknown error occurred",
212 DecapsError::InvalidCiphertextLength => "the provided ciphertext has the wrong length",
213 DecapsError::InvalidSharedSecretLength => {
214 "the provided shared secret has the wrong length"
215 }
216 DecapsError::InvalidDecapsKeyLength => {
217 "the provided decapsulation key has the wrong length"
218 }
219 };
220
221 f.write_str(text)
222 }
223}
224
225#[cfg(feature = "error-in-core")]
226mod error_in_core {
229 impl core::error::Error for super::KeyGenError {}
230 impl core::error::Error for super::EncapsError {}
231 impl core::error::Error for super::DecapsError {}
232}