eaa14f27f3312aa613e449c7d8084183a3cdee4b
[rust-lightning] / lightning / src / ln / channel_keys.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Keys used to generate commitment transactions.
11 //! See: <https://github.com/lightning/bolts/blob/master/03-transactions.md#keys>
12
13 use crate::io;
14 use crate::ln::msgs::DecodeError;
15 use crate::util::ser::Readable;
16 use crate::util::ser::Writeable;
17 use crate::util::ser::Writer;
18 use bitcoin::hashes::sha256::Hash as Sha256;
19 use bitcoin::hashes::Hash;
20 use bitcoin::hashes::HashEngine;
21 use bitcoin::secp256k1;
22 use bitcoin::secp256k1::PublicKey;
23 use bitcoin::secp256k1::Scalar;
24 use bitcoin::secp256k1::Secp256k1;
25 use bitcoin::secp256k1::SecretKey;
26
27 macro_rules! doc_comment {
28         ($x:expr, $($tt:tt)*) => {
29                 #[doc = $x]
30                 $($tt)*
31         };
32 }
33 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                         /// Derives the "tweak" used to calculate the per-commitment private key.
42                         ///
43                         /// The per-commitment private key is calculates a private key as:
44                         /// `privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)`
45                         ///
46                         /// This calculates the hash part in the tweak derivation process, which is used to
47                         /// ensure that each key is unique and cannot be guessed by an external party.
48                         pub fn derive_add_tweak(&self, per_commitment_point: &PublicKey) -> Sha256 {
49                                 let mut sha = Sha256::engine();
50                                 sha.input(&per_commitment_point.serialize());
51                                 sha.input(&self.to_public_key().serialize());
52                                 Sha256::from_engine(sha)
53                         }
54                 }
55
56                 impl From<PublicKey> for $BasepointT {
57                         fn from(value: PublicKey) -> Self {
58                                 Self(value)
59                         }
60                 }
61         };
62 }
63 macro_rules! key_impl {
64         ($BasepointT:ty, $KeyName:expr) => {
65                 doc_comment! {
66                         concat!("Derive a public ", $KeyName, " using one node's `per_commitment_point` and its countersignatory's `basepoint`"),
67                         pub fn from_basepoint<T: secp256k1::Signing>(
68                                 secp_ctx: &Secp256k1<T>,
69                                 countersignatory_basepoint: &$BasepointT,
70                                 per_commitment_point: &PublicKey,
71                         ) -> Self {
72                                 Self(derive_public_key(secp_ctx, per_commitment_point, &countersignatory_basepoint.0))
73                         }
74                 }
75
76                 doc_comment! {
77                         concat!("Build a ", $KeyName, " directly from an already-derived private key"),
78                         pub fn from_secret_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, sk: &SecretKey) -> Self {
79                                 Self(PublicKey::from_secret_key(&secp_ctx, &sk))
80                         }
81                 }
82
83                 /// Get inner Public Key
84                 pub fn to_public_key(&self) -> PublicKey {
85                         self.0
86                 }
87         }
88 }
89 macro_rules! key_read_write {
90         ($SelfT:ty) => {
91                 impl Writeable for $SelfT {
92                         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
93                                 self.0.serialize().write(w)
94                         }
95                 }
96
97                 impl Readable for $SelfT {
98                         fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
99                                 let key: PublicKey = Readable::read(r)?;
100                                 Ok(Self(key))
101                         }
102                 }
103         };
104 }
105
106 /// Base key used in conjunction with a `per_commitment_point` to generate a [`DelayedPaymentKey`].
107 ///
108 /// The delayed payment key is used to pay the commitment state broadcaster their
109 /// non-HTLC-encumbered funds after a delay to give their counterparty a chance to punish if the
110 /// state broadcasted was previously revoked.
111 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
112 pub struct DelayedPaymentBasepoint(pub PublicKey);
113 basepoint_impl!(DelayedPaymentBasepoint);
114 key_read_write!(DelayedPaymentBasepoint);
115
116 /// A derived key built from a [`DelayedPaymentBasepoint`] and `per_commitment_point`.
117 ///
118 /// The delayed payment key is used to pay the commitment state broadcaster their
119 /// non-HTLC-encumbered funds after a delay. This delay gives their counterparty a chance to
120 /// punish and claim all the channel funds if the state broadcasted was previously revoked.
121 ///
122 /// [See the BOLT specs]
123 /// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation)
124 /// for more information on key derivation details.
125 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
126 pub struct DelayedPaymentKey(pub PublicKey);
127
128 impl DelayedPaymentKey {
129         key_impl!(DelayedPaymentBasepoint, "delayedpubkey");
130 }
131 key_read_write!(DelayedPaymentKey);
132
133 /// Base key used in conjunction with a `per_commitment_point` to generate an [`HtlcKey`].
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 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
139 pub struct HtlcBasepoint(pub PublicKey);
140 basepoint_impl!(HtlcBasepoint);
141 key_read_write!(HtlcBasepoint);
142
143 /// A derived key built from a [`HtlcBasepoint`] and `per_commitment_point`.
144 ///
145 /// HTLC keys are used to ensure only the recipient of an HTLC can claim it on-chain with the HTLC
146 /// preimage and that only the sender of an HTLC can claim it on-chain after it has timed out.
147 /// Thus, both channel counterparties' HTLC keys will appears in each HTLC output's script.
148 ///
149 /// [See the BOLT specs]
150 /// (https://github.com/lightning/bolts/blob/master/03-transactions.md#localpubkey-local_htlcpubkey-remote_htlcpubkey-local_delayedpubkey-and-remote_delayedpubkey-derivation)
151 /// for more information on key derivation details.
152 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
153 pub struct HtlcKey(pub PublicKey);
154
155 impl HtlcKey {
156         key_impl!(HtlcBasepoint, "htlcpubkey");
157 }
158 key_read_write!(HtlcKey);
159
160 /// Derives a per-commitment-transaction public key (eg an htlc key or a delayed_payment key)
161 /// from the base point and the per_commitment_key. This is the public equivalent of
162 /// derive_private_key - using only public keys to derive a public key instead of private keys.
163 fn derive_public_key<T: secp256k1::Signing>(
164         secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey,
165 ) -> PublicKey {
166         let mut sha = Sha256::engine();
167         sha.input(&per_commitment_point.serialize());
168         sha.input(&base_point.serialize());
169         let res = Sha256::from_engine(sha);
170
171         add_public_key_tweak(secp_ctx, base_point, &res)
172 }
173
174 /// Adds a tweak to a public key to derive a new public key.
175 ///
176 /// May panic if `tweak` is not the output of a SHA-256 hash.
177 pub fn add_public_key_tweak<T: secp256k1::Signing>(
178         secp_ctx: &Secp256k1<T>, base_point: &PublicKey, tweak: &Sha256,
179 ) -> PublicKey {
180         let hashkey = PublicKey::from_secret_key(
181                 &secp_ctx,
182                 &SecretKey::from_slice(tweak.as_byte_array())
183                         .expect("Hashes should always be valid keys unless SHA-256 is broken"),
184         );
185         base_point.combine(&hashkey)
186                 .expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak contains the hash of the key.")
187 }
188
189 /// 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.
190 /// A watcher can be given a [RevocationBasepoint] to generate per commitment [RevocationKey] to create justice transactions.
191 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
192 pub struct RevocationBasepoint(pub PublicKey);
193 basepoint_impl!(RevocationBasepoint);
194 key_read_write!(RevocationBasepoint);
195
196 /// The revocation key is used to allow a channel party to revoke their state - giving their
197 /// counterparty the required material to claim all of their funds if they broadcast that state.
198 ///
199 /// Each commitment transaction has a revocation key based on the basepoint and
200 /// per_commitment_point which is used in both commitment and HTLC transactions.
201 ///
202 /// See [the BOLT spec for derivation details]
203 /// (https://github.com/lightning/bolts/blob/master/03-transactions.md#revocationpubkey-derivation)
204 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
205 pub struct RevocationKey(pub PublicKey);
206
207 impl RevocationKey {
208         /// Derives a per-commitment-transaction revocation public key from one party's per-commitment
209         /// point and the other party's [`RevocationBasepoint`]. This is the public equivalent of
210         /// [`chan_utils::derive_private_revocation_key`] - using only public keys to derive a public
211         /// key instead of private keys.
212         ///
213         /// Note that this is infallible iff we trust that at least one of the two input keys are randomly
214         /// generated (ie our own).
215         ///
216         /// [`chan_utils::derive_private_revocation_key`]: crate::ln::chan_utils::derive_private_revocation_key
217         pub fn from_basepoint<T: secp256k1::Verification>(
218                 secp_ctx: &Secp256k1<T>, countersignatory_basepoint: &RevocationBasepoint,
219                 per_commitment_point: &PublicKey,
220         ) -> Self {
221                 let rev_append_commit_hash_key = {
222                         let mut sha = Sha256::engine();
223                         sha.input(&countersignatory_basepoint.to_public_key().serialize());
224                         sha.input(&per_commitment_point.serialize());
225
226                         Sha256::from_engine(sha).to_byte_array()
227                 };
228                 let commit_append_rev_hash_key = {
229                         let mut sha = Sha256::engine();
230                         sha.input(&per_commitment_point.serialize());
231                         sha.input(&countersignatory_basepoint.to_public_key().serialize());
232
233                         Sha256::from_engine(sha).to_byte_array()
234                 };
235
236                 let countersignatory_contrib = countersignatory_basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap())
237                         .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
238                 let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap())
239                         .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
240                 let pk = countersignatory_contrib.combine(&broadcaster_contrib)
241                         .expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key.");
242                 Self(pk)
243         }
244
245         /// Get inner Public Key
246         pub fn to_public_key(&self) -> PublicKey {
247                 self.0
248         }
249 }
250 key_read_write!(RevocationKey);
251
252 #[cfg(test)]
253 mod test {
254         use super::derive_public_key;
255         use bitcoin::hashes::hex::FromHex;
256         use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
257
258         #[test]
259         fn test_key_derivation() {
260                 // Test vectors from BOLT 3 Appendix E:
261                 let secp_ctx = Secp256k1::new();
262
263                 let base_secret = SecretKey::from_slice(
264                         &<Vec<u8>>::from_hex(
265                                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
266                         )
267                         .unwrap()[..],
268                 )
269                 .unwrap();
270                 let per_commitment_secret = SecretKey::from_slice(
271                         &<Vec<u8>>::from_hex(
272                                 "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
273                         )
274                         .unwrap()[..],
275                 )
276                 .unwrap();
277
278                 let base_point = PublicKey::from_secret_key(&secp_ctx, &base_secret);
279                 assert_eq!(
280                         base_point.serialize()[..],
281                         <Vec<u8>>::from_hex(
282                                 "036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2"
283                         )
284                         .unwrap()[..]
285                 );
286
287                 let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
288                 assert_eq!(
289                         per_commitment_point.serialize()[..],
290                         <Vec<u8>>::from_hex(
291                                 "025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486"
292                         )
293                         .unwrap()[..]
294                 );
295
296                 assert_eq!(
297                         derive_public_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..],
298                         <Vec<u8>>::from_hex(
299                                 "0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5"
300                         )
301                         .unwrap()[..]
302                 );
303         }
304 }