Skip to content

Commit f352d03

Browse files
authored
Merge pull request #2748 from TheBlueMatt/2023-11-2675-followups
Doc and style followups from #2675
2 parents 52c2253 + 3b6d693 commit f352d03

File tree

2 files changed

+143
-144
lines changed

2 files changed

+143
-144
lines changed

lightning/src/ln/channel.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,8 +1833,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
18331833
/// will sign and send to our counterparty.
18341834
/// If an Err is returned, it is a ChannelError::Close (for get_funding_created)
18351835
fn build_remote_transaction_keys(&self) -> TxCreationKeys {
1836-
//TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we
1837-
//may see payments to it!
18381836
let revocation_basepoint = &self.get_holder_pubkeys().revocation_basepoint;
18391837
let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint;
18401838
let counterparty_pubkeys = self.get_counterparty_pubkeys();

lightning/src/ln/channel_keys.rs

Lines changed: 143 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -25,126 +25,125 @@ use bitcoin::secp256k1::PublicKey;
2525
use bitcoin::hashes::sha256::Hash as Sha256;
2626

2727
macro_rules! doc_comment {
28-
($x:expr, $($tt:tt)*) => {
29-
#[doc = $x]
30-
$($tt)*
31-
};
28+
($x:expr, $($tt:tt)*) => {
29+
#[doc = $x]
30+
$($tt)*
31+
};
3232
}
3333
macro_rules! basepoint_impl {
34-
($BasepointT:ty) => {
35-
impl $BasepointT {
36-
/// Get inner Public Key
37-
pub fn to_public_key(&self) -> PublicKey {
38-
self.0
39-
}
40-
}
41-
42-
impl From<PublicKey> for $BasepointT {
43-
fn from(value: PublicKey) -> Self {
44-
Self(value)
45-
}
46-
}
47-
48-
}
34+
($BasepointT:ty) => {
35+
impl $BasepointT {
36+
/// Get inner Public Key
37+
pub fn to_public_key(&self) -> PublicKey {
38+
self.0
39+
}
40+
}
41+
42+
impl From<PublicKey> for $BasepointT {
43+
fn from(value: PublicKey) -> Self {
44+
Self(value)
45+
}
46+
}
47+
48+
}
4949
}
5050
macro_rules! key_impl {
51-
($BasepointT:ty, $KeyName:expr) => {
52-
doc_comment! {
53-
concat!("Generate ", $KeyName, " using per_commitment_point"),
54-
pub fn from_basepoint<T: secp256k1::Signing>(
55-
secp_ctx: &Secp256k1<T>,
56-
basepoint: &$BasepointT,
57-
per_commitment_point: &PublicKey,
58-
) -> Self {
59-
Self(derive_public_key(secp_ctx, per_commitment_point, &basepoint.0))
60-
}
61-
}
62-
63-
doc_comment! {
64-
concat!("Generate ", $KeyName, " from privkey"),
65-
pub fn from_secret_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, sk: &SecretKey) -> Self {
66-
Self(PublicKey::from_secret_key(&secp_ctx, &sk))
67-
}
68-
}
69-
70-
/// Get inner Public Key
71-
pub fn to_public_key(&self) -> PublicKey {
72-
self.0
73-
}
74-
}
51+
($BasepointT:ty, $KeyName:expr) => {
52+
doc_comment! {
53+
concat!("Derive a public ", $KeyName, " using one node's `per_commitment_point` and its countersignatory's `basepoint`"),
54+
pub fn from_basepoint<T: secp256k1::Signing>(
55+
secp_ctx: &Secp256k1<T>,
56+
countersignatory_basepoint: &$BasepointT,
57+
per_commitment_point: &PublicKey,
58+
) -> Self {
59+
Self(derive_public_key(secp_ctx, per_commitment_point, &countersignatory_basepoint.0))
60+
}
61+
}
62+
63+
doc_comment! {
64+
concat!("Build a ", $KeyName, " directly from an already-derived private key"),
65+
pub fn from_secret_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, sk: &SecretKey) -> Self {
66+
Self(PublicKey::from_secret_key(&secp_ctx, &sk))
67+
}
68+
}
69+
70+
/// Get inner Public Key
71+
pub fn to_public_key(&self) -> PublicKey {
72+
self.0
73+
}
74+
}
7575
}
7676
macro_rules! key_read_write {
77-
($SelfT:ty) => {
78-
impl Writeable for $SelfT {
79-
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
80-
self.0.serialize().write(w)
81-
}
82-
}
83-
84-
impl Readable for $SelfT {
85-
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
86-
let key: PublicKey = Readable::read(r)?;
87-
Ok(Self(key))
88-
}
89-
}
90-
}
77+
($SelfT:ty) => {
78+
impl Writeable for $SelfT {
79+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
80+
self.0.serialize().write(w)
81+
}
82+
}
83+
84+
impl Readable for $SelfT {
85+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
86+
let key: PublicKey = Readable::read(r)?;
87+
Ok(Self(key))
88+
}
89+
}
90+
}
9191
}
9292

