From: Ken Sedgwick Date: Wed, 29 Dec 2021 04:37:20 +0000 (-0800) Subject: Set the SigHashType of remote htlc signatures w/ anchors to SinglePlusAnyoneCanPay X-Git-Tag: v0.0.105~40^2~9 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=8f09e5a7ff464109ca1d7de065f56635c17bd0ac;p=rust-lightning Set the SigHashType of remote htlc signatures w/ anchors to SinglePlusAnyoneCanPay --- diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 9e0cfb06e..a7965d4f3 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -612,7 +612,8 @@ impl BaseSign for InMemorySigner { for htlc in commitment_tx.htlcs() { let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys); - let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]); + let htlc_sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All }; + let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]); let holder_htlc_key = chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key).map_err(|_| ())?; htlc_sigs.push(secp_ctx.sign(&htlc_sighash, &holder_htlc_key)); } diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index cbafbed67..6e11dc42b 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -1394,6 +1394,8 @@ impl<'a> TrustedCommitmentTransaction<'a> { /// which HTLCOutputInCommitment::transaction_output_index.is_some()). /// /// The returned Vec has one entry for each HTLC, and in the same order. + /// + /// This function is only valid in the holder commitment context, it always uses SigHashType::All. pub fn get_htlc_sigs(&self, htlc_base_key: &SecretKey, channel_parameters: &DirectedChannelTransactionParameters, secp_ctx: &Secp256k1) -> Result, ()> { let inner = self.inner; let keys = &inner.keys; @@ -1429,12 +1431,14 @@ impl<'a> TrustedCommitmentTransaction<'a> { let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key); + let sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All }; + // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element. htlc_tx.input[0].witness.push(Vec::new()); htlc_tx.input[0].witness.push(counterparty_signature.serialize_der().to_vec()); htlc_tx.input[0].witness.push(signature.serialize_der().to_vec()); - htlc_tx.input[0].witness[1].push(SigHashType::All as u8); + htlc_tx.input[0].witness[1].push(sighashtype as u8); htlc_tx.input[0].witness[2].push(SigHashType::All as u8); if this_htlc.offered { diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index ca6c6781f..2f97f9a88 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -2625,7 +2625,8 @@ impl Channel { &keys.broadcaster_delayed_payment_key, &keys.revocation_key); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys); - let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]); + let htlc_sighashtype = if self.opt_anchors() { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All }; + let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]); log_trace!(logger, "Checking HTLC tx signature {} by key {} against tx {} (sighash {}) with redeemscript {} in channel {}.", log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(keys.countersignatory_htlc_key.serialize()), encode::serialize_hex(&htlc_tx), log_bytes!(htlc_sighash[..]), encode::serialize_hex(&htlc_redeemscript), log_bytes!(self.channel_id())); @@ -6288,7 +6289,8 @@ mod tests { chan.get_counterparty_selected_contest_delay().unwrap(), &htlc, opt_anchors, &keys.broadcaster_delayed_payment_key, &keys.revocation_key); let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, opt_anchors, &keys); - let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]).unwrap(); + let htlc_sighashtype = if opt_anchors { SigHashType::SinglePlusAnyoneCanPay } else { SigHashType::All }; + let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, htlc_sighashtype)[..]).unwrap(); secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key).unwrap(); let mut preimage: Option = None;