Skip to content

Commit

Permalink
feat(identity)!: make rand optional
Browse files Browse the repository at this point in the history
Some restricted environments lack proper random source, and `getrandom` crate
fails to compile.  However, random sources is needed only for random key
generation which is not always required.

This change introduces `rand` feature flag that is gate to all the
functionality that requires `rand` crate.
  • Loading branch information
monoid committed Aug 19, 2023
1 parent da94dcb commit 5605603
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 13 deletions.
10 changes: 5 additions & 5 deletions identity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ zeroize = { version = "1.6", optional = true }
ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false, optional = true}

[features]
secp256k1 = [ "dep:libsecp256k1", "dep:asn1_der", "dep:rand", "dep:sha2", "dep:zeroize" ]
ecdsa = [ "dep:p256", "dep:rand", "dep:void", "dep:zeroize", "dep:sec1" ]
rsa = [ "dep:ring", "dep:asn1_der", "dep:rand", "dep:zeroize" ]
ed25519 = [ "dep:ed25519-dalek", "dep:rand", "dep:zeroize" ]
peerid = [ "dep:multihash", "dep:bs58", "dep:rand", "dep:thiserror", "dep:sha2" ]
secp256k1 = [ "dep:libsecp256k1", "dep:asn1_der", "dep:sha2", "dep:zeroize" ]
ecdsa = [ "dep:p256", "dep:void", "dep:zeroize", "dep:sec1" ]
rsa = [ "dep:ring", "dep:asn1_der", "rand", "dep:zeroize" ]
ed25519 = [ "dep:ed25519-dalek", "dep:zeroize" ]
peerid = [ "dep:multihash", "dep:bs58", "dep:thiserror", "dep:sha2" ]

[dev-dependencies]
quickcheck = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions identity/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Keypair {

impl Keypair {
/// Generate a new random ECDSA keypair.
#[cfg(feature = "rand")]
pub fn generate() -> Keypair {
Keypair::from(SecretKey::generate())
}
Expand Down Expand Up @@ -265,6 +266,7 @@ mod tests {
use super::*;

#[test]
#[cfg(feature = "rand")]
fn sign_verify() {
let pair = Keypair::generate();
let pk = pair.public();
Expand Down
6 changes: 6 additions & 0 deletions identity/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use core::cmp;
use core::fmt;
use core::hash;
use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _};
#[cfg(feature = "rand")]
use rand::RngCore;
use std::convert::TryFrom;
use zeroize::Zeroize;
Expand All @@ -34,6 +35,7 @@ pub struct Keypair(ed25519::Keypair);

impl Keypair {
/// Generate a new random Ed25519 keypair.
#[cfg(feature = "rand")]
pub fn generate() -> Keypair {
Keypair::from(SecretKey::generate())
}
Expand Down Expand Up @@ -202,6 +204,7 @@ impl fmt::Debug for SecretKey {

impl SecretKey {
/// Generate a new Ed25519 secret key.
#[cfg(feature = "rand")]
pub fn generate() -> SecretKey {
let mut bytes = [0u8; 32];
rand::thread_rng().fill_bytes(&mut bytes);
Expand Down Expand Up @@ -235,6 +238,7 @@ mod tests {
}

#[test]
#[cfg(feature = "rand")]
fn ed25519_keypair_encode_decode() {
fn prop() -> bool {
let kp1 = Keypair::generate();
Expand All @@ -246,6 +250,7 @@ mod tests {
}

#[test]
#[cfg(feature = "rand")]
fn ed25519_keypair_from_secret() {
fn prop() -> bool {
let kp1 = Keypair::generate();
Expand All @@ -257,6 +262,7 @@ mod tests {
}

#[test]
#[cfg(feature = "rand")]
fn ed25519_signature() {
let kp = Keypair::generate();
let pk = kp.public();
Expand Down
12 changes: 6 additions & 6 deletions identity/src/keypair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,23 @@ enum KeyPairInner {

impl Keypair {
/// Generate a new Ed25519 keypair.
#[cfg(feature = "ed25519")]
#[cfg(all(feature = "ed25519", feature = "rand"))]
pub fn generate_ed25519() -> Keypair {
Keypair {
keypair: KeyPairInner::Ed25519(ed25519::Keypair::generate()),
}
}

/// Generate a new Secp256k1 keypair.
#[cfg(feature = "secp256k1")]
#[cfg(all(feature = "secp256k1", feature = "rand"))]
pub fn generate_secp256k1() -> Keypair {
Keypair {
keypair: KeyPairInner::Secp256k1(secp256k1::Keypair::generate()),
}
}

/// Generate a new ECDSA keypair.
#[cfg(feature = "ecdsa")]
#[cfg(all(feature = "ecdsa", feature = "rand"))]
pub fn generate_ecdsa() -> Keypair {
Keypair {
keypair: KeyPairInner::Ecdsa(ecdsa::Keypair::generate()),
Expand Down Expand Up @@ -863,7 +863,7 @@ mod tests {
}

#[test]
#[cfg(feature = "ed25519")]
#[cfg(all(feature = "ed25519", feature = "rand"))]
fn test_publickey_from_ed25519_public_key() {
let pubkey = Keypair::generate_ed25519().public();
let ed25519_pubkey = pubkey
Expand All @@ -878,7 +878,7 @@ mod tests {
}

#[test]
#[cfg(feature = "secp256k1")]
#[cfg(all(feature = "secp256k1", feature = "rand"))]
fn test_publickey_from_secp256k1_public_key() {
let pubkey = Keypair::generate_secp256k1().public();
let secp256k1_pubkey = pubkey
Expand All @@ -892,7 +892,7 @@ mod tests {
}

#[test]
#[cfg(feature = "ecdsa")]
#[cfg(all(feature = "ecdsa", feature = "rand"))]
fn test_publickey_from_ecdsa_public_key() {
let pubkey = Keypair::generate_ecdsa().public();
let ecdsa_pubkey = pubkey.clone().try_into_ecdsa().expect("A ecdsa keypair");
Expand Down
7 changes: 5 additions & 2 deletions identity/src/peer_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#[cfg(feature = "rand")]
use rand::Rng;
use sha2::Digest as _;
use std::{convert::TryFrom, fmt, str::FromStr};
Expand Down Expand Up @@ -101,6 +102,7 @@ impl PeerId {
/// Generates a random peer ID from a cryptographically secure PRNG.
///
/// This is useful for randomly walking on a DHT, or for testing purposes.
#[cfg(feature = "rand")]
pub fn random() -> PeerId {
let peer_id = rand::thread_rng().gen::<[u8; 32]>();
PeerId {
Expand Down Expand Up @@ -247,22 +249,23 @@ mod tests {
use super::*;

#[test]
#[cfg(feature = "ed25519")]
#[cfg(all(feature = "ed25519", feature = "rand"))]
fn peer_id_into_bytes_then_from_bytes() {
let peer_id = crate::Keypair::generate_ed25519().public().to_peer_id();
let second = PeerId::from_bytes(&peer_id.to_bytes()).unwrap();
assert_eq!(peer_id, second);
}

#[test]
#[cfg(feature = "ed25519")]
#[cfg(all(feature = "ed25519", feature = "rand"))]
fn peer_id_to_base58_then_back() {
let peer_id = crate::Keypair::generate_ed25519().public().to_peer_id();
let second: PeerId = peer_id.to_base58().parse().unwrap();
assert_eq!(peer_id, second);
}

#[test]
#[cfg(feature = "rand")]
fn random_peer_id_is_valid() {
for _ in 0..5000 {
let peer_id = PeerId::random();
Expand Down
3 changes: 3 additions & 0 deletions identity/src/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Keypair {

impl Keypair {
/// Generate a new sec256k1 `Keypair`.
#[cfg(feature = "rand")]
pub fn generate() -> Keypair {
Keypair::from(SecretKey::generate())
}
Expand Down Expand Up @@ -88,6 +89,7 @@ impl fmt::Debug for SecretKey {

impl SecretKey {
/// Generate a new random Secp256k1 secret key.
#[cfg(feature = "rand")]
pub fn generate() -> SecretKey {
SecretKey(libsecp256k1::SecretKey::random(&mut rand::thread_rng()))
}
Expand Down Expand Up @@ -226,6 +228,7 @@ mod tests {
use super::*;

#[test]
#[cfg(feature = "rand")]
fn secp256k1_secret_from_bytes() {
let sk1 = SecretKey::generate();
let mut sk_bytes = [0; 32];
Expand Down

0 comments on commit 5605603

Please sign in to comment.