9393

9494

95-
/// Master key used in conjunction with per_commitment_point to generate [`local_delayedpubkey`](https://github.com/lightning/bolts/blob/master/03-transactions.md#key-derivation) for the latest state of a channel.
96-
/// A watcher can be given a [DelayedPaymentBasepoint] to generate per commitment [DelayedPaymentKey] to create justice transactions.
95+
/// Base key used in conjunction with a `per_commitment_point` to generate a [`DelayedPaymentKey`].
96+
///
97+
/// The delayed payment key is used to pay the commitment state broadcaster their
98+
/// non-HTLC-encumbered funds after a delay to give their counterparty a chance to punish if the
99+
/// state broadcasted was previously revoked.
97100
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
98101
pub struct DelayedPaymentBasepoint(pub PublicKey);
99102
basepoint_impl!(DelayedPaymentBasepoint);
100103
key_read_write!(DelayedPaymentBasepoint);
101104

102-
/// [delayedpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation)
103-
/// To allow a counterparty to contest a channel state published by a node, Lightning protocol sets delays for some of the outputs, before can be spend.
104-
/// For example a commitment transaction has to_local output encumbered by a delay, negotiated at the channel establishment flow.
105-
/// To spend from such output a node has to generate a script using, among others, a local delayed payment key.
105+
106+
/// A derived key built from a [`DelayedPaymentBasepoint`] and `per_commitment_point`.
107+
///
108+
/// The delayed payment key is used to pay the commitment state broadcaster their
109+
/// non-HTLC-encumbered funds after a delay. This delay gives their counterparty a chance to
110+
/// punish and claim all the channel funds if the state broadcasted was previously revoked.
111+
///
112+
/// [See the BOLT specs]
113+
/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation)
114+
/// for more information on key derivation details.
106115
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
107116
pub struct DelayedPaymentKey(pub PublicKey);
108117

109118
impl DelayedPaymentKey {
110-
key_impl!(DelayedPaymentBasepoint, "delayedpubkey");
119+
key_impl!(DelayedPaymentBasepoint, "delayedpubkey");
111120
}
112121
key_read_write!(DelayedPaymentKey);
113122

