Switch Sha256 to using bitcoin_hashes and our own HKDF
[rust-lightning] / src / ln / chan_utils.rs
1 use bitcoin::blockdata::script::{Script,Builder};
2 use bitcoin::blockdata::opcodes;
3 use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction};
4 use bitcoin::util::hash::{Hash160,Sha256dHash};
5
6 use bitcoin_hashes::{Hash, HashEngine};
7 use bitcoin_hashes::sha256::Hash as Sha256;
8
9 use ln::channelmanager::PaymentHash;
10
11 use secp256k1::key::{PublicKey,SecretKey};
12 use secp256k1::Secp256k1;
13 use secp256k1;
14
15 use crypto::digest::Digest;
16 use crypto::ripemd160::Ripemd160;
17
18 pub const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
19 pub const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
20
21 // Various functions for key derivation and transaction creation for use within channels. Primarily
22 // used in Channel and ChannelMonitor.
23
24 pub fn build_commitment_secret(commitment_seed: [u8; 32], idx: u64) -> [u8; 32] {
25         let mut res: [u8; 32] = commitment_seed;
26         for i in 0..48 {
27                 let bitpos = 47 - i;
28                 if idx & (1 << bitpos) == (1 << bitpos) {
29                         res[bitpos / 8] ^= 1 << (bitpos & 7);
30                         res = Sha256::hash(&res).into_inner();
31                 }
32         }
33         res
34 }
35
36 pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
37         let mut sha = Sha256::engine();
38         sha.input(&per_commitment_point.serialize());
39         sha.input(&PublicKey::from_secret_key(&secp_ctx, &base_secret).serialize());
40         let res = Sha256::from_engine(sha).into_inner();
41
42         let mut key = base_secret.clone();
43         key.add_assign(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &res)?)?;
44         Ok(key)
45 }
46
47 pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
48         let mut sha = Sha256::engine();
49         sha.input(&per_commitment_point.serialize());
50         sha.input(&base_point.serialize());
51         let res = Sha256::from_engine(sha).into_inner();
52
53         let hashkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &res)?);
54         base_point.combine(&secp_ctx, &hashkey)
55 }
56
57 /// Derives a revocation key from its constituent parts
58 pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
59         let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret);
60         let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
61
62         let rev_append_commit_hash_key = {
63                 let mut sha = Sha256::engine();
64                 sha.input(&revocation_base_point.serialize());
65                 sha.input(&per_commitment_point.serialize());
66
67                 SecretKey::from_slice(&secp_ctx, &Sha256::from_engine(sha).into_inner())?
68         };
69         let commit_append_rev_hash_key = {
70                 let mut sha = Sha256::engine();
71                 sha.input(&per_commitment_point.serialize());
72                 sha.input(&revocation_base_point.serialize());
73
74                 SecretKey::from_slice(&secp_ctx, &Sha256::from_engine(sha).into_inner())?
75         };
76
77         let mut part_a = revocation_base_secret.clone();
78         part_a.mul_assign(&secp_ctx, &rev_append_commit_hash_key)?;
79         let mut part_b = per_commitment_secret.clone();
80         part_b.mul_assign(&secp_ctx, &commit_append_rev_hash_key)?;
81         part_a.add_assign(&secp_ctx, &part_b)?;
82         Ok(part_a)
83 }
84
85 pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
86         let rev_append_commit_hash_key = {
87                 let mut sha = Sha256::engine();
88                 sha.input(&revocation_base_point.serialize());
89                 sha.input(&per_commitment_point.serialize());
90
91                 SecretKey::from_slice(&secp_ctx, &Sha256::from_engine(sha).into_inner())?
92         };
93         let commit_append_rev_hash_key = {
94                 let mut sha = Sha256::engine();
95                 sha.input(&per_commitment_point.serialize());
96                 sha.input(&revocation_base_point.serialize());
97
98                 SecretKey::from_slice(&secp_ctx, &Sha256::from_engine(sha).into_inner())?
99         };
100
101         let mut part_a = revocation_base_point.clone();
102         part_a.mul_assign(&secp_ctx, &rev_append_commit_hash_key)?;
103         let mut part_b = per_commitment_point.clone();
104         part_b.mul_assign(&secp_ctx, &commit_append_rev_hash_key)?;
105         part_a.combine(&secp_ctx, &part_b)
106 }
107
108 pub struct TxCreationKeys {
109         pub per_commitment_point: PublicKey,
110         pub revocation_key: PublicKey,
111         pub a_htlc_key: PublicKey,
112         pub b_htlc_key: PublicKey,
113         pub a_delayed_payment_key: PublicKey,
114         pub b_payment_key: PublicKey,
115 }
116
117 impl TxCreationKeys {
118         pub fn new<T: secp256k1::Signing + secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_payment_base: &PublicKey, b_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
119                 Ok(TxCreationKeys {
120                         per_commitment_point: per_commitment_point.clone(),
121                         revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
122                         a_htlc_key: derive_public_key(&secp_ctx, &per_commitment_point, &a_htlc_base)?,
123                         b_htlc_key: derive_public_key(&secp_ctx, &per_commitment_point, &b_htlc_base)?,
124                         a_delayed_payment_key: derive_public_key(&secp_ctx, &per_commitment_point, &a_delayed_payment_base)?,
125                         b_payment_key: derive_public_key(&secp_ctx, &per_commitment_point, &b_payment_base)?,
126                 })
127         }
128 }
129
130 /// Gets the "to_local" output redeemscript, ie the script which is time-locked or spendable by
131 /// the revocation key
132 pub fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script {
133         Builder::new().push_opcode(opcodes::All::OP_IF)
134                       .push_slice(&revocation_key.serialize())
135                       .push_opcode(opcodes::All::OP_ELSE)
136                       .push_int(to_self_delay as i64)
137                       .push_opcode(opcodes::OP_CSV)
138                       .push_opcode(opcodes::All::OP_DROP)
139                       .push_slice(&delayed_payment_key.serialize())
140                       .push_opcode(opcodes::All::OP_ENDIF)
141                       .push_opcode(opcodes::All::OP_CHECKSIG)
142                       .into_script()
143 }
144
145 #[derive(Clone, PartialEq)]
146 pub struct HTLCOutputInCommitment {
147         pub offered: bool,
148         pub amount_msat: u64,
149         pub cltv_expiry: u32,
150         pub payment_hash: PaymentHash,
151         pub transaction_output_index: u32,
152 }
153
154 #[inline]
155 pub fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, a_htlc_key: &PublicKey, b_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script {
156         let payment_hash160 = {
157                 let mut ripemd = Ripemd160::new();
158                 ripemd.input(&htlc.payment_hash.0[..]);
159                 let mut res = [0; 20];
160                 ripemd.result(&mut res);
161                 res
162         };
163         if htlc.offered {
164                 Builder::new().push_opcode(opcodes::All::OP_DUP)
165                               .push_opcode(opcodes::All::OP_HASH160)
166                               .push_slice(&Hash160::from_data(&revocation_key.serialize())[..])
167                               .push_opcode(opcodes::All::OP_EQUAL)
168                               .push_opcode(opcodes::All::OP_IF)
169                               .push_opcode(opcodes::All::OP_CHECKSIG)
170                               .push_opcode(opcodes::All::OP_ELSE)
171                               .push_slice(&b_htlc_key.serialize()[..])
172                               .push_opcode(opcodes::All::OP_SWAP)
173                               .push_opcode(opcodes::All::OP_SIZE)
174                               .push_int(32)
175                               .push_opcode(opcodes::All::OP_EQUAL)
176                               .push_opcode(opcodes::All::OP_NOTIF)
177                               .push_opcode(opcodes::All::OP_DROP)
178                               .push_int(2)
179                               .push_opcode(opcodes::All::OP_SWAP)
180                               .push_slice(&a_htlc_key.serialize()[..])
181                               .push_int(2)
182                               .push_opcode(opcodes::All::OP_CHECKMULTISIG)
183                               .push_opcode(opcodes::All::OP_ELSE)
184                               .push_opcode(opcodes::All::OP_HASH160)
185                               .push_slice(&payment_hash160)
186                               .push_opcode(opcodes::All::OP_EQUALVERIFY)
187                               .push_opcode(opcodes::All::OP_CHECKSIG)
188                               .push_opcode(opcodes::All::OP_ENDIF)
189                               .push_opcode(opcodes::All::OP_ENDIF)
190                               .into_script()
191         } else {
192                 Builder::new().push_opcode(opcodes::All::OP_DUP)
193                               .push_opcode(opcodes::All::OP_HASH160)
194                               .push_slice(&Hash160::from_data(&revocation_key.serialize())[..])
195                               .push_opcode(opcodes::All::OP_EQUAL)
196                               .push_opcode(opcodes::All::OP_IF)
197                               .push_opcode(opcodes::All::OP_CHECKSIG)
198                               .push_opcode(opcodes::All::OP_ELSE)
199                               .push_slice(&b_htlc_key.serialize()[..])
200                               .push_opcode(opcodes::All::OP_SWAP)
201                               .push_opcode(opcodes::All::OP_SIZE)
202                               .push_int(32)
203                               .push_opcode(opcodes::All::OP_EQUAL)
204                               .push_opcode(opcodes::All::OP_IF)
205                               .push_opcode(opcodes::All::OP_HASH160)
206                               .push_slice(&payment_hash160)
207                               .push_opcode(opcodes::All::OP_EQUALVERIFY)
208                               .push_int(2)
209                               .push_opcode(opcodes::All::OP_SWAP)
210                               .push_slice(&a_htlc_key.serialize()[..])
211                               .push_int(2)
212                               .push_opcode(opcodes::All::OP_CHECKMULTISIG)
213                               .push_opcode(opcodes::All::OP_ELSE)
214                               .push_opcode(opcodes::All::OP_DROP)
215                               .push_int(htlc.cltv_expiry as i64)
216                               .push_opcode(opcodes::OP_CLTV)
217                               .push_opcode(opcodes::All::OP_DROP)
218                               .push_opcode(opcodes::All::OP_CHECKSIG)
219                               .push_opcode(opcodes::All::OP_ENDIF)
220                               .push_opcode(opcodes::All::OP_ENDIF)
221                               .into_script()
222         }
223 }
224
225 /// note here that 'a_revocation_key' is generated using b_revocation_basepoint and a's
226 /// commitment secret. 'htlc' does *not* need to have its previous_output_index filled.
227 #[inline]
228 pub fn get_htlc_redeemscript(htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Script {
229         get_htlc_redeemscript_with_explicit_keys(htlc, &keys.a_htlc_key, &keys.b_htlc_key, &keys.revocation_key)
230 }
231
232 pub fn build_htlc_transaction(prev_hash: &Sha256dHash, feerate_per_kw: u64, to_self_delay: u16, htlc: &HTLCOutputInCommitment, a_delayed_payment_key: &PublicKey, revocation_key: &PublicKey) -> Transaction {
233         let mut txins: Vec<TxIn> = Vec::new();
234         txins.push(TxIn {
235                 previous_output: OutPoint {
236                         txid: prev_hash.clone(),
237                         vout: htlc.transaction_output_index,
238                 },
239                 script_sig: Script::new(),
240                 sequence: 0,
241                 witness: Vec::new(),
242         });
243
244         let total_fee = if htlc.offered {
245                         feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000
246                 } else {
247                         feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000
248                 };
249
250         let mut txouts: Vec<TxOut> = Vec::new();
251         txouts.push(TxOut {
252                 script_pubkey: get_revokeable_redeemscript(revocation_key, to_self_delay, a_delayed_payment_key).to_v0_p2wsh(),
253                 value: htlc.amount_msat / 1000 - total_fee //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here)
254         });
255
256         Transaction {
257                 version: 2,
258                 lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 },
259                 input: txins,
260                 output: txouts,
261         }
262 }