From 83fe0b8260d3dc9c456fdc6e8694737bb6597909 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 17:57:21 +0000 Subject: [PATCH 1/6] Fix space and execss indentation in `channel_keys.rs` --- lightning/src/ln/channel_keys.rs | 219 +++++++++++++++---------------- 1 file changed, 109 insertions(+), 110 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index f737dd23407..9a5a8278dd0 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -25,69 +25,69 @@ use bitcoin::secp256k1::PublicKey; use bitcoin::hashes::sha256::Hash as Sha256; macro_rules! doc_comment { - ($x:expr, $($tt:tt)*) => { - #[doc = $x] - $($tt)* - }; + ($x:expr, $($tt:tt)*) => { + #[doc = $x] + $($tt)* + }; } macro_rules! basepoint_impl { - ($BasepointT:ty) => { - impl $BasepointT { - /// Get inner Public Key - pub fn to_public_key(&self) -> PublicKey { - self.0 - } - } - - impl From for $BasepointT { - fn from(value: PublicKey) -> Self { - Self(value) - } - } - - } + ($BasepointT:ty) => { + impl $BasepointT { + /// Get inner Public Key + pub fn to_public_key(&self) -> PublicKey { + self.0 + } + } + + impl From for $BasepointT { + fn from(value: PublicKey) -> Self { + Self(value) + } + } + + } } macro_rules! key_impl { - ($BasepointT:ty, $KeyName:expr) => { - doc_comment! { - concat!("Generate ", $KeyName, " using per_commitment_point"), - pub fn from_basepoint( - secp_ctx: &Secp256k1, - basepoint: &$BasepointT, - per_commitment_point: &PublicKey, - ) -> Self { - Self(derive_public_key(secp_ctx, per_commitment_point, &basepoint.0)) - } - } - - doc_comment! { - concat!("Generate ", $KeyName, " from privkey"), - pub fn from_secret_key(secp_ctx: &Secp256k1, sk: &SecretKey) -> Self { - Self(PublicKey::from_secret_key(&secp_ctx, &sk)) - } - } - - /// Get inner Public Key - pub fn to_public_key(&self) -> PublicKey { - self.0 - } - } + ($BasepointT:ty, $KeyName:expr) => { + doc_comment! { + concat!("Generate ", $KeyName, " using per_commitment_point"), + pub fn from_basepoint( + secp_ctx: &Secp256k1, + basepoint: &$BasepointT, + per_commitment_point: &PublicKey, + ) -> Self { + Self(derive_public_key(secp_ctx, per_commitment_point, &basepoint.0)) + } + } + + doc_comment! { + concat!("Generate ", $KeyName, " from privkey"), + pub fn from_secret_key(secp_ctx: &Secp256k1, sk: &SecretKey) -> Self { + Self(PublicKey::from_secret_key(&secp_ctx, &sk)) + } + } + + /// Get inner Public Key + pub fn to_public_key(&self) -> PublicKey { + self.0 + } + } } macro_rules! key_read_write { - ($SelfT:ty) => { - impl Writeable for $SelfT { - fn write(&self, w: &mut W) -> Result<(), io::Error> { - self.0.serialize().write(w) - } - } - - impl Readable for $SelfT { - fn read(r: &mut R) -> Result { - let key: PublicKey = Readable::read(r)?; - Ok(Self(key)) - } - } - } + ($SelfT:ty) => { + impl Writeable for $SelfT { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.0.serialize().write(w) + } + } + + impl Readable for $SelfT { + fn read(r: &mut R) -> Result { + let key: PublicKey = Readable::read(r)?; + Ok(Self(key)) + } + } + } } @@ -107,7 +107,7 @@ key_read_write!(DelayedPaymentBasepoint); pub struct DelayedPaymentKey(pub PublicKey); impl DelayedPaymentKey { - key_impl!(DelayedPaymentBasepoint, "delayedpubkey"); + key_impl!(DelayedPaymentBasepoint, "delayedpubkey"); } key_read_write!(DelayedPaymentKey); @@ -127,7 +127,7 @@ key_read_write!(PaymentBasepoint); pub struct PaymentKey(pub PublicKey); impl PaymentKey { - key_impl!(PaymentBasepoint, "localpubkey"); + key_impl!(PaymentBasepoint, "localpubkey"); } key_read_write!(PaymentKey); @@ -144,7 +144,7 @@ key_read_write!(HtlcBasepoint); pub struct HtlcKey(pub PublicKey); impl HtlcKey { - key_impl!(HtlcBasepoint, "htlcpubkey"); + key_impl!(HtlcBasepoint, "htlcpubkey"); } key_read_write!(HtlcKey); @@ -156,7 +156,6 @@ fn derive_public_key(secp_ctx: &Secp256k1, per_commitm sha.input(&per_commitment_point.serialize()); sha.input(&base_point.serialize()); let res = Sha256::from_engine(sha).to_byte_array(); - let hashkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&res).expect("Hashes should always be valid keys unless SHA-256 is broken")); @@ -178,50 +177,50 @@ key_read_write!(RevocationBasepoint); pub struct RevocationKey(pub PublicKey); impl RevocationKey { - /// Derives a per-commitment-transaction revocation public key from its constituent parts. This is - /// the public equivalend of derive_private_revocation_key - using only public keys to derive a - /// public key instead of private keys. - /// - /// Only the cheating participant owns a valid witness to propagate a revoked - /// commitment transaction, thus per_commitment_point always come from cheater - /// and revocation_base_point always come from punisher, which is the broadcaster - /// of the transaction spending with this key knowledge. - /// - /// Note that this is infallible iff we trust that at least one of the two input keys are randomly - /// generated (ie our own). - pub fn from_basepoint( - secp_ctx: &Secp256k1, - basepoint: &RevocationBasepoint, - per_commitment_point: &PublicKey, - ) -> Self { - let rev_append_commit_hash_key = { - let mut sha = Sha256::engine(); - sha.input(&basepoint.to_public_key().serialize()); - sha.input(&per_commitment_point.serialize()); - - Sha256::from_engine(sha).to_byte_array() - }; - let commit_append_rev_hash_key = { - let mut sha = Sha256::engine(); - sha.input(&per_commitment_point.serialize()); - sha.input(&basepoint.to_public_key().serialize()); - - Sha256::from_engine(sha).to_byte_array() - }; - - let countersignatory_contrib = basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap()) - .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); - let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap()) - .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); - let pk = countersignatory_contrib.combine(&broadcaster_contrib) - .expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key."); - Self(pk) - } - - /// Get inner Public Key - pub fn to_public_key(&self) -> PublicKey { - self.0 - } + /// Derives a per-commitment-transaction revocation public key from its constituent parts. This is + /// the public equivalend of derive_private_revocation_key - using only public keys to derive a + /// public key instead of private keys. + /// + /// Only the cheating participant owns a valid witness to propagate a revoked + /// commitment transaction, thus per_commitment_point always come from cheater + /// and revocation_base_point always come from punisher, which is the broadcaster + /// of the transaction spending with this key knowledge. + /// + /// Note that this is infallible iff we trust that at least one of the two input keys are randomly + /// generated (ie our own). + pub fn from_basepoint( + secp_ctx: &Secp256k1, + basepoint: &RevocationBasepoint, + per_commitment_point: &PublicKey, + ) -> Self { + let rev_append_commit_hash_key = { + let mut sha = Sha256::engine(); + sha.input(&basepoint.to_public_key().serialize()); + sha.input(&per_commitment_point.serialize()); + + Sha256::from_engine(sha).to_byte_array() + }; + let commit_append_rev_hash_key = { + let mut sha = Sha256::engine(); + sha.input(&per_commitment_point.serialize()); + sha.input(&basepoint.to_public_key().serialize()); + + Sha256::from_engine(sha).to_byte_array() + }; + + let countersignatory_contrib = basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap()) + .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); + let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap()) + .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); + let pk = countersignatory_contrib.combine(&broadcaster_contrib) + .expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key."); + Self(pk) + } + + /// Get inner Public Key + pub fn to_public_key(&self) -> PublicKey { + self.0 + } } key_read_write!(RevocationKey); @@ -229,11 +228,11 @@ key_read_write!(RevocationKey); #[cfg(test)] mod test { - use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; - use bitcoin::hashes::hex::FromHex; - use super::derive_public_key; + use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; + use bitcoin::hashes::hex::FromHex; + use super::derive_public_key; - #[test] + #[test] fn test_key_derivation() { // Test vectors from BOLT 3 Appendix E: let secp_ctx = Secp256k1::new(); @@ -248,6 +247,6 @@ mod test { assert_eq!(per_commitment_point.serialize()[..], >::from_hex("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486").unwrap()[..]); assert_eq!(derive_public_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..], - >::from_hex("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]); + >::from_hex("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]); } } From 029448a6136e3f68d718c4e0ddc9f450e3739609 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 18:16:57 +0000 Subject: [PATCH 2/6] Update docs on `RevocationKey` for clarity and to provide more info This also adds required linebreaks to keep the docs to a reasonable width. --- lightning/src/ln/channel_keys.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index 9a5a8278dd0..19b7b84c5d8 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -171,23 +171,27 @@ basepoint_impl!(RevocationBasepoint); key_read_write!(RevocationBasepoint); -/// [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, -/// 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. +/// The revocation key is used to allow a channel party to revoke their state - giving their +/// counterparty the required material to claim all of their funds if they broadcast that state. +/// +/// Each commitment transaction has a revocation key based on the basepoint and +/// per_commitment_point which is used in both commitment and HTLC transactions. +/// +/// See [the BOLT spec for derivation details] +/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#revocationpubkey-derivation) #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub struct RevocationKey(pub PublicKey); impl RevocationKey { - /// Derives a per-commitment-transaction revocation public key from its constituent parts. This is - /// the public equivalend of derive_private_revocation_key - using only public keys to derive a - /// public key instead of private keys. - /// - /// Only the cheating participant owns a valid witness to propagate a revoked - /// commitment transaction, thus per_commitment_point always come from cheater - /// and revocation_base_point always come from punisher, which is the broadcaster - /// of the transaction spending with this key knowledge. + /// Derives a per-commitment-transaction revocation public key from one party's per-commitment + /// point and the other party's [`RevocationBasepoint`]. This is the public equivalent of + /// [`chan_utils::derive_private_revocation_key`] - using only public keys to derive a public + /// key instead of private keys. /// /// Note that this is infallible iff we trust that at least one of the two input keys are randomly /// generated (ie our own). + /// + /// [`chan_utils::derive_private_revocation_key`]: crate::ln::chan_utils::derive_private_revocation_key pub fn from_basepoint( secp_ctx: &Secp256k1, basepoint: &RevocationBasepoint, From e4f690cd4c58050b982a24fc9a600dd922d299e7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 18:18:04 +0000 Subject: [PATCH 3/6] Change `RevocationKey` args to make clear one side is a countersig 935a716cc6c4fada075e2b740a70bb1b7b349d49 changed the parameter names to `RevocationKey` derivation to remove the naming which made clear one of the two parameters is a countersignatory key, which is restored here. --- lightning/src/ln/channel_keys.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index 19b7b84c5d8..3ea9ac01a65 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -194,12 +194,12 @@ impl RevocationKey { /// [`chan_utils::derive_private_revocation_key`]: crate::ln::chan_utils::derive_private_revocation_key pub fn from_basepoint( secp_ctx: &Secp256k1, - basepoint: &RevocationBasepoint, + countersignatory_basepoint: &RevocationBasepoint, per_commitment_point: &PublicKey, ) -> Self { let rev_append_commit_hash_key = { let mut sha = Sha256::engine(); - sha.input(&basepoint.to_public_key().serialize()); + sha.input(&countersignatory_basepoint.to_public_key().serialize()); sha.input(&per_commitment_point.serialize()); Sha256::from_engine(sha).to_byte_array() @@ -207,12 +207,12 @@ impl RevocationKey { let commit_append_rev_hash_key = { let mut sha = Sha256::engine(); sha.input(&per_commitment_point.serialize()); - sha.input(&basepoint.to_public_key().serialize()); + sha.input(&countersignatory_basepoint.to_public_key().serialize()); Sha256::from_engine(sha).to_byte_array() }; - let countersignatory_contrib = basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap()) + let countersignatory_contrib = countersignatory_basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap()) .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap()) .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs"); @@ -229,7 +229,6 @@ impl RevocationKey { key_read_write!(RevocationKey); - #[cfg(test)] mod test { use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; From bc273a293949df9e749bca4ee1d07fa20ffd8fa0 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 18:32:08 +0000 Subject: [PATCH 4/6] Update docs for slightly more clarity on channel key derivation --- lightning/src/ln/channel_keys.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index 3ea9ac01a65..fbb0162e93c 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -50,18 +50,18 @@ macro_rules! basepoint_impl { macro_rules! key_impl { ($BasepointT:ty, $KeyName:expr) => { doc_comment! { - concat!("Generate ", $KeyName, " using per_commitment_point"), + concat!("Derive a public ", $KeyName, " using one node's `per_commitment_point` and its countersignatory's `basepoint`"), pub fn from_basepoint( secp_ctx: &Secp256k1, - basepoint: &$BasepointT, + countersignatory_basepoint: &$BasepointT, per_commitment_point: &PublicKey, ) -> Self { - Self(derive_public_key(secp_ctx, per_commitment_point, &basepoint.0)) + Self(derive_public_key(secp_ctx, per_commitment_point, &countersignatory_basepoint.0)) } } doc_comment! { - concat!("Generate ", $KeyName, " from privkey"), + concat!("Build a ", $KeyName, " directly from an already-derived private key"), pub fn from_secret_key(secp_ctx: &Secp256k1, sk: &SecretKey) -> Self { Self(PublicKey::from_secret_key(&secp_ctx, &sk)) } From c5e3f5fa820a17dc6789db41e3a4a772dc28b068 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 18:51:13 +0000 Subject: [PATCH 5/6] Drop the unused `PaymentKey` type 935a716cc6c4fada075e2b740a70bb1b7b349d49 added new wrappers for the various channel keys, including a payment_key. However, the `payment_key` has been unused in lightning since the introduction (and broad requiring) of the `static_remotekey` feature. Thus, we simply remove it (and an incredibly stale TODO) here. --- lightning/src/ln/channel.rs | 2 -- lightning/src/ln/channel_keys.rs | 20 -------------------- 2 files changed, 22 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 263d0dbd229..469eddd642f 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1568,8 +1568,6 @@ impl ChannelContext where SP::Target: SignerProvider { /// will sign and send to our counterparty. /// If an Err is returned, it is a ChannelError::Close (for get_funding_created) fn build_remote_transaction_keys(&self) -> TxCreationKeys { - //TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we - //may see payments to it! let revocation_basepoint = &self.get_holder_pubkeys().revocation_basepoint; let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint; let counterparty_pubkeys = self.get_counterparty_pubkeys(); diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index fbb0162e93c..d08f1d68521 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -111,26 +111,6 @@ impl DelayedPaymentKey { } key_read_write!(DelayedPaymentKey); -/// 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. -/// 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. -/// Shared by both nodes in a channel establishment message flow. -#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] -pub struct PaymentBasepoint(pub PublicKey); -basepoint_impl!(PaymentBasepoint); -key_read_write!(PaymentBasepoint); - - -/// [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, -/// 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 -/// a commitment transaction's to_remote ouput, which our node can claim in case the counterparty force closes the channel. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct PaymentKey(pub PublicKey); - -impl PaymentKey { - key_impl!(PaymentBasepoint, "localpubkey"); -} -key_read_write!(PaymentKey); - /// 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. #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub struct HtlcBasepoint(pub PublicKey); From 3b6d6937bbfb5303b2bc9f114667714735bd3382 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 27 Nov 2023 18:52:37 +0000 Subject: [PATCH 6/6] Update docs on `HTLC` and `DelayedPayment` keys for clarity This also adds required linebreaks to keep the docs to a reasonable width. --- lightning/src/ln/channel_keys.rs | 39 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/lightning/src/ln/channel_keys.rs b/lightning/src/ln/channel_keys.rs index d08f1d68521..b577dc60008 100644 --- a/lightning/src/ln/channel_keys.rs +++ b/lightning/src/ln/channel_keys.rs @@ -92,17 +92,26 @@ macro_rules! key_read_write { -/// 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. -/// A watcher can be given a [DelayedPaymentBasepoint] to generate per commitment [DelayedPaymentKey] to create justice transactions. +/// Base key used in conjunction with a `per_commitment_point` to generate a [`DelayedPaymentKey`]. +/// +/// The delayed payment key is used to pay the commitment state broadcaster their +/// non-HTLC-encumbered funds after a delay to give their counterparty a chance to punish if the +/// state broadcasted was previously revoked. #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub struct DelayedPaymentBasepoint(pub PublicKey); basepoint_impl!(DelayedPaymentBasepoint); key_read_write!(DelayedPaymentBasepoint); -/// [delayedpubkey](https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) -/// 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. -/// For example a commitment transaction has to_local output encumbered by a delay, negotiated at the channel establishment flow. -/// To spend from such output a node has to generate a script using, among others, a local delayed payment key. + +/// A derived key built from a [`DelayedPaymentBasepoint`] and `per_commitment_point`. +/// +/// The delayed payment key is used to pay the commitment state broadcaster their +/// non-HTLC-encumbered funds after a delay. This delay gives their counterparty a chance to +/// punish and claim all the channel funds if the state broadcasted was previously revoked. +/// +/// [See the BOLT specs] +/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) +/// for more information on key derivation details. #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct DelayedPaymentKey(pub PublicKey); @@ -111,15 +120,25 @@ impl DelayedPaymentKey { } key_read_write!(DelayedPaymentKey); -/// 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. +/// Base key used in conjunction with a `per_commitment_point` to generate an [`HtlcKey`]. +/// +/// HTLC keys are used to ensure only the recipient of an HTLC can claim it on-chain with the HTLC +/// preimage and that only the sender of an HTLC can claim it on-chain after it has timed out. +/// Thus, both channel counterparties' HTLC keys will appears in each HTLC output's script. #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub struct HtlcBasepoint(pub PublicKey); basepoint_impl!(HtlcBasepoint); key_read_write!(HtlcBasepoint); - -/// [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, -/// 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. +/// A derived key built from a [`HtlcBasepoint`] and `per_commitment_point`. +/// +/// HTLC keys are used to ensure only the recipient of an HTLC can claim it on-chain with the HTLC +/// preimage and that only the sender of an HTLC can claim it on-chain after it has timed out. +/// Thus, both channel counterparties' HTLC keys will appears in each HTLC output's script. +/// +/// [See the BOLT specs] +/// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation) +/// for more information on key derivation details. #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct HtlcKey(pub PublicKey);