Implement Script for Witness and Add Tweak in PSBT.
[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 a per-commitment-transaction (eg an htlc key or delayed_payment key) private key addition tweak
42                         /// from a basepoint and a per_commitment_point:
43                         /// `privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)`
44                         /// This calculates the hash part in the tweak derivation process, which is used to ensure
45                         /// that each key is unique and cannot be guessed by an external party. It is equivalent
46                         /// to the `from_basepoint` method, but without the addition operation, providing just the
47                         /// tweak from the hash of the per_commitment_point and the basepoint.
48                         pub fn derive_add_tweak(&self, per_commitment_point: &PublicKey) -> [u8; 32] {
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).to_byte_array()
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).to_byte_array();
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 pub fn add_public_key_tweak<T: secp256k1::Signing>(
176         secp_ctx: &Secp256k1<T>, base_point: &PublicKey, tweak: &[u8; 32],
177 ) -> PublicKey {
178         let hashkey = PublicKey::from_secret_key(
179                 &secp_ctx,
180                 &SecretKey::from_slice(tweak)
181                         .expect("Hashes should always be valid keys unless SHA-256 is broken"),
182         );
183         base_point.combine(&hashkey)
184                 .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.")
185 }
186
187 /// 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.
188 /// A watcher can be given a [RevocationBasepoint] to generate per commitment [RevocationKey] to create justice transactions.
189 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
190 pub struct RevocationBasepoint(pub PublicKey);
191 basepoint_impl!(RevocationBasepoint);
192 key_read_write!(RevocationBasepoint);
193
194 /// The revocation key is used to allow a channel party to revoke their state - giving their
195 /// counterparty the required material to claim all of their funds if they broadcast that state.
196 ///
197 /// Each commitment transaction has a revocation key based on the basepoint and
198 /// per_commitment_point which is used in both commitment and HTLC transactions.
199 ///
200 /// See [the BOLT spec for derivation details]
201 /// (https://github.com/lightning/bolts/blob/master/03-transactions.md#revocationpubkey-derivation)
202 #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
203 pub struct RevocationKey(pub PublicKey);
204
205 impl RevocationKey {
206         /// Derives a per-commitment-transaction revocation public key from one party's per-commitment
207         /// point and the other party's [`RevocationBasepoint`]. This is the public equivalent of
208         /// [`chan_utils::derive_private_revocation_key`] - using only public keys to derive a public
209         /// key instead of private keys.
210         ///
211         /// Note that this is infallible iff we trust that at least one of the two input keys are randomly
212         /// generated (ie our own).
213         ///
214         /// [`chan_utils::derive_private_revocation_key`]: crate::ln::chan_utils::derive_private_revocation_key
215         pub fn from_basepoint<T: secp256k1::Verification>(
216                 secp_ctx: &Secp256k1<T>, countersignatory_basepoint: &RevocationBasepoint,
217                 per_commitment_point: &PublicKey,
218         ) -> Self {
219                 let rev_append_commit_hash_key = {
220                         let mut sha = Sha256::engine();
221                         sha.input(&countersignatory_basepoint.to_public_key().serialize());
222                         sha.input(&per_commitment_point.serialize());
223
224                         Sha256::from_engine(sha).to_byte_array()
225                 };
226                 let commit_append_rev_hash_key = {
227                         let mut sha = Sha256::engine();
228                         sha.input(&per_commitment_point.serialize());
229                         sha.input(&countersignatory_basepoint.to_public_key().serialize());
230
231                         Sha256::from_engine(sha).to_byte_array()
232                 };
233
234                 let countersignatory_contrib = countersignatory_basepoint.to_public_key().mul_tweak(&secp_ctx, &Scalar::from_be_bytes(rev_append_commit_hash_key).unwrap())
235                         .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
236                 let broadcaster_contrib = (&per_commitment_point).mul_tweak(&secp_ctx, &Scalar::from_be_bytes(commit_append_rev_hash_key).unwrap())
237                         .expect("Multiplying a valid public key by a hash is expected to never fail per secp256k1 docs");
238                 let pk = countersignatory_contrib.combine(&broadcaster_contrib)
239                         .expect("Addition only fails if the tweak is the inverse of the key. This is not possible when the tweak commits to the key.");
240                 Self(pk)
241         }
242
243         /// Get inner Public Key
244         pub fn to_public_key(&self) -> PublicKey {
245                 self.0
246         }
247 }
248 key_read_write!(RevocationKey);
249
250 #[cfg(test)]
251 mod test {
252         use super::derive_public_key;
253         use bitcoin::hashes::hex::FromHex;
254         use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
255
256         #[test]
257         fn test_key_derivation() {
258                 // Test vectors from BOLT 3 Appendix E:
259                 let secp_ctx = Secp256k1::new();
260
261                 let base_secret = SecretKey::from_slice(
262                         &<Vec<u8>>::from_hex(
263                                 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
264                         )
265                         .unwrap()[..],
266                 )
267                 .unwrap();
268                 let per_commitment_secret = SecretKey::from_slice(
269                         &<Vec<u8>>::from_hex(
270                                 "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
271                         )
272                         .unwrap()[..],
273                 )
274                 .unwrap();
275
276                 let base_point = PublicKey::from_secret_key(&secp_ctx, &base_secret);
277                 assert_eq!(
278                         base_point.serialize()[..],
279                         <Vec<u8>>::from_hex(
280                                 "036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2"
281                         )
282                         .unwrap()[..]
283                 );
284
285                 let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
286                 assert_eq!(
287                         per_commitment_point.serialize()[..],
288                         <Vec<u8>>::from_hex(
289                                 "025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486"
290                         )
291                         .unwrap()[..]
292                 );
293
294                 assert_eq!(
295                         derive_public_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..],
296                         <Vec<u8>>::from_hex(
297                                 "0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5"
298                         )
299                         .unwrap()[..]
300                 );
301         }
302 }