-
Notifications
You must be signed in to change notification settings - Fork 228
crypto-common: add TryKeyInit trait
#2092
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
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`) Key generation methods are provided which generically implement rejection sampling as a reasonabe baseline for unbiased random sampling of potential keys. As a provided method, implementers of `TryKeyInit` can override it if they can provide more efficient means of generating keys.
There is a counterexample to this: the Ed25519 signature system uses a seed to derive the private scalar as the result of SHA-512 acting as a KDF, along with "clamping" to ensure the scalar is in range. So Ed25519 keys could use But for ECDSA keys, or secp256k1 Schnorr, we'd want (There is also a similar concern for X25519 static keys) |
| fn generate_key() -> Result<Key<Self>, getrandom::Error> { | ||
| // Use rejection sampling to find a key which initializes successfully in an unbiased manner | ||
| loop { | ||
| let mut key = Key::<Self>::default(); | ||
| getrandom::fill(&mut key)?; | ||
|
|
||
| if Self::new(&key).is_ok() { | ||
| return Ok(key); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: #2060 implementing random bytestring generation in hybrid-array (which I still think is an independently good idea) won't suffice for these use cases, since they need algorithm-specific logic to select valid keys.
The approach in this PR is able to provide a generic unbiased key generation implementation which can have algorithm-specific overrides to improve efficiency.
I think we could potentially drop the keygen for KeyInit and point to hybrid-array for such cases, but having generic keygen for TryKeyInit is still independently useful, IMO.
|
With #2096 I think the RNG code in this PR can be substantially improved. It would be nice to retain a generic implementation of rejection sampling though. Perhaps it could work with a blanket impl and a marker trait, e.g. |
Adds a trait providing fallible key initialization, similar to the existing
KeyInittrait, 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 thatKeyInitandTryKeyInithave an either-or relationship, i.e. types will not impl bothKeyInitandTryKeyInit, and consumers of code which is generic over these traits will not be attempting to abstract over theKeyInit/TryKeyInitdistinction, but one or the other will make sense in a given context (e.g. symmetric cryptography usesKeyInit, ECC usesTryKeyInit)Key generation methods are provided which generically implement rejection sampling as a reasonabe baseline for unbiased random sampling of potential keys. As a provided method, implementers of
TryKeyInitcan override it if they can provide more efficient means of generating keys.Closes #1897