Skip to content

Commit a0819e2

Browse files
authored
crypto-common: add TryKeyInit trait (#2097)
Adds a trait providing fallible key initialization, similar to the existing `KeyInit` trait, but designed to handle the case that not all bytestrings of a given length represent valid keys. This is primarily useful in the context of public-key cryptography, e.g. scalars representing elliptic curve private keys. The API and method names are duplicated from `KeyInit`. It is assumed that `KeyInit` and `TryKeyInit` have an either-or relationship, i.e. types will not impl both `KeyInit` and `TryKeyInit`, and consumers of code which is generic over these traits will not be attempting to abstract over the `KeyInit`/`TryKeyInit` distinction, but one or the other will make sense in a given context (e.g. symmetric cryptography uses `KeyInit`, ECC uses `TryKeyInit`)
1 parent 7452c3b commit a0819e2

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

crypto-common/src/lib.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ pub trait AlgorithmName {
153153
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
154154
}
155155

156-
/// Types which can be initialized from key.
156+
/// Types which can be initialized from a key.
157157
pub trait KeyInit: KeySizeUser + Sized {
158158
/// Create new value from fixed size key.
159159
fn new(key: &Key<Self>) -> Self;
@@ -180,7 +180,7 @@ pub trait KeyInit: KeySizeUser + Sized {
180180
}
181181
}
182182

183-
/// Types which can be initialized from key and initialization vector (nonce).
183+
/// Types which can be initialized from a key and initialization vector (nonce).
184184
pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
185185
/// Create new value from fixed length key and nonce.
186186
fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
@@ -207,6 +207,27 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
207207
}
208208
}
209209

210+
/// Types which can be fallibly initialized from a key.
211+
pub trait TryKeyInit: KeySizeUser + Sized {
212+
/// Create new value from a fixed-size key.
213+
///
214+
/// # Errors
215+
/// - if the key is considered invalid according to rules specific to the implementing type
216+
fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
217+
218+
/// Create new value from a variable size key.
219+
///
220+
/// # Errors
221+
/// - if the provided slice is the wrong length
222+
/// - if the key is considered invalid by [`TryKeyInit::new`]
223+
#[inline]
224+
fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
225+
<&Key<Self>>::try_from(key)
226+
.map_err(|_| InvalidKey)
227+
.and_then(Self::new)
228+
}
229+
}
230+
210231
/// Types which can be initialized from another type (usually block ciphers).
211232
///
212233
/// Usually used for initializing types from block ciphers.
@@ -317,6 +338,20 @@ where
317338
}
318339
*/
319340

341+
/// Error type for [`TryKeyInit`] for cases where the provided bytes do not correspond to a
342+
/// valid key.
343+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
344+
pub struct InvalidKey;
345+
346+
impl fmt::Display for InvalidKey {
347+
#[inline]
348+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
349+
f.write_str("WeakKey")
350+
}
351+
}
352+
353+
impl core::error::Error for InvalidKey {}
354+
320355
/// The error type returned when key and/or IV used in the [`KeyInit`],
321356
/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
322357
/// an invalid length.

0 commit comments

Comments
 (0)