Add annotations for things which we cannot (yet) expose
[rust-lightning] / lightning / src / chain / keysinterface.rs
index fbc6c9bc6e6c673ca4d8f2555bd41d630b312cd7..3c115bc770bf24ab8fe12cd7947cfddc42edb8d0 100644 (file)
@@ -11,7 +11,7 @@
 //! spendable on-chain outputs which the user owns and is responsible for using just as any other
 //! on-chain output which is theirs.
 
-use bitcoin::blockdata::transaction::{Transaction, OutPoint, TxOut};
+use bitcoin::blockdata::transaction::{Transaction, TxOut, SigHashType};
 use bitcoin::blockdata::script::{Script, Builder};
 use bitcoin::blockdata::opcodes;
 use bitcoin::network::constants::Network;
@@ -31,9 +31,10 @@ use bitcoin::secp256k1;
 use util::byte_utils;
 use util::ser::{Writeable, Writer, Readable};
 
+use chain::transaction::OutPoint;
 use ln::chan_utils;
 use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
-use ln::msgs;
+use ln::msgs::UnsignedChannelAnnouncement;
 
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::io::Error;
@@ -316,7 +317,7 @@ pub trait ChannelKeys : Send+Clone {
        /// Note that if this fails or is rejected, the channel will not be publicly announced and
        /// our counterparty may (though likely will not) close the channel on us for violating the
        /// protocol.
-       fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
+       fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
 
        /// Set the remote channel basepoints and remote/local to_self_delay.
        /// This is done immediately on incoming channels and as soon as the channel is accepted on outgoing channels.
@@ -341,12 +342,10 @@ pub trait KeysInterface: Send + Sync {
        /// 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, channel_value_satoshis: u64) -> Self::ChanKeySigner;
-       /// Get a secret and PRNG seed for constructing an onion packet
-       fn get_onion_rand(&self) -> (SecretKey, [u8; 32]);
-       /// Get a unique temporary channel id. Channels will be referred to by this until the funding
-       /// transaction is created, at which point they will use the outpoint in the funding
-       /// transaction.
-       fn get_channel_id(&self) -> [u8; 32];
+       /// Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting
+       /// onion packets and for temporary channel IDs. There is no requirement that these be
+       /// persisted anywhere, though they must be unique across restarts.
+       fn get_secure_random_bytes(&self) -> [u8; 32];
 }
 
 #[derive(Clone)]
@@ -478,7 +477,7 @@ impl ChannelKeys for InMemoryChannelKeys {
                let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
                let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &accepted_data.remote_channel_pubkeys.funding_pubkey);
 
-               let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
+               let commitment_sighash = hash_to_message!(&bip143::SigHashCache::new(commitment_tx).signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
                let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key);
 
                let commitment_txid = commitment_tx.txid();
@@ -488,7 +487,7 @@ impl ChannelKeys for InMemoryChannelKeys {
                        if let Some(_) = htlc.transaction_output_index {
                                let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, feerate_per_kw, accepted_data.local_to_self_delay, htlc, &keys.a_delayed_payment_key, &keys.revocation_key);
                                let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
-                               let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
+                               let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
                                let our_htlc_key = match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) {
                                        Ok(s) => s,
                                        Err(_) => return Err(()),
@@ -549,8 +548,8 @@ impl ChannelKeys for InMemoryChannelKeys {
                        };
                        chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.local_to_self_delay(), &remote_delayedpubkey)
                };
-               let sighash_parts = bip143::SighashComponents::new(&justice_tx);
-               let sighash = hash_to_message!(&sighash_parts.sighash_all(&justice_tx.input[input], &witness_script, amount)[..]);
+               let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
+               let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
                return Ok(secp_ctx.sign(&sighash, &revocation_key))
        }
 
@@ -563,8 +562,8 @@ impl ChannelKeys for InMemoryChannelKeys {
                                        } else { return Err(()) }
                                } else { return Err(()) }
                        } else { return Err(()) };
