libcrux_traits/ecdh/
slice.rs1use super::arrayref;
6use libcrux_secrets::U8;
7
8pub trait EcdhSlice {
9 fn generate_secret(secret: &mut [U8], rand: &[U8]) -> Result<(), GenerateSecretError>;
13
14 fn secret_to_public(public: &mut [u8], secret: &[U8]) -> Result<(), SecretToPublicError>;
16
17 fn generate_pair(
20 public: &mut [u8],
21 secret: &mut [U8],
22 rand: &[U8],
23 ) -> Result<(), GenerateSecretError> {
24 Self::generate_secret(secret, rand)?;
25 Self::secret_to_public(public, secret).map_err(|_| GenerateSecretError::Unknown)
26 }
27
28 fn derive_ecdh(derived: &mut [U8], public: &[u8], secret: &[U8]) -> Result<(), DeriveError>;
35
36 fn validate_secret(secret: &[U8]) -> Result<(), ValidateSecretError>;
38}
39
40#[macro_export]
43macro_rules! impl_ecdh_slice_trait {
44 ($type:ty => $rand_len:expr, $sk_len:expr, $pk_len:expr) => {
45 impl $crate::ecdh::slice::EcdhSlice for $type {
46 fn generate_secret(secret: &mut [U8], rand: &[U8]) -> Result<(), $crate::ecdh::slice::GenerateSecretError> {
47 let secret: &mut [U8; $sk_len] = secret
48 .try_into()
49 .map_err(|_|
50 $crate::ecdh::slice::GenerateSecretError::InvalidSecretLength)?;
51
52 let rand: &[U8; $rand_len] = rand
53 .try_into()
54 .map_err(|_|
55 $crate::ecdh::slice::GenerateSecretError::InvalidRandomnessLength)?;
56
57 <$type as $crate::ecdh::arrayref::EcdhArrayref<$rand_len, $sk_len, $pk_len>>::generate_secret(secret, rand)
58 .map_err($crate::ecdh::slice::GenerateSecretError::from)
59 }
60
61 fn secret_to_public(public: &mut [u8], secret: &[U8]) -> Result<(), $crate::ecdh::slice::SecretToPublicError> {
62 let secret: &[U8; $sk_len] = secret
63 .try_into()
64 .map_err(|_|
65 $crate::ecdh::slice::SecretToPublicError::InvalidSecretLength)?;
66
67 let public: &mut [u8; $pk_len] = public
68 .try_into()
69 .map_err(|_|
70 $crate::ecdh::slice::SecretToPublicError::InvalidPublicLength)?;
71
72 <$type as $crate::ecdh::arrayref::EcdhArrayref<$rand_len, $sk_len, $pk_len>>::secret_to_public(public, secret)
73 .map_err($crate::ecdh::slice::SecretToPublicError::from)
74 }
75
76 fn derive_ecdh(derived: &mut [U8], public: &[u8], secret: &[U8]) -> Result<(), $crate::ecdh::slice::DeriveError> {
77 let derived: &mut [U8; $pk_len] = derived
78 .try_into()
79 .map_err(|_|
80 $crate::ecdh::slice::DeriveError::InvalidDeriveLength)?;
81
82 let secret: &[U8; $sk_len] = secret
83 .try_into()
84 .map_err(|_|
85 $crate::ecdh::slice::DeriveError::InvalidSecretLength)?;
86
87 let public: &[u8; $pk_len] = public
88 .try_into()
89 .map_err(|_|
90 $crate::ecdh::slice::DeriveError::InvalidPublicLength)?;
91
92 <$type as $crate::ecdh::arrayref::EcdhArrayref<$rand_len, $sk_len, $pk_len>>::derive_ecdh(derived, public, secret)
93 .map_err($crate::ecdh::slice::DeriveError::from)
94 }
95
96 fn validate_secret(secret: &[U8]) -> Result<(), $crate::ecdh::slice::ValidateSecretError> {
97 let secret: &[U8; $sk_len] = secret
98 .try_into()
99 .map_err(|_|
100 $crate::ecdh::slice::ValidateSecretError::InvalidSecretLength)?;
101
102 <$type as $crate::ecdh::arrayref::EcdhArrayref<$rand_len, $sk_len, $pk_len>>::validate_secret(secret)
103 .map_err($crate::ecdh::slice::ValidateSecretError::from)
104 }
105 }
106 };
107}
108
109pub use impl_ecdh_slice_trait;
110
111#[derive(Debug)]
112pub enum GenerateSecretError {
114 InvalidRandomness,
116 InvalidSecretLength,
118 InvalidRandomnessLength,
120 Unknown,
122}
123
124#[derive(Debug)]
125pub enum SecretToPublicError {
127 InvalidSecret,
129 InvalidSecretLength,
131 InvalidPublicLength,
133 Unknown,
135}
136
137#[derive(Debug)]
138pub enum DeriveError {
140 InvalidPublic,
142 InvalidSecret,
144 InvalidSecretLength,
146 InvalidPublicLength,
148 InvalidDeriveLength,
150 Unknown,
152}
153
154#[derive(Debug)]
155pub enum ValidateSecretError {
157 InvalidSecret,
159 InvalidSecretLength,
161 Unknown,
163}
164
165impl From<arrayref::GenerateSecretError> for GenerateSecretError {
166 fn from(value: arrayref::GenerateSecretError) -> Self {
167 match value {
168 arrayref::GenerateSecretError::InvalidRandomness => {
169 GenerateSecretError::InvalidRandomness
170 }
171 arrayref::GenerateSecretError::Unknown => GenerateSecretError::Unknown,
172 }
173 }
174}
175impl From<arrayref::SecretToPublicError> for SecretToPublicError {
176 fn from(value: arrayref::SecretToPublicError) -> Self {
177 match value {
178 arrayref::SecretToPublicError::InvalidSecret => SecretToPublicError::InvalidSecret,
179 arrayref::SecretToPublicError::Unknown => SecretToPublicError::Unknown,
180 }
181 }
182}
183impl From<arrayref::DeriveError> for DeriveError {
184 fn from(value: arrayref::DeriveError) -> Self {
185 match value {
186 arrayref::DeriveError::InvalidPublic => DeriveError::InvalidPublic,
187 arrayref::DeriveError::InvalidSecret => DeriveError::InvalidSecret,
188 arrayref::DeriveError::Unknown => DeriveError::Unknown,
189 }
190 }
191}
192impl From<arrayref::ValidateSecretError> for ValidateSecretError {
193 fn from(value: arrayref::ValidateSecretError) -> Self {
194 match value {
195 arrayref::ValidateSecretError::InvalidSecret => ValidateSecretError::InvalidSecret,
196 arrayref::ValidateSecretError::Unknown => ValidateSecretError::Unknown,
197 }
198 }
199}
200
201impl core::fmt::Display for GenerateSecretError {
202 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
203 let text = match self {
204 GenerateSecretError::InvalidRandomness => {
205 "error generating secret value with provided randomness"
206 }
207 GenerateSecretError::Unknown => "an unknown error occured",
208 GenerateSecretError::InvalidRandomnessLength => {
209 "the provided randomess buffer has the wrong length"
210 }
211 GenerateSecretError::InvalidSecretLength => {
212 "the provided secret value buffer has the wrong length"
213 }
214 };
215
216 f.write_str(text)
217 }
218}
219
220impl core::fmt::Display for SecretToPublicError {
221 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
222 let text = match self {
223 SecretToPublicError::InvalidSecret => "secret value is invalid",
224 SecretToPublicError::Unknown => "an unknown error occured",
225 SecretToPublicError::InvalidSecretLength => {
226 "the provided secret value buffer has the wrong length"
227 }
228 SecretToPublicError::InvalidPublicLength => {
229 "the provided public value buffer has the wrong length"
230 }
231 };
232
233 f.write_str(text)
234 }
235}
236
237impl core::fmt::Display for DeriveError {
238 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
239 let text = match self {
240 DeriveError::InvalidPublic => "public value is invalid",
241 DeriveError::InvalidSecret => "secret value is invalid",
242 DeriveError::Unknown => "an unknown error occured",
243 DeriveError::InvalidSecretLength => {
244 "the provided secret value buffer has the wrong length"
245 }
246 DeriveError::InvalidPublicLength => {
247 "the provided public value buffer has the wrong length"
248 }
249 DeriveError::InvalidDeriveLength => {
250 "the provided shared secret buffer has the wrong length"
251 }
252 };
253
254 f.write_str(text)
255 }
256}
257
258impl core::fmt::Display for ValidateSecretError {
259 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
260 let text = match self {
261 ValidateSecretError::InvalidSecret => "secret value is invalid",
262 ValidateSecretError::Unknown => "an unknown error occured",
263 ValidateSecretError::InvalidSecretLength => {
264 "the provided secret value buffer has the wrong length"
265 }
266 };
267
268 f.write_str(text)
269 }
270}
271
272#[cfg(feature = "error-in-core")]
273mod error_in_core {
276 impl core::error::Error for super::GenerateSecretError {}
277 impl core::error::Error for super::SecretToPublicError {}
278 impl core::error::Error for super::DeriveError {}
279 impl core::error::Error for super::ValidateSecretError {}
280}