Skip to content

Commit af0b9a1

Browse files
committed
Introduce TaprootSigner trait.
For Taproot support, we need to define an alternative trait to EcdsaChannelSigner. This trait will be implemented by all signers that wish to support Taproot channels.
1 parent 19259e6 commit af0b9a1

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

lightning/src/sign/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ use crate::util::invoice::construct_invoice_preimage;
5757

5858
pub(crate) mod type_resolver;
5959

60+
#[cfg(taproot)]
61+
pub mod taproot;
62+
6063
/// Used as initial key material, to be expanded into multiple secret keys (but not to be used
6164
/// directly). This is used within LDK to encrypt/decrypt inbound payment data.
6265
///

lightning/src/sign/taproot.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//! Defines a Taproot-specific signer type.
2+
3+
use bitcoin::blockdata::transaction::Transaction;
4+
use bitcoin::secp256k1;
5+
use bitcoin::secp256k1::{PublicKey, schnorr::Signature, Secp256k1, SecretKey};
6+
7+
use musig2::types::{PartialSignature, PublicNonce};
8+
9+
use crate::ln::chan_utils::{ClosingTransaction, CommitmentTransaction, HolderCommitmentTransaction, HTLCOutputInCommitment};
10+
use crate::ln::msgs::PartialSignatureWithNonce;
11+
use crate::ln::PaymentPreimage;
12+
use crate::sign::{ChannelSigner, HTLCDescriptor};
13+
14+
/// A Taproot-specific signer type that defines signing-related methods that are either unique to
15+
/// Taproot or have argument or return types that differ from the ones an ECDSA signer would be
16+
/// expected to have.
17+
pub trait TaprootChannelSigner: ChannelSigner {
18+
/// Generate a local nonce pair, which requires committing to ahead of time
19+
/// The counterparty needs the public nonce generated herein to compute a partial signature
20+
fn generate_local_nonce_pair(&self, commitment_number: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicNonce;
21+
22+
/// Create a signature for a counterparty's commitment transaction and associated HTLC transactions.
23+
///
24+
/// Note that if signing fails or is rejected, the channel will be force-closed.
25+
///
26+
/// Policy checks should be implemented in this function, including checking the amount
27+
/// sent to us and checking the HTLCs.
28+
///
29+
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
30+
/// A validating signer should ensure that an HTLC output is removed only when the matching
31+
/// preimage is provided, or when the value to holder is restored.
32+
///
33+
/// Note that all the relevant preimages will be provided, but there may also be additional
34+
/// irrelevant or duplicate preimages.
35+
//
36+
// TODO: Document the things someone using this interface should enforce before signing.
37+
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce,
38+
commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>,
39+
secp_ctx: &Secp256k1<secp256k1::All>,
40+
) -> Result<(PartialSignatureWithNonce, Vec<Signature>), ()>;
41+
42+
/// Creates a signature for a holder's commitment transaction and its claiming HTLC transactions.
43+
///
44+
/// This will be called
45+
/// - with a non-revoked `commitment_tx`.
46+
/// - with the latest `commitment_tx` when we initiate a force-close.
47+
/// - with the previous `commitment_tx`, just to get claiming HTLC
48+
/// signatures, if we are reacting to a [`ChannelMonitor`]
49+
/// [replica](https://github.com/lightningdevkit/rust-lightning/blob/main/GLOSSARY.md#monitor-replicas)
50+
/// that decided to broadcast before it had been updated to the latest `commitment_tx`.
51+
///
52+
/// This may be called multiple times for the same transaction.
53+
///
54+
/// An external signer implementation should check that the commitment has not been revoked.
55+
///
56+
/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
57+
// TODO: Document the things someone using this interface should enforce before signing.
58+
fn finalize_holder_commitment_and_htlc_signatures(&self, commitment_number: u64,
59+
commitment_tx: &HolderCommitmentTransaction,
60+
counterparty_partial_signature: PartialSignatureWithNonce,
61+
secp_ctx: &Secp256k1<secp256k1::All>
62+
) -> Result<(PartialSignature, Vec<Signature>), ()>;
63+
64+
/// Create a signature for the given input in a transaction spending an HTLC transaction output
65+
/// or a commitment transaction `to_local` output when our counterparty broadcasts an old state.
66+
///
67+
/// A justice transaction may claim multiple outputs at the same time if timelocks are
68+
/// similar, but only a signature for the input at index `input` should be signed for here.
69+
/// It may be called multiple times for same output(s) if a fee-bump is needed with regards
70+
/// to an upcoming timelock expiration.
71+
///
72+
/// Amount is value of the output spent by this input, committed to in the BIP 341 signature.
73+
///
74+
/// `per_commitment_key` is revocation secret which was provided by our counterparty when they
75+
/// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does
76+
/// not allow the spending of any funds by itself (you need our holder `revocation_secret` to do
77+
/// so).
78+
fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64,
79+
per_commitment_key: &SecretKey, secp_ctx: &Secp256k1<secp256k1::All>,
80+
) -> Result<Signature, ()>;
81+
82+
/// Create a signature for the given input in a transaction spending a commitment transaction
83+
/// HTLC output when our counterparty broadcasts an old state.
84+
///
85+
/// A justice transaction may claim multiple outputs at the same time if timelocks are
86+
/// similar, but only a signature for the input at index `input` should be signed for here.
87+
/// It may be called multiple times for same output(s) if a fee-bump is needed with regards
88+
/// to an upcoming timelock expiration.
89+
///
90+
/// `amount` is the value of the output spent by this input, committed to in the BIP 341
91+
/// signature.
92+
///
93+
/// `per_commitment_key` is revocation secret which was provided by our counterparty when they
94+
/// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does
95+
/// not allow the spending of any funds by itself (you need our holder revocation_secret to do
96+
/// so).
97+
///
98+
/// `htlc` holds HTLC elements (hash, timelock), thus changing the format of the witness script
99+
/// (which is committed to in the BIP 341 signatures).
100+
fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64,
101+
per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment,
102+
secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
103+
104+
/// Computes the signature for a commitment transaction's HTLC output used as an input within
105+
/// `htlc_tx`, which spends the commitment transaction at index `input`. The signature returned
106+
/// must be be computed using [`SchnorrSighashType::Default`]. Note that this should only be
107+
/// used to sign HTLC transactions from channels supporting anchor outputs after all additional
108+
/// inputs/outputs have been added to the transaction.
109+
///
110+
/// [`SchnorrSighashType::Default`]: bitcoin::SchnorrSighashType::Default
111+
fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize,
112+
htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1<secp256k1::All>,
113+
) -> Result<Signature, ()>;
114+
115+
/// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment
116+
/// transaction, either offered or received.
117+
///
118+
/// Such a transaction may claim multiples offered outputs at same time if we know the
119+
/// preimage for each when we create it, but only the input at index `input` should be
120+
/// signed for here. It may be called multiple times for same output(s) if a fee-bump is
121+
/// needed with regards to an upcoming timelock expiration.
122+
///
123+
/// `witness_script` is either an offered or received script as defined in BOLT3 for HTLC
124+
/// outputs.
125+
///
126+
/// `amount` is value of the output spent by this input, committed to in the BIP 341 signature.
127+
///
128+
/// `per_commitment_point` is the dynamic point corresponding to the channel state
129+
/// detected onchain. It has been generated by our counterparty and is used to derive
130+
/// channel state keys, which are then included in the witness script and committed to in the
131+
/// BIP 341 signature.
132+
fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64,
133+
per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment,
134+
secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
135+
136+
/// Create a signature for a (proposed) closing transaction.
137+
///
138+
/// Note that, due to rounding, there may be one "missing" satoshi, and either party may have
139+
/// chosen to forgo their output as dust.
140+
fn partially_sign_closing_transaction(&self, closing_tx: &ClosingTransaction,
141+
secp_ctx: &Secp256k1<secp256k1::All>) -> Result<PartialSignature, ()>;
142+
143+
/// Computes the signature for a commitment transaction's anchor output used as an
144+
/// input within `anchor_tx`, which spends the commitment transaction, at index `input`.
145+
fn sign_holder_anchor_input(
146+
&self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
147+
) -> Result<Signature, ()>;
148+
149+
// TODO: sign channel announcement
150+
}

0 commit comments

Comments
 (0)