Skip to content

Commit ec1f334

Browse files
committed
Extend BaseSign with HTLC output signing support for external claims
1 parent 8170c84 commit ec1f334

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

lightning/src/chain/keysinterface.rs

+33-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
3434
use crate::util::transaction_utils;
3535
use crate::util::crypto::{hkdf_extract_expand_twice, sign};
3636
use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
37-
37+
#[cfg(anchors)]
38+
use crate::util::events::HTLCDescriptor;
3839
use crate::chain::transaction::OutPoint;
3940
use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
4041
use crate::ln::{chan_utils, PaymentPreimage};
@@ -325,6 +326,19 @@ pub trait BaseSign {
325326
/// (which is committed to in the BIP 143 signatures).
326327
fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
327328

329+
#[cfg(anchors)]
330+
/// Computes the signature for a commitment transaction's HTLC output used as an input within
331+
/// `htlc_tx`, which spends the commitment transaction, at index `input`. The signature returned
332+
/// must be be computed using [`EcdsaSighashType::All`]. Note that this should only be used to
333+
/// sign HTLC transactions from channels supporting anchor outputs after all additional
334+
/// inputs/outputs have been added to the transaction.
335+
///
336+
/// [`EcdsaSighashType::All`]: bitcoin::blockdata::transaction::EcdsaSighashType::All
337+
fn sign_holder_htlc_transaction(
338+
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
339+
secp_ctx: &Secp256k1<secp256k1::All>
340+
) -> Result<Signature, ()>;
341+
328342
/// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment
329343
/// transaction, either offered or received.
330344
///
@@ -682,7 +696,6 @@ impl InMemorySigner {
682696
witness.push(witness_script.clone().into_bytes());
683697
Ok(witness)
684698
}
685-
686699
}
687700

688701
impl BaseSign for InMemorySigner {
@@ -779,6 +792,24 @@ impl BaseSign for InMemorySigner {
779792
return Ok(sign(secp_ctx, &sighash, &revocation_key))
780793
}
781794

795+
#[cfg(anchors)]
796+
fn sign_holder_htlc_transaction(
797+
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
798+
secp_ctx: &Secp256k1<secp256k1::All>
799+
) -> Result<Signature, ()> {
800+
let per_commitment_point = self.get_per_commitment_point(
801+
htlc_descriptor.per_commitment_number, &secp_ctx
802+
);
803+
let witness_script = htlc_descriptor.witness_script(&per_commitment_point, secp_ctx);
804+
let sighash = &sighash::SighashCache::new(&*htlc_tx).segwit_signature_hash(
805+
input, &witness_script, htlc_descriptor.htlc.amount_msat / 1000, EcdsaSighashType::All
806+
).map_err(|_| ())?;
807+
let our_htlc_private_key = chan_utils::derive_private_key(
808+
&secp_ctx, &per_commitment_point, &self.htlc_base_key
809+
);
810+
Ok(sign(&secp_ctx, &hash_to_message!(sighash), &our_htlc_private_key))
811+
}
812+
782813
fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
783814
let htlc_key = chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &self.htlc_base_key);
784815
let revocation_pubkey = chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &self.pubkeys().revocation_basepoint);

lightning/src/util/enforcing_trait_impls.rs

+13
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use bitcoin::util::sighash;
2323
use bitcoin::secp256k1;
2424
use bitcoin::secp256k1::{SecretKey, PublicKey};
2525
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
26+
#[cfg(anchors)]
27+
use crate::util::events::HTLCDescriptor;
2628
use crate::util::ser::{Writeable, Writer};
2729
use crate::io::Error;
2830

@@ -190,6 +192,17 @@ impl BaseSign for EnforcingSigner {
190192
Ok(self.inner.sign_justice_revoked_htlc(justice_tx, input, amount, per_commitment_key, htlc, secp_ctx).unwrap())
191193
}
192194

195+
#[cfg(anchors)]
196+
fn sign_holder_htlc_transaction(
197+
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
198+
secp_ctx: &Secp256k1<secp256k1::All>
199+
) -> Result<Signature, ()> {
200+
let per_commitment_point = self.get_per_commitment_point(htlc_descriptor.per_commitment_number, secp_ctx);
201+
assert_eq!(htlc_tx.input[input], htlc_descriptor.unsigned_tx_input());
202+
assert_eq!(htlc_tx.output[input], htlc_descriptor.tx_output(&per_commitment_point, secp_ctx));
203+
Ok(self.inner.sign_holder_htlc_transaction(htlc_tx, input, htlc_descriptor, secp_ctx).unwrap())
204+
}
205+
193206
fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
194207
Ok(self.inner.sign_counterparty_htlc_transaction(htlc_tx, input, amount, per_commitment_point, htlc, secp_ctx).unwrap())
195208
}

0 commit comments

Comments
 (0)