mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 15:02:20 +01:00
Merge pull request #353 from TheBlueMatt/2019-07-no-rand
Make rand a dev-dependency
This commit is contained in:
commit
cd8f1de394
44 changed files with 178 additions and 273 deletions
|
@ -3,7 +3,7 @@ rust:
|
|||
- stable
|
||||
- beta
|
||||
- 1.22.0
|
||||
- 1.29.2
|
||||
- 1.34.2
|
||||
cache: cargo
|
||||
|
||||
before_install:
|
||||
|
@ -13,5 +13,5 @@ before_install:
|
|||
script:
|
||||
- cargo build --verbose
|
||||
- cargo test --verbose
|
||||
- if [ "$(rustup show | grep default | grep 1.29.2)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi
|
||||
- if [ "$(rustup show | grep default | grep 1.34.2)" != "" ]; then cd fuzz && cargo test --verbose && ./travis-fuzz.sh; fi
|
||||
- if [ "$(rustup show | grep default | grep stable)" != "" ]; then cd net-tokio && cargo build --verbose; fi
|
||||
|
|
|
@ -24,7 +24,6 @@ max_level_debug = []
|
|||
[dependencies]
|
||||
bitcoin = "0.18"
|
||||
bitcoin_hashes = "0.3"
|
||||
rand = "0.4"
|
||||
secp256k1 = "0.12"
|
||||
|
||||
[dev-dependencies.bitcoin]
|
||||
|
@ -33,6 +32,7 @@ features = ["bitcoinconsensus"]
|
|||
|
||||
[dev-dependencies]
|
||||
hex = "0.3"
|
||||
rand = "0.4"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
|
|
@ -8,7 +8,6 @@ extern crate lightning;
|
|||
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
|
||||
|
||||
use lightning::ln::channelmonitor;
|
||||
use lightning::util::reset_rng_state;
|
||||
use lightning::util::ser::{ReadableArgs, Writer};
|
||||
|
||||
mod utils;
|
||||
|
@ -30,7 +29,6 @@ impl Writer for VecWriter {
|
|||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
let logger = Arc::new(test_logger::TestLogger::new("".to_owned()));
|
||||
if let Ok((latest_block_hash, monitor)) = <(Sha256dHash, channelmonitor::ChannelMonitor)>::read(&mut Cursor::new(data), logger.clone()) {
|
||||
let mut w = VecWriter(Vec::new());
|
||||
|
|
|
@ -37,7 +37,7 @@ use lightning::ln::channelmonitor::{ChannelMonitorUpdateErr, HTLCUpdate};
|
|||
use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage};
|
||||
use lightning::ln::router::{Route, RouteHop};
|
||||
use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, ErrorAction, HandleError, UpdateAddHTLC, LocalFeatures};
|
||||
use lightning::util::{reset_rng_state, fill_bytes, events};
|
||||
use lightning::util::events;
|
||||
use lightning::util::logger::Logger;
|
||||
use lightning::util::config::UserConfig;
|
||||
use lightning::util::events::{EventsProvider, MessageSendEventsProvider};
|
||||
|
@ -52,6 +52,7 @@ use secp256k1::Secp256k1;
|
|||
use std::cmp::Ordering;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::{Arc,Mutex};
|
||||
use std::sync::atomic;
|
||||
use std::io::Cursor;
|
||||
|
||||
struct FuzzEstimator {}
|
||||
|
@ -91,6 +92,8 @@ impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
|
|||
|
||||
struct KeyProvider {
|
||||
node_id: u8,
|
||||
session_id: atomic::AtomicU8,
|
||||
channel_id: atomic::AtomicU8,
|
||||
}
|
||||
impl KeysInterface for KeyProvider {
|
||||
fn get_node_secret(&self) -> SecretKey {
|
||||
|
@ -121,22 +124,18 @@ impl KeysInterface for KeyProvider {
|
|||
}
|
||||
|
||||
fn get_session_key(&self) -> SecretKey {
|
||||
let mut session_key = [0; 32];
|
||||
fill_bytes(&mut session_key);
|
||||
SecretKey::from_slice(&session_key).unwrap()
|
||||
let id = self.session_id.fetch_add(1, atomic::Ordering::Relaxed);
|
||||
SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 10, self.node_id]).unwrap()
|
||||
}
|
||||
|
||||
fn get_channel_id(&self) -> [u8; 32] {
|
||||
let mut channel_id = [0; 32];
|
||||
fill_bytes(&mut channel_id);
|
||||
channel_id
|
||||
let id = self.channel_id.fetch_add(1, atomic::Ordering::Relaxed);
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id, 11, self.node_id]
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
|
||||
let fee_est = Arc::new(FuzzEstimator{});
|
||||
let broadcast = Arc::new(TestBroadcaster{});
|
||||
|
||||
|
@ -146,7 +145,7 @@ pub fn do_test(data: &[u8]) {
|
|||
let watch = Arc::new(ChainWatchInterfaceUtil::new(Network::Bitcoin, Arc::clone(&logger)));
|
||||
let monitor = Arc::new(TestChannelMonitor::new(watch.clone(), broadcast.clone(), logger.clone(), fee_est.clone()));
|
||||
|
||||
let keys_manager = Arc::new(KeyProvider { node_id: $node_id });
|
||||
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
|
||||
let mut config = UserConfig::new();
|
||||
config.channel_options.fee_proportional_millionths = 0;
|
||||
config.channel_options.announced_channel = true;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::AcceptChannel, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::AnnouncementSignatures, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_exact!(msgs::ChannelAnnouncement, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::ChannelReestablish, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_exact!(msgs::ChannelUpdate, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::ClosingSigned, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::CommitmentSigned, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::DecodedOnionErrorPacket, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_hole!(msgs::ErrorMessage, data, 32, 2);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::FundingCreated, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::FundingLocked, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::FundingSigned, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::Init, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_exact!(msgs::NodeAnnouncement, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_hole!(msgs::OnionHopData, data, 1+8+8+4, 12);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::OpenChannel, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_simple!(msgs::Ping, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_simple!(msgs::Pong, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::RevokeAndACK, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::Shutdown, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
TEST_MSG!(msgs::MSG_TARGET, dataEXTRA_ARGS);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg_hole!(msgs::UpdateAddHTLC, data, 85, 33);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::UpdateFailHTLC, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::UpdateFailMalformedHTLC, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::UpdateFee, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
extern crate lightning;
|
||||
|
||||
use lightning::ln::msgs;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
mod utils;
|
||||
use utils::VecWriter;
|
||||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
test_msg!(msgs::UpdateFulfillHTLC, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ extern crate lightning;
|
|||
extern crate secp256k1;
|
||||
|
||||
use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
|
||||
use lightning::util::reset_rng_state;
|
||||
|
||||
use secp256k1::key::{PublicKey,SecretKey};
|
||||
|
||||
|
@ -14,8 +13,6 @@ fn slice_to_be16(v: &[u8]) -> u16 {
|
|||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
|
||||
let mut read_pos = 0;
|
||||
macro_rules! get_slice {
|
||||
($len: expr) => {
|
||||
|
@ -34,13 +31,17 @@ pub fn do_test(data: &[u8]) {
|
|||
Ok(key) => key,
|
||||
Err(_) => return,
|
||||
};
|
||||
let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
|
||||
Ok(key) => key,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let mut crypter = if get_slice!(1)[0] != 0 {
|
||||
let their_pubkey = match PublicKey::from_slice(get_slice!(33)) {
|
||||
Ok(key) => key,
|
||||
Err(_) => return,
|
||||
};
|
||||
let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey);
|
||||
let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
|
||||
crypter.get_act_one();
|
||||
match crypter.process_act_two(get_slice!(50), &our_network_key) {
|
||||
Ok(_) => {},
|
||||
|
@ -50,7 +51,7 @@ pub fn do_test(data: &[u8]) {
|
|||
crypter
|
||||
} else {
|
||||
let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key);
|
||||
match crypter.process_act_one_with_key(get_slice!(50), &our_network_key) {
|
||||
match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key) {
|
||||
Ok(_) => {},
|
||||
Err(_) => return,
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use lightning::ln::channelmanager::ChannelDetails;
|
|||
use lightning::ln::msgs;
|
||||
use lightning::ln::msgs::{RoutingMessageHandler};
|
||||
use lightning::ln::router::{Router, RouteHint};
|
||||
use lightning::util::reset_rng_state;
|
||||
use lightning::util::logger::Logger;
|
||||
use lightning::util::ser::Readable;
|
||||
|
||||
|
@ -96,8 +95,6 @@ impl ChainWatchInterface for DummyChainWatcher {
|
|||
|
||||
#[inline]
|
||||
pub fn do_test(data: &[u8]) {
|
||||
reset_rng_state();
|
||||
|
||||
let input = Arc::new(InputData {
|
||||
data: data.to_vec(),
|
||||
read_pos: AtomicUsize::new(0),
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../../src/util/rust_crypto_nonstd_arch.c
|
|
@ -9,6 +9,7 @@ use bitcoin::network::constants::Network;
|
|||
use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, ChildNumber};
|
||||
|
||||
use bitcoin_hashes::{Hash, HashEngine};
|
||||
use bitcoin_hashes::sha256::HashEngine as Sha256State;
|
||||
use bitcoin_hashes::sha256::Hash as Sha256;
|
||||
use bitcoin_hashes::hash160::Hash as Hash160;
|
||||
|
||||
|
@ -16,11 +17,9 @@ use secp256k1::key::{SecretKey, PublicKey};
|
|||
use secp256k1::Secp256k1;
|
||||
use secp256k1;
|
||||
|
||||
use util::logger::Logger;
|
||||
use util::rng;
|
||||
use util::byte_utils;
|
||||
use util::logger::Logger;
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
|
@ -131,13 +130,31 @@ pub struct KeysManager {
|
|||
channel_id_master_key: ExtendedPrivKey,
|
||||
channel_id_child_index: AtomicUsize,
|
||||
|
||||
unique_start: Sha256State,
|
||||
logger: Arc<Logger>,
|
||||
}
|
||||
|
||||
impl KeysManager {
|
||||
/// Constructs a KeysManager from a 32-byte seed. If the seed is in some way biased (eg your
|
||||
/// RNG is busted) this may panic.
|
||||
pub fn new(seed: &[u8; 32], network: Network, logger: Arc<Logger>) -> KeysManager {
|
||||
/// RNG is busted) this may panic (but more importantly, you will possibly lose funds).
|
||||
/// starting_time isn't strictly required to actually be a time, but it must absolutely,
|
||||
/// without a doubt, be unique to this instance. ie if you start multiple times with the same
|
||||
/// seed, starting_time must be unique to each run. Thus, the easiest way to achieve this is to
|
||||
/// simply use the current time (with very high precision).
|
||||
///
|
||||
/// The seed MUST be backed up safely prior to use so that the keys can be re-created, however,
|
||||
/// obviously, starting_time should be unique every time you reload the library - it is only
|
||||
/// used to generate new ephemeral key data (which will be stored by the individual channel if
|
||||
/// necessary).
|
||||
///
|
||||
/// Note that the seed is required to recover certain on-chain funds independent of
|
||||
/// ChannelMonitor data, though a current copy of ChannelMonitor data is also required for any
|
||||
/// channel, and some on-chain during-closing funds.
|
||||
///
|
||||
/// Note that until the 0.1 release there is no guarantee of backward compatibility between
|
||||
/// versions. Once the library is more fully supported, the docs will be updated to include a
|
||||
/// detailed description of the guarantee.
|
||||
pub fn new(seed: &[u8; 32], network: Network, logger: Arc<Logger>, starting_time_secs: u64, starting_time_nanos: u32) -> KeysManager {
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
match ExtendedPrivKey::new_master(network.clone(), seed) {
|
||||
Ok(master_key) => {
|
||||
|
@ -158,6 +175,12 @@ impl KeysManager {
|
|||
let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap()).expect("Your RNG is busted");
|
||||
let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
|
||||
let channel_id_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap()).expect("Your RNG is busted");
|
||||
|
||||
let mut unique_start = Sha256::engine();
|
||||
unique_start.input(&byte_utils::be64_to_array(starting_time_secs));
|
||||
unique_start.input(&byte_utils::be32_to_array(starting_time_nanos));
|
||||
unique_start.input(seed);
|
||||
|
||||
KeysManager {
|
||||
secp_ctx,
|
||||
node_secret,
|
||||
|
@ -170,6 +193,7 @@ impl KeysManager {
|
|||
channel_id_master_key,
|
||||
channel_id_child_index: AtomicUsize::new(0),
|
||||
|
||||
unique_start,
|
||||
logger,
|
||||
}
|
||||
},
|
||||
|
@ -193,24 +217,15 @@ impl KeysInterface for KeysManager {
|
|||
|
||||
fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys {
|
||||
// We only seriously intend to rely on the channel_master_key for true secure
|
||||
// entropy, everything else just ensures uniqueness. We generally don't expect
|
||||
// all clients to have non-broken RNGs here, so we also include the current
|
||||
// time as a fallback to get uniqueness.
|
||||
let mut sha = Sha256::engine();
|
||||
|
||||
let mut seed = [0u8; 32];
|
||||
rng::fill_bytes(&mut seed[..]);
|
||||
sha.input(&seed);
|
||||
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
|
||||
sha.input(&byte_utils::be32_to_array(now.subsec_nanos()));
|
||||
sha.input(&byte_utils::be64_to_array(now.as_secs()));
|
||||
// entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
|
||||
// starting_time provided in the constructor) to be unique.
|
||||
let mut sha = self.unique_start.clone();
|
||||
|
||||
let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
|
||||
let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
|
||||
sha.input(&child_privkey.private_key.key[..]);
|
||||
|
||||
seed = Sha256::from_engine(sha).into_inner();
|
||||
let seed = Sha256::from_engine(sha).into_inner();
|
||||
|
||||
let commitment_seed = {
|
||||
let mut sha = Sha256::engine();
|
||||
|
@ -244,11 +259,7 @@ impl KeysInterface for KeysManager {
|
|||
}
|
||||
|
||||
fn get_session_key(&self) -> SecretKey {
|
||||
let mut sha = Sha256::engine();
|
||||
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
|
||||
sha.input(&byte_utils::be32_to_array(now.subsec_nanos()));
|
||||
sha.input(&byte_utils::be64_to_array(now.as_secs()));
|
||||
let mut sha = self.unique_start.clone();
|
||||
|
||||
let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel);
|
||||
let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
|
||||
|
@ -257,11 +268,7 @@ impl KeysInterface for KeysManager {
|
|||
}
|
||||
|
||||
fn get_channel_id(&self) -> [u8; 32] {
|
||||
let mut sha = Sha256::engine();
|
||||
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
|
||||
sha.input(&byte_utils::be32_to_array(now.subsec_nanos()));
|
||||
sha.input(&byte_utils::be64_to_array(now.as_secs()));
|
||||
let mut sha = self.unique_start.clone();
|
||||
|
||||
let child_ix = self.channel_id_child_index.fetch_add(1, Ordering::AcqRel);
|
||||
let child_privkey = self.channel_id_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
extern crate bitcoin;
|
||||
extern crate bitcoin_hashes;
|
||||
extern crate rand;
|
||||
extern crate secp256k1;
|
||||
#[cfg(test)] extern crate rand;
|
||||
#[cfg(test)] extern crate hex;
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -36,7 +36,7 @@ use ln::onion_utils;
|
|||
use ln::msgs::{ChannelMessageHandler, DecodeError, HandleError};
|
||||
use chain::keysinterface::KeysInterface;
|
||||
use util::config::UserConfig;
|
||||
use util::{byte_utils, events, rng};
|
||||
use util::{byte_utils, events};
|
||||
use util::ser::{Readable, ReadableArgs, Writeable, Writer};
|
||||
use util::chacha20::ChaCha20;
|
||||
use util::logger::Logger;
|
||||
|
@ -214,11 +214,11 @@ impl MsgHandleErrInternal {
|
|||
}
|
||||
}
|
||||
|
||||
/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
|
||||
/// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
|
||||
/// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
|
||||
/// probably increase this significantly.
|
||||
const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u32 = 50;
|
||||
/// We hold back HTLCs we intend to relay for a random interval greater than this (see
|
||||
/// Event::PendingHTLCsForwardable for the API guidelines indicating how long should be waited).
|
||||
/// This provides some limited amount of privacy. Ideally this would range from somewhere like one
|
||||
/// second to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly.
|
||||
const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u64 = 100;
|
||||
|
||||
pub(super) enum HTLCForwardInfo {
|
||||
AddHTLC {
|
||||
|
@ -1486,7 +1486,7 @@ impl ChannelManager {
|
|||
|
||||
let mut forward_event = None;
|
||||
if channel_state_lock.forward_htlcs.is_empty() {
|
||||
forward_event = Some(Duration::from_millis(((rng::rand_f32() * 4.0 + 1.0) * MIN_HTLC_RELAY_HOLDING_CELL_MILLIS as f32) as u64));
|
||||
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS));
|
||||
}
|
||||
match channel_state_lock.forward_htlcs.entry(short_channel_id) {
|
||||
hash_map::Entry::Occupied(mut entry) => {
|
||||
|
@ -2095,7 +2095,7 @@ impl ChannelManager {
|
|||
if !pending_forwards.is_empty() {
|
||||
let mut channel_state = self.channel_state.lock().unwrap();
|
||||
if channel_state.forward_htlcs.is_empty() {
|
||||
forward_event = Some(Duration::from_millis(((rng::rand_f32() * 4.0 + 1.0) * MIN_HTLC_RELAY_HOLDING_CELL_MILLIS as f32) as u64));
|
||||
forward_event = Some(Duration::from_millis(MIN_HTLC_RELAY_HOLDING_CELL_MILLIS))
|
||||
}
|
||||
for (forward_info, prev_htlc_id) in pending_forwards.drain(..) {
|
||||
match channel_state.forward_htlcs.entry(forward_info.short_channel_id) {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
use chain::transaction::OutPoint;
|
||||
use chain::chaininterface::{ChainListener, ChainWatchInterface};
|
||||
use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor};
|
||||
use chain::keysinterface;
|
||||
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC, BREAKDOWN_TIMEOUT};
|
||||
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash};
|
||||
use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ManyChannelMonitor, ANTI_REORG_DELAY};
|
||||
|
@ -19,7 +18,6 @@ use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsPro
|
|||
use util::errors::APIError;
|
||||
use util::ser::{Writeable, ReadableArgs};
|
||||
use util::config::UserConfig;
|
||||
use util::rng;
|
||||
|
||||
use bitcoin::util::hash::BitcoinHash;
|
||||
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
|
||||
|
@ -45,6 +43,8 @@ use std::sync::Arc;
|
|||
use std::sync::atomic::Ordering;
|
||||
use std::mem;
|
||||
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use ln::functional_test_utils::*;
|
||||
|
||||
#[test]
|
||||
|
@ -1192,7 +1192,6 @@ fn duplicate_htlc_test() {
|
|||
}
|
||||
|
||||
fn do_channel_reserve_test(test_recv: bool) {
|
||||
use util::rng;
|
||||
use std::sync::atomic::Ordering;
|
||||
use ln::msgs::HandleError;
|
||||
|
||||
|
@ -1309,7 +1308,8 @@ fn do_channel_reserve_test(test_recv: bool) {
|
|||
let secp_ctx = Secp256k1::new();
|
||||
let session_priv = SecretKey::from_slice(&{
|
||||
let mut session_key = [0; 32];
|
||||
rng::fill_bytes(&mut session_key);
|
||||
let mut rng = thread_rng();
|
||||
rng.fill_bytes(&mut session_key);
|
||||
session_key
|
||||
}).expect("RNG is bad!");
|
||||
|
||||
|
@ -3225,7 +3225,7 @@ fn test_no_txn_manager_serialize_deserialize() {
|
|||
|
||||
let mut nodes_0_read = &nodes_0_serialized[..];
|
||||
let config = UserConfig::new();
|
||||
let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let (_, nodes_0_deserialized) = {
|
||||
let mut channel_monitors = HashMap::new();
|
||||
channel_monitors.insert(chan_0_monitor.get_funding_txo().unwrap(), &chan_0_monitor);
|
||||
|
@ -3290,7 +3290,7 @@ fn test_simple_manager_serialize_deserialize() {
|
|||
assert!(chan_0_monitor_read.is_empty());
|
||||
|
||||
let mut nodes_0_read = &nodes_0_serialized[..];
|
||||
let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let (_, nodes_0_deserialized) = {
|
||||
let mut channel_monitors = HashMap::new();
|
||||
channel_monitors.insert(chan_0_monitor.get_funding_txo().unwrap(), &chan_0_monitor);
|
||||
|
@ -3354,7 +3354,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
|
|||
}
|
||||
|
||||
let mut nodes_0_read = &nodes_0_serialized[..];
|
||||
let keys_manager = Arc::new(keysinterface::KeysManager::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::new(test_utils::TestLogger::new())));
|
||||
let (_, nodes_0_deserialized) = <(Sha256dHash, ChannelManager)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
|
||||
default_config: UserConfig::new(),
|
||||
keys_manager,
|
||||
|
@ -5083,7 +5083,8 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
|
|||
|
||||
let session_priv = SecretKey::from_slice(&{
|
||||
let mut session_key = [0; 32];
|
||||
rng::fill_bytes(&mut session_key);
|
||||
let mut rng = thread_rng();
|
||||
rng.fill_bytes(&mut session_key);
|
||||
session_key
|
||||
}).expect("RNG is bad!");
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use secp256k1::ecdh::SharedSecret;
|
|||
use secp256k1;
|
||||
|
||||
use util::chacha20poly1305rfc::ChaCha20Poly1305RFC;
|
||||
use util::{byte_utils,rng};
|
||||
use util::byte_utils;
|
||||
|
||||
// Sha256("Noise_XK_secp256k1_ChaChaPoly_SHA256")
|
||||
const NOISE_CK: [u8; 32] = [0x26, 0x40, 0xf5, 0x2e, 0xeb, 0xcd, 0x9e, 0x88, 0x29, 0x58, 0x95, 0x1c, 0x79, 0x42, 0x50, 0xee, 0xdb, 0x28, 0x00, 0x2c, 0x05, 0xd7, 0xdc, 0x2e, 0xa0, 0xf1, 0x95, 0x40, 0x60, 0x42, 0xca, 0xf1];
|
||||
|
@ -70,12 +70,8 @@ pub struct PeerChannelEncryptor {
|
|||
}
|
||||
|
||||
impl PeerChannelEncryptor {
|
||||
pub fn new_outbound(their_node_id: PublicKey) -> PeerChannelEncryptor {
|
||||
let mut key = [0u8; 32];
|
||||
rng::fill_bytes(&mut key);
|
||||
|
||||
pub fn new_outbound(their_node_id: PublicKey, ephemeral_key: SecretKey) -> PeerChannelEncryptor {
|
||||
let secp_ctx = Secp256k1::signing_only();
|
||||
let sec_key = SecretKey::from_slice(&key).unwrap(); //TODO: nicer rng-is-bad error message
|
||||
|
||||
let mut sha = Sha256::engine();
|
||||
sha.input(&NOISE_H);
|
||||
|
@ -88,7 +84,7 @@ impl PeerChannelEncryptor {
|
|||
noise_state: NoiseState::InProgress {
|
||||
state: NoiseStep::PreActOne,
|
||||
directional_state: DirectionalNoiseState::Outbound {
|
||||
ie: sec_key,
|
||||
ie: ephemeral_key,
|
||||
},
|
||||
bidirectional_state: BidirectionalNoiseState {
|
||||
h: h,
|
||||
|
@ -243,8 +239,7 @@ impl PeerChannelEncryptor {
|
|||
}
|
||||
}
|
||||
|
||||
// Separated for testing:
|
||||
fn process_act_one_with_ephemeral_key(&mut self, act_one: &[u8], our_node_secret: &SecretKey, our_ephemeral: SecretKey) -> Result<[u8; 50], HandleError> {
|
||||
pub fn process_act_one_with_keys(&mut self, act_one: &[u8], our_node_secret: &SecretKey, our_ephemeral: SecretKey) -> Result<[u8; 50], HandleError> {
|
||||
assert_eq!(act_one.len(), 50);
|
||||
|
||||
match self.noise_state {
|
||||
|
@ -271,15 +266,6 @@ impl PeerChannelEncryptor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn process_act_one_with_key(&mut self, act_one: &[u8], our_node_secret: &SecretKey) -> Result<[u8; 50], HandleError> {
|
||||
assert_eq!(act_one.len(), 50);
|
||||
|
||||
let mut key = [0u8; 32];
|
||||
rng::fill_bytes(&mut key);
|
||||
let our_ephemeral_key = SecretKey::from_slice(&key).unwrap(); //TODO: nicer rng-is-bad error message
|
||||
self.process_act_one_with_ephemeral_key(act_one, our_node_secret, our_ephemeral_key)
|
||||
}
|
||||
|
||||
pub fn process_act_two(&mut self, act_two: &[u8], our_node_secret: &SecretKey) -> Result<([u8; 66], PublicKey), HandleError> {
|
||||
assert_eq!(act_two.len(), 50);
|
||||
|
||||
|
@ -485,21 +471,12 @@ mod tests {
|
|||
|
||||
use hex;
|
||||
|
||||
use ln::peer_channel_encryptor::{PeerChannelEncryptor,NoiseState,DirectionalNoiseState};
|
||||
use ln::peer_channel_encryptor::{PeerChannelEncryptor,NoiseState};
|
||||
|
||||
fn get_outbound_peer_for_initiator_test_vectors() -> PeerChannelEncryptor {
|
||||
let their_node_id = PublicKey::from_slice(&hex::decode("028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7").unwrap()[..]).unwrap();
|
||||
|
||||
let mut outbound_peer = PeerChannelEncryptor::new_outbound(their_node_id);
|
||||
match outbound_peer.noise_state {
|
||||
NoiseState::InProgress { state: _, ref mut directional_state, bidirectional_state: _ } => {
|
||||
*directional_state = DirectionalNoiseState::Outbound { // overwrite ie...
|
||||
ie: SecretKey::from_slice(&hex::decode("1212121212121212121212121212121212121212121212121212121212121212").unwrap()[..]).unwrap(),
|
||||
};
|
||||
},
|
||||
_ => panic!()
|
||||
}
|
||||
|
||||
let mut outbound_peer = PeerChannelEncryptor::new_outbound(their_node_id, SecretKey::from_slice(&hex::decode("1212121212121212121212121212121212121212121212121212121212121212").unwrap()[..]).unwrap());
|
||||
assert_eq!(outbound_peer.get_act_one()[..], hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap()[..]);
|
||||
outbound_peer
|
||||
}
|
||||
|
@ -566,7 +543,7 @@ mod tests {
|
|||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
// test vector doesn't specify the initiator static key, but it's the same as the one
|
||||
|
@ -594,28 +571,28 @@ mod tests {
|
|||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("01036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act1 bad key serialization test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one =hex::decode("00046360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act1 bad MAC test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6b").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
assert!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).is_err());
|
||||
}
|
||||
{
|
||||
// transport-responder act3 bad version test
|
||||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("01b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
|
@ -629,7 +606,7 @@ mod tests {
|
|||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00c9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
|
@ -639,7 +616,7 @@ mod tests {
|
|||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00bfe3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa2235536ad09a8ee351870c2bb7f78b754a26c6cef79a98d25139c856d7efd252c2ae73c").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
|
@ -649,7 +626,7 @@ mod tests {
|
|||
let mut inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139bb").unwrap().to_vec();
|
||||
assert!(inbound_peer.process_act_three(&act_three[..]).is_err());
|
||||
|
@ -692,7 +669,7 @@ mod tests {
|
|||
inbound_peer = PeerChannelEncryptor::new_inbound(&our_node_id);
|
||||
|
||||
let act_one = hex::decode("00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a").unwrap().to_vec();
|
||||
assert_eq!(inbound_peer.process_act_one_with_ephemeral_key(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
assert_eq!(inbound_peer.process_act_one_with_keys(&act_one[..], &our_node_id, our_ephemeral.clone()).unwrap()[..], hex::decode("0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae").unwrap()[..]);
|
||||
|
||||
let act_three = hex::decode("00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba").unwrap().to_vec();
|
||||
// test vector doesn't specify the initiator static key, but it's the same as the one
|
||||
|
|
|
@ -20,6 +20,10 @@ use std::sync::{Arc, Mutex};
|
|||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::{cmp,error,hash,fmt};
|
||||
|
||||
use bitcoin_hashes::sha256::Hash as Sha256;
|
||||
use bitcoin_hashes::sha256::HashEngine as Sha256Engine;
|
||||
use bitcoin_hashes::{HashEngine, Hash};
|
||||
|
||||
/// Provides references to trait impls which handle different types of messages.
|
||||
pub struct MessageHandler {
|
||||
/// A message handler which handles messages specific to channels. Usually this is just a
|
||||
|
@ -151,12 +155,25 @@ impl<Descriptor: SocketDescriptor> PeerHolder<Descriptor> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
|
||||
fn _check_usize_is_32_or_64() {
|
||||
// See below, less than 32 bit pointers may be unsafe here!
|
||||
unsafe { mem::transmute::<*const usize, [u8; 4]>(panic!()); }
|
||||
}
|
||||
|
||||
/// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket
|
||||
/// events into messages which it passes on to its MessageHandlers.
|
||||
pub struct PeerManager<Descriptor: SocketDescriptor> {
|
||||
message_handler: MessageHandler,
|
||||
peers: Mutex<PeerHolder<Descriptor>>,
|
||||
our_node_secret: SecretKey,
|
||||
ephemeral_key_midstate: Sha256Engine,
|
||||
|
||||
// Usize needs to be at least 32 bits to avoid overflowing both low and high. If usize is 64
|
||||
// bits we will never realistically count into high:
|
||||
peer_counter_low: AtomicUsize,
|
||||
peer_counter_high: AtomicUsize,
|
||||
|
||||
initial_syncs_sent: AtomicUsize,
|
||||
logger: Arc<Logger>,
|
||||
}
|
||||
|
@ -188,7 +205,12 @@ const INITIAL_SYNCS_TO_SEND: usize = 5;
|
|||
/// PeerIds may repeat, but only after disconnect_event() has been called.
|
||||
impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
|
||||
/// Constructs a new PeerManager with the given message handlers and node_id secret key
|
||||
pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, logger: Arc<Logger>) -> PeerManager<Descriptor> {
|
||||
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
|
||||
/// cryptographically secure random bytes.
|
||||
pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: Arc<Logger>) -> PeerManager<Descriptor> {
|
||||
let mut ephemeral_key_midstate = Sha256::engine();
|
||||
ephemeral_key_midstate.input(ephemeral_random_data);
|
||||
|
||||
PeerManager {
|
||||
message_handler: message_handler,
|
||||
peers: Mutex::new(PeerHolder {
|
||||
|
@ -197,6 +219,9 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
|
|||
node_id_to_descriptor: HashMap::new()
|
||||
}),
|
||||
our_node_secret: our_node_secret,
|
||||
ephemeral_key_midstate,
|
||||
peer_counter_low: AtomicUsize::new(0),
|
||||
peer_counter_high: AtomicUsize::new(0),
|
||||
initial_syncs_sent: AtomicUsize::new(0),
|
||||
logger,
|
||||
}
|
||||
|
@ -217,6 +242,19 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
|
|||
}).collect()
|
||||
}
|
||||
|
||||
fn get_ephemeral_key(&self) -> SecretKey {
|
||||
let mut ephemeral_hash = self.ephemeral_key_midstate.clone();
|
||||
let low = self.peer_counter_low.fetch_add(1, Ordering::AcqRel);
|
||||
let high = if low == 0 {
|
||||
self.peer_counter_high.fetch_add(1, Ordering::AcqRel)
|
||||
} else {
|
||||
self.peer_counter_high.load(Ordering::Acquire)
|
||||
};
|
||||
ephemeral_hash.input(&byte_utils::le64_to_array(low as u64));
|
||||
ephemeral_hash.input(&byte_utils::le64_to_array(high as u64));
|
||||
SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!")
|
||||
}
|
||||
|
||||
/// Indicates a new outbound connection has been established to a node with the given node_id.
|
||||
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
|
||||
/// descriptor but must disconnect the connection immediately.
|
||||
|
@ -226,7 +264,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
|
|||
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
|
||||
/// disconnect_event.
|
||||
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
|
||||
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone());
|
||||
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
|
||||
let res = peer_encryptor.get_act_one().to_vec();
|
||||
let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes
|
||||
|
||||
|
@ -517,7 +555,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
|
|||
let next_step = peer.channel_encryptor.get_noise_step();
|
||||
match next_step {
|
||||
NextNoiseStep::ActOne => {
|
||||
let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_key(&peer.pending_read_buffer[..], &self.our_node_secret)).to_vec();
|
||||
let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_keys(&peer.pending_read_buffer[..], &self.our_node_secret, self.get_ephemeral_key())).to_vec();
|
||||
peer.pending_outbound_buffer.push_back(act_two);
|
||||
peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long
|
||||
},
|
||||
|
@ -1096,6 +1134,8 @@ mod tests {
|
|||
let mut peers = Vec::new();
|
||||
let mut rng = thread_rng();
|
||||
let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());
|
||||
let mut ephemeral_bytes = [0; 32];
|
||||
rng.fill_bytes(&mut ephemeral_bytes);
|
||||
|
||||
for _ in 0..peer_count {
|
||||
let chan_handler = test_utils::TestChannelMessageHandler::new();
|
||||
|
@ -1106,7 +1146,7 @@ mod tests {
|
|||
SecretKey::from_slice(&key_slice).unwrap()
|
||||
};
|
||||
let msg_handler = MessageHandler { chan_handler: Arc::new(chan_handler), route_handler: Arc::new(router) };
|
||||
let peer = PeerManager::new(msg_handler, node_id, Arc::clone(&logger));
|
||||
let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, Arc::clone(&logger));
|
||||
peers.push(peer);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,10 @@ pub enum Event {
|
|||
/// Used to indicate that ChannelManager::process_pending_htlc_forwards should be called at a
|
||||
/// time in the future.
|
||||
PendingHTLCsForwardable {
|
||||
/// The amount of time that should be waited prior to calling process_pending_htlc_forwards
|
||||
/// The minimum amount of time that should be waited prior to calling
|
||||
/// process_pending_htlc_forwards. To increase the effort required to correlate payments,
|
||||
/// you should wait a random amount of time in roughly the range (now + time_forwardable,
|
||||
/// now + 5*time_forwardable).
|
||||
time_forwardable: Duration,
|
||||
},
|
||||
/// Used to indicate that an output was generated on-chain which you should know how to spend.
|
||||
|
|
|
@ -10,7 +10,6 @@ pub(crate) mod chacha20;
|
|||
pub(crate) mod poly1305;
|
||||
pub(crate) mod chacha20poly1305rfc;
|
||||
pub(crate) mod internal_traits;
|
||||
pub(crate) mod rng;
|
||||
pub(crate) mod transaction_utils;
|
||||
|
||||
#[macro_use]
|
||||
|
@ -22,9 +21,6 @@ pub(crate) mod macro_logger;
|
|||
pub mod logger;
|
||||
pub mod config;
|
||||
|
||||
#[cfg(feature = "fuzztarget")]
|
||||
pub use self::rng::{reset_rng_state, fill_bytes};
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_utils;
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
#[cfg(not(feature = "fuzztarget"))]
|
||||
mod real_rng {
|
||||
use rand::{thread_rng,Rng};
|
||||
|
||||
pub fn fill_bytes(data: &mut [u8]) {
|
||||
let mut rng = thread_rng();
|
||||
rng.fill_bytes(data);
|
||||
}
|
||||
|
||||
pub fn rand_f32() -> f32 {
|
||||
let mut rng = thread_rng();
|
||||
rng.next_f32()
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "fuzztarget"))]
|
||||
pub use self::real_rng::*;
|
||||
|
||||
#[cfg(feature = "fuzztarget")]
|
||||
mod fuzzy_rng {
|
||||
use util::byte_utils;
|
||||
|
||||
static mut RNG_ITER: u64 = 0;
|
||||
|
||||
pub fn fill_bytes(data: &mut [u8]) {
|
||||
let rng = unsafe { RNG_ITER += 1; RNG_ITER -1 };
|
||||
for i in 0..data.len() / 8 {
|
||||
data[i*8..(i+1)*8].copy_from_slice(&byte_utils::be64_to_array(rng));
|
||||
}
|
||||
let rem = data.len() % 8;
|
||||
let off = data.len() - rem;
|
||||
data[off..].copy_from_slice(&byte_utils::be64_to_array(rng)[0..rem]);
|
||||
}
|
||||
|
||||
pub fn rand_f32() -> f32 {
|
||||
let rng = unsafe { RNG_ITER += 1; RNG_ITER - 1 };
|
||||
f64::from_bits(rng) as f32
|
||||
}
|
||||
|
||||
pub fn reset_rng_state() {
|
||||
unsafe { RNG_ITER = 0; }
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "fuzztarget")]
|
||||
pub use self::fuzzy_rng::*;
|
|
@ -18,6 +18,7 @@ use bitcoin::network::constants::Network;
|
|||
|
||||
use secp256k1::{SecretKey, PublicKey};
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::sync::{Arc,Mutex};
|
||||
use std::{mem};
|
||||
|
||||
|
@ -242,8 +243,9 @@ impl keysinterface::KeysInterface for TestKeysInterface {
|
|||
|
||||
impl TestKeysInterface {
|
||||
pub fn new(seed: &[u8; 32], network: Network, logger: Arc<Logger>) -> Self {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
|
||||
Self {
|
||||
backing: keysinterface::KeysManager::new(seed, network, logger),
|
||||
backing: keysinterface::KeysManager::new(seed, network, logger, now.as_secs(), now.subsec_nanos()),
|
||||
override_session_priv: Mutex::new(None),
|
||||
override_channel_id_priv: Mutex::new(None),
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue