Skip to content

Commit db5ece0

Browse files
authored
Merge pull request #151 from rustaceanrob/8-14-rand
Remove explicit `rand` dependency
2 parents eceb074 + 3c24a68 commit db5ece0

File tree

4 files changed

+40
-15
lines changed

4 files changed

+40
-15
lines changed

protocol/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ rust-version = "1.63.0"
1313
default = ["std"]
1414
# High-level wrappers using tokio traits - may affect MSRV requirements.
1515
tokio = ["std", "dep:tokio"]
16-
std = ["bitcoin/std", "bitcoin_hashes/std", "chacha20-poly1305/std", "rand/std", "rand/std_rng"]
16+
std = ["bitcoin/rand-std", "bitcoin_hashes/std", "chacha20-poly1305/std"]
1717

1818
[dependencies]
1919
# The tokio feature may increase the MSRV beyond 1.63.0
2020
# depending on which version of tokio is selected by the caller.
2121
tokio = { version = "1", default-features = false, optional = true, features = ["io-util"] }
22-
rand = { version = "0.8.0", default-features = false }
2322
bitcoin = { version = "0.32.4", default-features = false }
2423
# Depending on hashes directly for HKDF, can drop this and
2524
# use the re-exported version in bitcoin > 0.32.*.

protocol/src/handshake.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ use bitcoin::{
1616
},
1717
Network,
1818
};
19-
use rand::Rng;
2019

2120
use crate::{
22-
CipherSession, Error, OutboundCipher, PacketType, Role, SessionKeyMaterial,
21+
CipherSession, Error, FillBytes, OutboundCipher, PacketType, Role, SessionKeyMaterial,
2322
NUM_ELLIGATOR_SWIFT_BYTES, NUM_GARBAGE_TERMINTOR_BYTES, VERSION_CONTENT,
2423
};
2524

@@ -117,7 +116,7 @@ impl Handshake<Initialized> {
117116
/// Initialize a V2 transport handshake with a remote peer.
118117
#[cfg(feature = "std")]
119118
pub fn new(network: Network, role: Role) -> Result<Self, Error> {
120-
let mut rng = rand::thread_rng();
119+
let mut rng = bitcoin::secp256k1::rand::thread_rng();
121120
let curve = Secp256k1::signing_only();
122121
Self::new_with_rng(network, role, &mut rng, &curve)
123122
}
@@ -126,11 +125,12 @@ impl Handshake<Initialized> {
126125
pub fn new_with_rng<C: Signing>(
127126
network: Network,
128127
role: Role,
129-
rng: &mut impl Rng,
128+
rng: &mut impl FillBytes,
130129
curve: &Secp256k1<C>,
131130
) -> Result<Self, Error> {
132131
let mut secret_key_buffer = [0u8; 32];
133-
rng.fill(&mut secret_key_buffer[..]);
132+
rng.fill_bytes(&mut secret_key_buffer);
133+
debug_assert_ne!([0u8; 32], secret_key_buffer);
134134
let sk = SecretKey::from_slice(&secret_key_buffer)?;
135135
let pk = PublicKey::from_secret_key(curve, &sk);
136136
let es = ElligatorSwift::from_pubkey(pk);

protocol/src/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ where
582582
#[cfg(test)]
583583
mod tests {
584584
use super::*;
585-
use rand::{rngs::StdRng, SeedableRng};
585+
use bitcoin::secp256k1::rand::{rngs::StdRng, SeedableRng};
586586
use std::io::Cursor;
587587

588588
/// Generate deterministic handshake messages for testing.

protocol/src/lib.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,10 @@ impl fmt::Display for Error {
234234
"Packet size exceeds maximum 4MiB size for automatic allocation."
235235
),
236236
Error::NoGarbageTerminator => {
237-
write!(f, "More than 4095 bytes of garbage recieved in the handshake before a terminator was sent.")
237+
write!(f, "More than 4095 bytes of garbage received in the handshake before a terminator was sent.")
238238
}
239239
Error::SecretGeneration(e) => write!(f, "Cannot generate secrets: {e:?}."),
240-
Error::Decryption(e) => write!(f, "Decrytion error: {e:?}."),
240+
Error::Decryption(e) => write!(f, "Decryption error: {e:?}."),
241241
Error::V1Protocol => write!(f, "The remote peer is communicating on the V1 protocol."),
242242
Error::TooMuchGarbage => write!(
243243
f,
@@ -376,7 +376,7 @@ impl SessionKeyMaterial {
376376
hk.expand(garbage_info, &mut garbage)?;
377377
let initiator_garbage_terminator: [u8; 16] = garbage[..16]
378378
.try_into()
379-
.expect("first 16 btyes of expanded garbage");
379+
.expect("first 16 bytes of expanded garbage");
380380
let responder_garbage_terminator: [u8; 16] = garbage[16..]
381381
.try_into()
382382
.expect("last 16 bytes of expanded garbage");
@@ -783,15 +783,41 @@ impl CipherSession {
783783
}
784784
}
785785

786+
/// Fill a slice with random bytes. This trait _should_ be cryptographically secure; however, a
787+
/// psuedo-random number generator may be sufficient depending on your security model.
788+
pub trait FillBytes {
789+
/// Fill a 32 byte slice with random data.
790+
fn fill_bytes(&mut self, dest: &mut [u8; 32]);
791+
}
792+
793+
#[cfg(feature = "std")]
794+
macro_rules! impl_fill_bytes {
795+
($rng:ident) => {
796+
impl FillBytes for $rng {
797+
fn fill_bytes(&mut self, dest: &mut [u8; 32]) {
798+
use bitcoin::secp256k1::rand::RngCore;
799+
RngCore::fill_bytes(self, dest);
800+
}
801+
}
802+
};
803+
}
804+
805+
#[cfg(feature = "std")]
806+
use bitcoin::secp256k1::rand::rngs::{StdRng, ThreadRng};
807+
#[cfg(feature = "std")]
808+
impl_fill_bytes!(StdRng);
809+
#[cfg(feature = "std")]
810+
impl_fill_bytes!(ThreadRng);
811+
786812
#[cfg(all(test, feature = "std"))]
787813
mod tests {
788814

789815
use super::*;
790816
use bitcoin::secp256k1::ellswift::{ElligatorSwift, ElligatorSwiftParty};
817+
use bitcoin::secp256k1::rand::Rng;
791818
use bitcoin::secp256k1::SecretKey;
792819
use core::str::FromStr;
793820
use hex::prelude::*;
794-
use rand::Rng;
795821
use std::vec;
796822
use std::vec::Vec;
797823

@@ -972,7 +998,7 @@ mod tests {
972998

973999
#[test]
9741000
fn test_fuzz_packets() {
975-
let mut rng = rand::thread_rng();
1001+
let mut rng = bitcoin::secp256k1::rand::thread_rng();
9761002
let alice =
9771003
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
9781004
.unwrap();
@@ -1039,7 +1065,7 @@ mod tests {
10391065

10401066
#[test]
10411067
fn test_additional_authenticated_data() {
1042-
let mut rng = rand::thread_rng();
1068+
let mut rng = bitcoin::secp256k1::rand::thread_rng();
10431069
let alice =
10441070
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
10451071
.unwrap();
@@ -1088,7 +1114,7 @@ mod tests {
10881114

10891115
#[test]
10901116
fn test_vector_1() {
1091-
let mut rng = rand::thread_rng();
1117+
let mut rng = bitcoin::secp256k1::rand::thread_rng();
10921118
let alice =
10931119
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
10941120
.unwrap();

0 commit comments

Comments
 (0)