From: Antoine Riard Date: Fri, 26 Oct 2018 15:15:55 +0000 (-0400) Subject: Add a KeysInterface which provides keys from user X-Git-Tag: v0.0.12~286^2~4 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=d33cb3cca560ec33b33542c1ef6e47f15b35e30a;p=rust-lightning Add a KeysInterface which provides keys from user Move ChannelKeys into keysinterface for generate a set of it from master_seed and change return type to panic on bogus data --- diff --git a/src/chain/keysinterface.rs b/src/chain/keysinterface.rs index bab21fd2..568b91e8 100644 --- a/src/chain/keysinterface.rs +++ b/src/chain/keysinterface.rs @@ -5,7 +5,12 @@ use bitcoin::blockdata::transaction::{OutPoint, TxOut}; use bitcoin::blockdata::script::Script; -use secp256k1::key::SecretKey; +use secp256k1::key::{SecretKey, PublicKey}; +use secp256k1::Secp256k1; + +use crypto::hkdf::{hkdf_extract,hkdf_expand}; + +use util::sha2::Sha256; /// When on-chain outputs are created by rust-lightning an event is generated which informs the /// user thereof. This enum describes the format of the output and provides the OutPoint. @@ -34,3 +39,81 @@ pub enum SpendableOutputDescriptor { to_self_delay: u16, } } + +/// A trait to describe an object which can get user secrets and key material. +pub trait KeysInterface: Send + Sync { + /// Get node secret key (aka node_id or network_key) + fn get_node_secret(&self) -> SecretKey; + /// Get destination redeemScript to encumber static protocol exit points. + fn get_destination_script(&self) -> Script; + /// Get shutdown_pubkey to use as PublicKey at channel closure + fn get_shutdown_pubkey(&self) -> PublicKey; + /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you + /// restarted with some stale data! + fn get_channel_keys(&self, inbound: bool) -> ChannelKeys; +} + +/// Set of lightning keys needed to operate a channel as described in BOLT 3 +pub struct ChannelKeys { + /// Private key of anchor tx + pub funding_key: SecretKey, + /// Local secret key for blinded revocation pubkey + pub revocation_base_key: SecretKey, + /// Local secret key used in commitment tx htlc outputs + pub payment_base_key: SecretKey, + /// Local secret key used in HTLC tx + pub delayed_payment_base_key: SecretKey, + /// Local htlc secret key used in commitment tx htlc outputs + pub htlc_base_key: SecretKey, + /// Local secret key used for closing tx + pub channel_close_key: SecretKey, + /// Local secret key used in justice tx, claim tx and preimage tx outputs + pub channel_monitor_claim_key: SecretKey, + /// Commitment seed + pub commitment_seed: [u8; 32], +} + +impl ChannelKeys { + /// Generate a set of lightning keys needed to operate a channel by HKDF-expanding a given + /// random 32-byte seed + pub fn new_from_seed(seed: &[u8; 32]) -> ChannelKeys { + let mut prk = [0; 32]; + hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk); + let secp_ctx = Secp256k1::without_caps(); + + let mut okm = [0; 32]; + hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm); + let funding_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm); + let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm); + let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm); + let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); + let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); + let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); + let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm).expect("Sha256 is broken"); + + hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); + + ChannelKeys { + funding_key: funding_key, + revocation_base_key: revocation_base_key, + payment_base_key: payment_base_key, + delayed_payment_base_key: delayed_payment_base_key, + htlc_base_key: htlc_base_key, + channel_close_key: channel_close_key, + channel_monitor_claim_key: channel_monitor_claim_key, + commitment_seed: okm + } + } +} diff --git a/src/ln/channel.rs b/src/ln/channel.rs index e8d7f538..8f73ab59 100644 --- a/src/ln/channel.rs +++ b/src/ln/channel.rs @@ -11,7 +11,6 @@ use secp256k1::{Secp256k1,Message,Signature}; use secp256k1; use crypto::digest::Digest; -use crypto::hkdf::{hkdf_extract,hkdf_expand}; use ln::msgs; use ln::msgs::{ErrorAction, HandleError, RAACommitmentOrder}; @@ -21,6 +20,7 @@ use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGH use ln::chan_utils; use chain::chaininterface::{FeeEstimator,ConfirmationTarget}; use chain::transaction::OutPoint; +use chain::keysinterface::ChannelKeys; use util::{transaction_utils,rng}; use util::ser::Writeable; use util::sha2::Sha256; @@ -33,17 +33,6 @@ use std::{cmp,mem}; use std::time::Instant; use std::sync::{Arc}; -pub struct ChannelKeys { - pub funding_key: SecretKey, - pub revocation_base_key: SecretKey, - pub payment_base_key: SecretKey, - pub delayed_payment_base_key: SecretKey, - pub htlc_base_key: SecretKey, - pub channel_close_key: SecretKey, - pub channel_monitor_claim_key: SecretKey, - pub commitment_seed: [u8; 32], -} - #[cfg(test)] pub struct ChannelValueStat { pub value_to_self_msat: u64, @@ -55,49 +44,6 @@ pub struct ChannelValueStat { pub their_max_htlc_value_in_flight_msat: u64, // outgoing } -impl ChannelKeys { - pub fn new_from_seed(seed: &[u8; 32]) -> Result { - let mut prk = [0; 32]; - hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk); - let secp_ctx = Secp256k1::without_caps(); - - let mut okm = [0; 32]; - hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm); - let funding_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm); - let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm); - let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm); - let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm); - let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm); - let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm); - let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm)?; - - hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm); - - Ok(ChannelKeys { - funding_key: funding_key, - revocation_base_key: revocation_base_key, - payment_base_key: payment_base_key, - delayed_payment_base_key: delayed_payment_base_key, - htlc_base_key: htlc_base_key, - channel_close_key: channel_close_key, - channel_monitor_claim_key: channel_monitor_claim_key, - commitment_seed: okm - }) - } -} - enum InboundHTLCRemovalReason { FailRelay(msgs::OnionErrorPacket), FailMalformed(([u8; 32], u16)), diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 7e736ba1..badde7f6 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -22,11 +22,12 @@ use secp256k1; use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator}; use chain::transaction::OutPoint; -use ln::channel::{Channel, ChannelError, ChannelKeys}; +use ln::channel::{Channel, ChannelError}; use ln::channelmonitor::{ChannelMonitorUpdateErr, ManyChannelMonitor, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS}; use ln::router::{Route,RouteHop}; use ln::msgs; use ln::msgs::{ChannelMessageHandler, HandleError, RAACommitmentOrder}; +use chain::keysinterface::ChannelKeys; use util::{byte_utils, events, internal_traits, rng}; use util::sha2::Sha256; use util::ser::{Readable, Writeable}; @@ -432,10 +433,7 @@ impl ChannelManager { } else { let mut key_seed = [0u8; 32]; rng::fill_bytes(&mut key_seed); - match ChannelKeys::new_from_seed(&key_seed) { - Ok(key) => key, - Err(_) => panic!("RNG is busted!") - } + ChannelKeys::new_from_seed(&key_seed) }; let channel = Channel::new_outbound(&*self.fee_estimator, chan_keys, their_network_key, channel_value_satoshis, push_msat, self.announce_channels_publicly, user_id, Arc::clone(&self.logger))?; @@ -1689,10 +1687,7 @@ impl ChannelManager { } else { let mut key_seed = [0u8; 32]; rng::fill_bytes(&mut key_seed); - match ChannelKeys::new_from_seed(&key_seed) { - Ok(key) => key, - Err(_) => panic!("RNG is busted!") - } + ChannelKeys::new_from_seed(&key_seed) }; let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger))