From f440ffcec339469fd2d1643bb1d37d0048dbda82 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 21 Jul 2021 20:29:29 +0100 Subject: [PATCH] Centralize dependency on Rng instance Use tink_core::subtle::random::rng() to return an instance of the tink_core::subtle::random::Generator trait, which is just a combination of rand::RngCore and rand::CryptoRng. Use this rng() instance throughout the code. Drop a couple of direct dependencies on rand which were not needed. --- Cargo.lock | 2 -- aead/Cargo.toml | 1 - core/src/keyset/manager.rs | 2 +- core/src/subtle/random.rs | 22 ++++++++++++++++--- signature/src/ed25519_signer_key_manager.rs | 2 +- streaming/Cargo.toml | 1 - tests/src/lib.rs | 2 +- .../aead/subtle/chacha20poly1305_test.rs | 10 +++++---- .../aead/subtle/xchacha20poly1305_test.rs | 10 +++++---- .../subtle/ed25519_signer_verifier_test.rs | 10 ++++----- tests/tests/streaming/integration_test.rs | 3 ++- 11 files changed, 41 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ae4d966..2f67244f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2055,7 +2055,6 @@ dependencies = [ "aes-gcm-siv", "chacha20poly1305", "generic-array", - "rand 0.7.3", "tink-core", "tink-mac", "tink-proto", @@ -2174,7 +2173,6 @@ version = "0.2.1" dependencies = [ "aes", "aes-gcm", - "rand 0.7.3", "tink-core", "tink-mac", "tink-proto", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 3a632e71..f0bc0a42 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -19,7 +19,6 @@ aes-gcm = "^0.9.2" aes-gcm-siv = "^0.10" chacha20poly1305 = "^0.9" generic-array = "^0.14.4" -rand = "^0.7" tink-core = "^0.2" tink-mac = "^0.2" tink-proto = "^0.2" diff --git a/core/src/keyset/manager.rs b/core/src/keyset/manager.rs index 00540541..30c2e440 100644 --- a/core/src/keyset/manager.rs +++ b/core/src/keyset/manager.rs @@ -209,7 +209,7 @@ impl Manager { /// Generate a key id that has not been used by any key in the [`Keyset`](tink_proto::Keyset). fn new_key_id(&self) -> KeyId { - let mut rng = rand::thread_rng(); + let mut rng = crate::subtle::random::rng(); loop { let ret = rng.gen::(); diff --git a/core/src/subtle/random.rs b/core/src/subtle/random.rs index 629a6d79..e58fb505 100644 --- a/core/src/subtle/random.rs +++ b/core/src/subtle/random.rs @@ -16,16 +16,32 @@ //! Utilities for random data. -use rand::{thread_rng, Rng}; +/// Re-export the particular version of the `rand` crate whose types appear in the API. +pub use rand; + +use rand::Rng; + +/// Trait that encapsulates the required traits that a random number generator instance must +/// implement. +pub trait Generator: rand::RngCore + rand::CryptoRng {} + +/// Blanket implementation: any type that is a [`rand::CryptoRng`] is automatically +/// suitable as a Tink [`Generator`]. +impl Generator for T where T: rand::RngCore + rand::CryptoRng {} + +/// Return a random number generator suitable for cryptographic operation. +pub fn rng() -> Box { + Box::new(rand::thread_rng()) +} /// Return a vector of the given `size` filled with random bytes. pub fn get_random_bytes(size: usize) -> Vec { let mut data = vec![0u8; size]; - thread_rng().fill(&mut data[..]); + rng().fill(&mut data[..]); data } /// Randomly generate an unsigned 32-bit integer. pub fn get_random_uint32() -> u32 { - thread_rng().gen() + rng().gen() } diff --git a/signature/src/ed25519_signer_key_manager.rs b/signature/src/ed25519_signer_key_manager.rs index 4dd9c3e4..e82a0488 100644 --- a/signature/src/ed25519_signer_key_manager.rs +++ b/signature/src/ed25519_signer_key_manager.rs @@ -47,7 +47,7 @@ impl tink_core::registry::KeyManager for Ed25519SignerKeyManager { } fn new_key(&self, _serialized_key_format: &[u8]) -> Result, TinkError> { - let mut csprng = rand::rngs::OsRng {}; + let mut csprng = tink_core::subtle::random::rng(); let keypair = ed25519_dalek::Keypair::generate(&mut csprng); let public_proto = tink_proto::Ed25519PublicKey { diff --git a/streaming/Cargo.toml b/streaming/Cargo.toml index ae27d35a..72cee391 100644 --- a/streaming/Cargo.toml +++ b/streaming/Cargo.toml @@ -15,7 +15,6 @@ categories = ["cryptography"] aes = { version = "^0.7.4", features = ["ctr"] } # Need the `std` feature for Error type conversion aes-gcm = { version = "^0.9.2", features = ["std"] } -rand = "^0.7" tink-core = "^0.2" tink-mac = "^0.2" tink-proto = "^0.2" diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 822e0fc3..d4c81e1a 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -394,7 +394,7 @@ pub fn get_ecdsa_params( /// Create an [`Ed25519PrivateKey`](tink_proto::Ed25519PrivateKey) with randomly generated key /// material. pub fn new_ed25519_private_key() -> tink_proto::Ed25519PrivateKey { - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = ed25519_dalek::Keypair::generate(&mut csprng); let public_proto = tink_proto::Ed25519PublicKey { diff --git a/tests/tests/aead/subtle/chacha20poly1305_test.rs b/tests/tests/aead/subtle/chacha20poly1305_test.rs index 6ae72c58..1b4ec7ac 100644 --- a/tests/tests/aead/subtle/chacha20poly1305_test.rs +++ b/tests/tests/aead/subtle/chacha20poly1305_test.rs @@ -15,10 +15,12 @@ //////////////////////////////////////////////////////////////////////////////// use super::{chacha20poly1305_vectors::*, wycheproof::*}; -use rand::{thread_rng, Rng}; use std::collections::HashSet; use tink_aead::subtle; -use tink_core::{subtle::random::get_random_bytes, Aead}; +use tink_core::{ + subtle::random::{get_random_bytes, rand::Rng}, + Aead, +}; use tink_tests::WycheproofResult; #[test] @@ -172,7 +174,7 @@ fn test_cha_cha20_poly1305_modify_ciphertext() { .unwrap_or_else(|e| panic!("#{}: encrypt failed: {:?}", i, e)); if !aad.is_empty() { - let alter_aad_idx = thread_rng().gen_range(0, aad.len()); + let alter_aad_idx = tink_core::subtle::random::rng().gen_range(0, aad.len()); aad[alter_aad_idx] ^= 0x80; assert!( ca.decrypt(&ct, &aad).is_err(), @@ -182,7 +184,7 @@ fn test_cha_cha20_poly1305_modify_ciphertext() { aad[alter_aad_idx] ^= 0x80; } - let alter_ct_idx = thread_rng().gen_range(0, ct.len()); + let alter_ct_idx = tink_core::subtle::random::rng().gen_range(0, ct.len()); ct[alter_ct_idx] ^= 0x80; assert!( ca.decrypt(&ct, &aad).is_err(), diff --git a/tests/tests/aead/subtle/xchacha20poly1305_test.rs b/tests/tests/aead/subtle/xchacha20poly1305_test.rs index aa22ef36..dcdbaf0c 100644 --- a/tests/tests/aead/subtle/xchacha20poly1305_test.rs +++ b/tests/tests/aead/subtle/xchacha20poly1305_test.rs @@ -15,10 +15,12 @@ //////////////////////////////////////////////////////////////////////////////// use super::{wycheproof::*, xchacha20poly1305_vectors::*}; -use rand::{thread_rng, Rng}; use std::collections::HashSet; use tink_aead::subtle; -use tink_core::{subtle::random::get_random_bytes, Aead}; +use tink_core::{ + subtle::random::{get_random_bytes, rand::Rng}, + Aead, +}; use tink_tests::WycheproofResult; #[test] @@ -173,7 +175,7 @@ fn test_x_cha_cha20_poly1305_modify_ciphertext() { .unwrap_or_else(|e| panic!("#{}: encrypt failed: {:?}", i, e)); if !aad.is_empty() { - let alter_aad_idx = thread_rng().gen_range(0, aad.len()); + let alter_aad_idx = tink_core::subtle::random::rng().gen_range(0, aad.len()); aad[alter_aad_idx] ^= 0x80; assert!( ca.decrypt(&ct, &aad).is_err(), @@ -183,7 +185,7 @@ fn test_x_cha_cha20_poly1305_modify_ciphertext() { aad[alter_aad_idx] ^= 0x80; } - let alter_ct_idx = thread_rng().gen_range(0, ct.len()); + let alter_ct_idx = tink_core::subtle::random::rng().gen_range(0, ct.len()); ct[alter_ct_idx] ^= 0x80; assert!( ca.decrypt(&ct, &aad).is_err(), diff --git a/tests/tests/signature/subtle/ed25519_signer_verifier_test.rs b/tests/tests/signature/subtle/ed25519_signer_verifier_test.rs index d31114e8..68d2e68e 100644 --- a/tests/tests/signature/subtle/ed25519_signer_verifier_test.rs +++ b/tests/tests/signature/subtle/ed25519_signer_verifier_test.rs @@ -23,7 +23,7 @@ use tink_tests::WycheproofResult; #[test] fn test_ed25519_deterministic() { let data = get_random_bytes(20); - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = Keypair::generate(&mut csprng); // Use the private key and public key directly to create new instances @@ -46,7 +46,7 @@ fn test_ed25519_deterministic() { #[test] fn test_ed25519_verify_modified_signature() { let data = get_random_bytes(20); - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = Keypair::generate(&mut csprng); // Use the private key and public key directly to create new instances @@ -73,7 +73,7 @@ fn test_ed25519_verify_modified_signature() { #[test] fn test_ed25519_verify_truncated_signature() { let data = get_random_bytes(20); - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = Keypair::generate(&mut csprng); // Use the private key and public key directly to create new instances @@ -89,7 +89,7 @@ fn test_ed25519_verify_truncated_signature() { #[test] fn test_ed25519_verify_modified_message() { let mut data = get_random_bytes(20); - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = Keypair::generate(&mut csprng); // Use the private key and public key directly to create new instances @@ -114,7 +114,7 @@ fn test_ed25519_verify_modified_message() { } #[test] fn test_ed25519_sign_verify() { - let mut csprng = rand::thread_rng(); + let mut csprng = tink_core::subtle::random::rng(); let keypair = Keypair::generate(&mut csprng); let seed = keypair.secret.as_bytes().to_vec(); diff --git a/tests/tests/streaming/integration_test.rs b/tests/tests/streaming/integration_test.rs index 6098f71f..c874a0d6 100644 --- a/tests/tests/streaming/integration_test.rs +++ b/tests/tests/streaming/integration_test.rs @@ -174,7 +174,8 @@ impl std::io::Read for PartialReader { // when more data is available. This is valid for Rust's `std::io::Read`, but // would not be valid for an `io::Writer` in Go. fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - if rand::thread_rng().gen_range(0, 3) == 0 { + let mut csprng = tink_core::subtle::random::rng(); + if csprng.gen_range(0, 3) == 0 { // Randomly pretend to have been interrupted. return Err(std::io::Error::new( std::io::ErrorKind::Interrupted,