Skip to content

Commit 1c80b04

Browse files
committed
Create TaprootSigner trait.
1 parent 72e1350 commit 1c80b04

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

lightning/src/sign/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ use crate::util::atomic_counter::AtomicCounter;
5353
use crate::util::chacha20::ChaCha20;
5454
use crate::util::invoice::construct_invoice_preimage;
5555

56+
#[cfg(all(anchors, taproot))]
57+
pub mod taproot;
58+
5659
/// Used as initial key material, to be expanded into multiple secret keys (but not to be used
5760
/// directly). This is used within LDK to encrypt/decrypt inbound payment data.
5861
///

lightning/src/sign/taproot.rs

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

0 commit comments

Comments
 (0)