-                       let sighash_parts = bip143::SighashComponents::new(&htlc_tx);
-                       let sighash = hash_to_message!(&sighash_parts.sighash_all(&htlc_tx.input[input], &witness_script, amount)[..]);
+                       let mut sighash_parts = bip143::SigHashCache::new(htlc_tx);
+                       let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
                        return Ok(secp_ctx.sign(&sighash, &htlc_key))
                }
                Err(())
@@ -579,12 +578,12 @@ impl ChannelKeys for InMemoryChannelKeys {
                let remote_channel_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
                let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_data.remote_channel_pubkeys.funding_pubkey);
 
-               let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx)
-                       .sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
+               let sighash = hash_to_message!(&bip143::SigHashCache::new(closing_tx)
+                       .signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
                Ok(secp_ctx.sign(&sighash, &self.funding_key))
        }
 
-       fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
+       fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
                Ok(secp_ctx.sign(&msghash, &self.funding_key))
        }
@@ -666,10 +665,8 @@ pub struct KeysManager {
        shutdown_pubkey: PublicKey,
        channel_master_key: ExtendedPrivKey,
        channel_child_index: AtomicUsize,
-       session_master_key: ExtendedPrivKey,
-       session_child_index: AtomicUsize,
-       channel_id_master_key: ExtendedPrivKey,
-       channel_id_child_index: AtomicUsize,
+       rand_bytes_master_key: ExtendedPrivKey,
+       rand_bytes_child_index: AtomicUsize,
 
        seed: [u8; 32],
        starting_time_secs: u64,
@@ -678,7 +675,7 @@ pub struct KeysManager {
 
 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 (but more importantly, you will possibly lose funds).
+       /// CSRNG 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
@@ -715,8 +712,7 @@ impl KeysManager {
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                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 rand_bytes_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4).unwrap()).expect("Your RNG is busted");
 
                                KeysManager {
                                        secp_ctx,
@@ -725,10 +721,8 @@ impl KeysManager {
                                        shutdown_pubkey,
                                        channel_master_key,
                                        channel_child_index: AtomicUsize::new(0),
-                                       session_master_key,
-                                       session_child_index: AtomicUsize::new(0),
-                                       channel_id_master_key,
-                                       channel_id_child_index: AtomicUsize::new(0),
+                                       rand_bytes_master_key,
+                                       rand_bytes_child_index: AtomicUsize::new(0),
 
                                        seed: *seed,
                                        starting_time_secs,
@@ -815,35 +809,20 @@ impl KeysInterface for KeysManager {
                self.shutdown_pubkey.clone()
        }
 
-       fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> InMemoryChannelKeys {
+       fn get_channel_keys(&self, _inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner {
                let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
                let ix_and_nanos: u64 = (child_ix as u64) << 32 | (self.starting_time_nanos as u64);
                self.derive_channel_keys(channel_value_satoshis, ix_and_nanos, self.starting_time_secs)
        }
 
-       fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) {
+       fn get_secure_random_bytes(&self) -> [u8; 32] {
                let mut sha = self.derive_unique_start();
 
-               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");
-               sha.input(&child_privkey.private_key.key[..]);
-
-               let mut rng_seed = sha.clone();
-               // Not exactly the most ideal construction, but the second value will get fed into
-               // ChaCha so it is another step harder to break.
-               rng_seed.input(b"RNG Seed Salt");
-               sha.input(b"Session Key Salt");
-               (SecretKey::from_slice(&Sha256::from_engine(sha).into_inner()).expect("Your RNG is busted"),
-               Sha256::from_engine(rng_seed).into_inner())
-       }
-
-       fn get_channel_id(&self) -> [u8; 32] {
-               let mut sha = self.derive_unique_start();
-
-               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");
+               let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
+               let child_privkey = self.rand_bytes_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[..]);
 
+               sha.input(b"Unique Secure Random Bytes Salt");
                Sha256::from_engine(sha).into_inner()
        }
 }