Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ rust-version = "1.63.0"
default = ["std"]
# High-level wrappers using tokio traits - may affect MSRV requirements.
tokio = ["std", "dep:tokio"]
std = ["bitcoin/std", "bitcoin_hashes/std", "chacha20-poly1305/std", "rand/std", "rand/std_rng"]
std = ["bitcoin/rand-std", "bitcoin_hashes/std", "chacha20-poly1305/std"]

[dependencies]
# The tokio feature may increase the MSRV beyond 1.63.0
# depending on which version of tokio is selected by the caller.
tokio = { version = "1", default-features = false, optional = true, features = ["io-util"] }
rand = { version = "0.8.0", default-features = false }
bitcoin = { version = "0.32.4", default-features = false }
# Depending on hashes directly for HKDF, can drop this and
# use the re-exported version in bitcoin > 0.32.*.
Expand Down
10 changes: 5 additions & 5 deletions protocol/src/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ use bitcoin::{
},
Network,
};
use rand::Rng;

use crate::{
CipherSession, Error, OutboundCipher, PacketType, Role, SessionKeyMaterial,
CipherSession, Error, FillBytes, OutboundCipher, PacketType, Role, SessionKeyMaterial,
NUM_ELLIGATOR_SWIFT_BYTES, NUM_GARBAGE_TERMINTOR_BYTES, VERSION_CONTENT,
};

Expand Down Expand Up @@ -117,7 +116,7 @@ impl Handshake<Initialized> {
/// Initialize a V2 transport handshake with a remote peer.
#[cfg(feature = "std")]
pub fn new(network: Network, role: Role) -> Result<Self, Error> {
let mut rng = rand::thread_rng();
let mut rng = bitcoin::secp256k1::rand::thread_rng();
let curve = Secp256k1::signing_only();
Self::new_with_rng(network, role, &mut rng, &curve)
}
Expand All @@ -126,11 +125,12 @@ impl Handshake<Initialized> {
pub fn new_with_rng<C: Signing>(
network: Network,
role: Role,
rng: &mut impl Rng,
rng: &mut impl FillBytes,
curve: &Secp256k1<C>,
) -> Result<Self, Error> {
let mut secret_key_buffer = [0u8; 32];
rng.fill(&mut secret_key_buffer[..]);
rng.fill_bytes(&mut secret_key_buffer);
debug_assert_ne!([0u8; 32], secret_key_buffer);
let sk = SecretKey::from_slice(&secret_key_buffer)?;
let pk = PublicKey::from_secret_key(curve, &sk);
let es = ElligatorSwift::from_pubkey(pk);
Expand Down
2 changes: 1 addition & 1 deletion protocol/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use rand::{rngs::StdRng, SeedableRng};
use bitcoin::secp256k1::rand::{rngs::StdRng, SeedableRng};
use std::io::Cursor;

/// Generate deterministic handshake messages for testing.
Expand Down
40 changes: 33 additions & 7 deletions protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,10 @@ impl fmt::Display for Error {
"Packet size exceeds maximum 4MiB size for automatic allocation."
),
Error::NoGarbageTerminator => {
write!(f, "More than 4095 bytes of garbage recieved in the handshake before a terminator was sent.")
write!(f, "More than 4095 bytes of garbage received in the handshake before a terminator was sent.")
}
Error::SecretGeneration(e) => write!(f, "Cannot generate secrets: {e:?}."),
Error::Decryption(e) => write!(f, "Decrytion error: {e:?}."),
Error::Decryption(e) => write!(f, "Decryption error: {e:?}."),
Error::V1Protocol => write!(f, "The remote peer is communicating on the V1 protocol."),
Error::TooMuchGarbage => write!(
f,
Expand Down Expand Up @@ -376,7 +376,7 @@ impl SessionKeyMaterial {
hk.expand(garbage_info, &mut garbage)?;
let initiator_garbage_terminator: [u8; 16] = garbage[..16]
.try_into()
.expect("first 16 btyes of expanded garbage");
.expect("first 16 bytes of expanded garbage");
let responder_garbage_terminator: [u8; 16] = garbage[16..]
.try_into()
.expect("last 16 bytes of expanded garbage");
Expand Down Expand Up @@ -783,15 +783,41 @@ impl CipherSession {
}
}

/// Fill a slice with random bytes. This trait _should_ be cryptographically secure; however, a
/// psuedo-random number generator may be sufficient depending on your security model.
pub trait FillBytes {
/// Fill a 32 byte slice with random data.
fn fill_bytes(&mut self, dest: &mut [u8; 32]);
}

#[cfg(feature = "std")]
macro_rules! impl_fill_bytes {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I see macros:

image

But this one seems good since small and contained.

($rng:ident) => {
impl FillBytes for $rng {
fn fill_bytes(&mut self, dest: &mut [u8; 32]) {
use bitcoin::secp256k1::rand::RngCore;
RngCore::fill_bytes(self, dest);
}
}
};
}

#[cfg(feature = "std")]
use bitcoin::secp256k1::rand::rngs::{StdRng, ThreadRng};
#[cfg(feature = "std")]
impl_fill_bytes!(StdRng);
#[cfg(feature = "std")]
impl_fill_bytes!(ThreadRng);

#[cfg(all(test, feature = "std"))]
mod tests {

use super::*;
use bitcoin::secp256k1::ellswift::{ElligatorSwift, ElligatorSwiftParty};
use bitcoin::secp256k1::rand::Rng;
use bitcoin::secp256k1::SecretKey;
use core::str::FromStr;
use hex::prelude::*;
use rand::Rng;
use std::vec;
use std::vec::Vec;

Expand Down Expand Up @@ -972,7 +998,7 @@ mod tests {

#[test]
fn test_fuzz_packets() {
let mut rng = rand::thread_rng();
let mut rng = bitcoin::secp256k1::rand::thread_rng();
let alice =
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
.unwrap();
Expand Down Expand Up @@ -1039,7 +1065,7 @@ mod tests {

#[test]
fn test_additional_authenticated_data() {
let mut rng = rand::thread_rng();
let mut rng = bitcoin::secp256k1::rand::thread_rng();
let alice =
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
.unwrap();
Expand Down Expand Up @@ -1088,7 +1114,7 @@ mod tests {

#[test]
fn test_vector_1() {
let mut rng = rand::thread_rng();
let mut rng = bitcoin::secp256k1::rand::thread_rng();
let alice =
SecretKey::from_str("61062ea5071d800bbfd59e2e8b53d47d194b095ae5a4df04936b49772ef0d4d7")
.unwrap();
Expand Down
Loading