114-
/// Master key used in conjunction with per_commitment_point to generate a [localpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#key-derivation) for the latest state of a channel.
115-
/// Also used to generate a commitment number in a commitment transaction or as a Payment Key for a remote node (not us) in an anchor output if `option_static_remotekey` is enabled.
116-
/// Shared by both nodes in a channel establishment message flow.
117-
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
118-
pub struct PaymentBasepoint(pub PublicKey);
119-
basepoint_impl!(PaymentBasepoint);
120-
key_read_write!(PaymentBasepoint);
121-
122-
123-
/// [localpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) is a child key of a payment basepoint,
124-
/// that enables a secure hash-lock for off-chain payments without risk of funds getting stuck or stolen. A payment key is normally shared with a counterparty so that it can generate
125-
/// a commitment transaction's to_remote ouput, which our node can claim in case the counterparty force closes the channel.
126-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
127-
pub struct PaymentKey(pub PublicKey);
128-
129-
impl PaymentKey {
130-
key_impl!(PaymentBasepoint, "localpubkey");
131-
}
132-
key_read_write!(PaymentKey);
133-
134-
/// Master key used in conjunction with per_commitment_point to generate [htlcpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#key-derivation) for the latest state of a channel.
123+
/// Base key used in conjunction with a `per_commitment_point` to generate an [`HtlcKey`].
124+
///
125+
/// HTLC keys are used to ensure only the recipient of an HTLC can claim it on-chain with the HTLC
126+
/// preimage and that only the sender of an HTLC can claim it on-chain after it has timed out.
127+
/// Thus, both channel counterparties' HTLC keys will appears in each HTLC output's script.
135128
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
136129
pub struct HtlcBasepoint(pub PublicKey);
137130
basepoint_impl!(HtlcBasepoint);
138131
key_read_write!(HtlcBasepoint);
139132

140-
141-
/// [htlcpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) is a child key of an htlc basepoint,
142-
/// that enables secure routing of payments in onion scheme without a risk of them getting stuck or diverted. It is used to claim the funds in successful or timed out htlc outputs.
133+
/// A derived key built from a [`HtlcBasepoint`] and `per_commitment_point`.
134+
///
135+
/// HTLC keys are used to ensure only the recipient of an HTLC can claim it on-chain with the HTLC
136+
/// preimage and that only the sender of an HTLC can claim it on-chain after it has timed out.
137+
/// Thus, both channel counterparties' HTLC keys will appears in each HTLC output's script.
138+
///
139+
/// [See the BOLT specs]
140+
/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation)
141+
/// for more information on key derivation details.
143142
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
144143
pub struct HtlcKey(pub PublicKey);
145144

146145
impl HtlcKey {
147-
key_impl!(HtlcBasepoint, "htlcpubkey");
146+
key_impl!(HtlcBasepoint, "htlcpubkey");
148147
}
149148
key_read_write!(HtlcKey);
150149

@@ -156,7 +155,6 @@ fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitm
156155
sha.input(&per_commitment_point.serialize());
157156
sha.input(&base_point.serialize());
158157
let res = Sha256::from_engine(sha).to_byte_array();
159-
160158

161159
let hashkey = PublicKey::from_secret_key(&secp_ctx,
162160
&SecretKey::from_slice(&res).expect("Hashes should always be valid keys unless SHA-256 is broken"));
@@ -172,68 +170,71 @@ basepoint_impl!(RevocationBasepoint);
172170
key_read_write!(RevocationBasepoint);
173171

174172

175-
/// [htlcpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) is a child key of a revocation basepoint,
176-
/// that enables a node to create a justice transaction punishing a counterparty for an attempt to steal funds. Used to in generation of commitment and htlc outputs.
173+
/// The revocation key is used to allow a channel party to revoke their state - giving their
174+
/// counterparty the required material to claim all of their funds if they broadcast that state.
175+
///
176+
/// Each commitment transaction has a revocation key based on the basepoint and
177+
/// per_commitment_point which is used in both commitment and HTLC transactions.
178+
///
179+
/// See [the BOLT spec for derivation details]
180+
/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#revocationpubkey-derivation)
177181
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
178182
pub struct RevocationKey(pub PublicKey);
179183

180184
impl RevocationKey {
181-
/// Derives a per-commitment-transaction revocation public key from its constituent parts. This is
182-
/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
183-
/// public key instead of private keys.
184-
///
185-
/// Only the cheating participant owns a valid witness to propagate a revoked
186-
/// commitment transaction, thus per_commitment_point always come from cheater
187-
/// and revocation_base_point always come from punisher, which is the broadcaster
188-
/// of the transaction spending with this key knowledge.
189-
///
190-
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
191-
/// generated (ie our own).
192-
pub fn from_basepoint<T: secp256k1::Verification>(
193-
secp_ctx: &Secp256k1<T>,
194-
basepoint: &RevocationBasepoint,
195-
per_commitment_point: &PublicKey,
196-
) -> Self {
197-
let rev_append_commit_hash_key = {
198-
let mut sha = Sha256::engine();
199-
sha.input(&basepoint.to_public_key().serialize());
200-
sha.input(&per_commitment_point.serialize());
201-
202-
Sha256::from_engine(sha).to_byte_array()
203-
};
204-
let commit_append_rev_hash_key = {
205-
let mut sha = Sha256::engine();
206-
sha.input(&per_commitment_point.serialize());
207-
sha.input(&basepoint.to_public_key().serialize());
208-
209-
Sha256::from_engine(sha).to_byte_array()
210-
};
211-
212-
let countersignatory_contrib = basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap())
213-
.expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
214-
let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap())
215-
.expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
216-
let pk = countersignatory_contrib.combine(&broadcaster_contrib)
217-
.expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key.");
218-
Self(pk)
219-
}
220-
221-
/// Get inner Public Key
222-
pub fn to_public_key(&self) -> PublicKey {
223-
self.0
224-
}
185+
/// Derives a per-commitment-transaction revocation public key from one party's per-commitment
186+
/// point and the other party's [`RevocationBasepoint`]. This is the public equivalent of
187+
/// [`chan_utils::derive_private_revocation_key`] - using only public keys to derive a public
188+
/// key instead of private keys.
189+
///
190+
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly
191+
/// generated (ie our own).
192+
///
193+
/// [`chan_utils::derive_private_revocation_key`]: crate::ln::chan_utils::derive_private_revocation_key
194+
pub fn from_basepoint<T: secp256k1::Verification>(
195+
secp_ctx: &Secp256k1<T>,
196+
countersignatory_basepoint: &RevocationBasepoint,
197+
per_commitment_point: &PublicKey,
198+
) -> Self {
199+
let rev_append_commit_hash_key = {
200+
let mut sha = Sha256::engine();
201+
sha.input(&countersignatory_basepoint.to_public_key().serialize());
202+
sha.input(&per_commitment_point.serialize());
203+
204+
Sha256::from_engine(sha).to_byte_array()
205+
};
206+
let commit_append_rev_hash_key = {
207+
let mut sha = Sha256::engine();
208+
sha.input(&per_commitment_point.serialize());
209+
sha.input(&countersignatory_basepoint.to_public_key().serialize());
210+
211+
Sha256::from_engine(sha).to_byte_array()
212+
};
213+
214+
let countersignatory_contrib = countersignatory_basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap())
215+
.expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
216+
let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap())
217+
.expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
218+
let pk = countersignatory_contrib.combine(&broadcaster_contrib)
219+
.expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key.");
220+
Self(pk)
221+
}
222+
223+
/// Get inner Public Key
224+
pub fn to_public_key(&self) -> PublicKey {
225+
self.0
226+
}
225227
}
226228
key_read_write!(RevocationKey);
227229

228230

229-
230231
#[cfg(test)]
231232
mod test {
232-
use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
233-
use bitcoin::hashes::hex::FromHex;
234-
use super::derive_public_key;
233+
use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
234+
use bitcoin::hashes::hex::FromHex;
235+
use super::derive_public_key;
235236

236-
#[test]
237+
#[test]
237238
fn test_key_derivation() {
238239
// Test vectors from BOLT 3 Appendix E:
239240
let secp_ctx = Secp256k1::new();
@@ -248,6 +249,6 @@ mod test {
248249
assert_eq!(per_commitment_point.serialize()[..], <Vec<u8>>::from_hex("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486").unwrap()[..]);
249250

250251
assert_eq!(derive_public_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..],
251-
<Vec<u8>>::from_hex("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]);
252+
<Vec<u8>>::from_hex("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]);
252253
}
253254
}

0 commit comments

Comments
 (0)