1 //! Various utilities for building scripts and deriving keys related to channels. These are
2 //! largely of interest for those implementing chain::keysinterface::ChannelKeys message signing
5 use bitcoin::blockdata::script::{Script,Builder};
6 use bitcoin::blockdata::opcodes;
7 use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction};
9 use bitcoin_hashes::{Hash, HashEngine};
10 use bitcoin_hashes::sha256::Hash as Sha256;
11 use bitcoin_hashes::ripemd160::Hash as Ripemd160;
12 use bitcoin_hashes::hash160::Hash as Hash160;
13 use bitcoin_hashes::sha256d::Hash as Sha256dHash;
15 use ln::channelmanager::PaymentHash;
17 use secp256k1::key::{PublicKey,SecretKey};
18 use secp256k1::Secp256k1;
21 pub(super) const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
22 pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
24 // Various functions for key derivation and transaction creation for use within channels. Primarily
25 // used in Channel and ChannelMonitor.
27 pub(super) fn build_commitment_secret(commitment_seed: &[u8; 32], idx: u64) -> [u8; 32] {
28 let mut res: [u8; 32] = commitment_seed.clone();
31 if idx & (1 << bitpos) == (1 << bitpos) {
32 res[bitpos / 8] ^= 1 << (bitpos & 7);
33 res = Sha256::hash(&res).into_inner();
39 /// Derives a per-commitment-transaction private key (eg an htlc key or payment key) from the base
40 /// private key for that type of key and the per_commitment_point (available in TxCreationKeys)
41 pub fn derive_private_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
42 let mut sha = Sha256::engine();
43 sha.input(&per_commitment_point.serialize());
44 sha.input(&PublicKey::from_secret_key(&secp_ctx, &base_secret).serialize());
45 let res = Sha256::from_engine(sha).into_inner();
47 let mut key = base_secret.clone();
48 key.add_assign(&res)?;
52 pub(super) fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
53 let mut sha = Sha256::engine();
54 sha.input(&per_commitment_point.serialize());
55 sha.input(&base_point.serialize());
56 let res = Sha256::from_engine(sha).into_inner();
58 let hashkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&res)?);
59 base_point.combine(&hashkey)
62 /// Derives a revocation key from its constituent parts
63 pub(super) fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_commitment_secret: &SecretKey, revocation_base_secret: &SecretKey) -> Result<SecretKey, secp256k1::Error> {
64 let revocation_base_point = PublicKey::from_secret_key(&secp_ctx, &revocation_base_secret);
65 let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
67 let rev_append_commit_hash_key = {
68 let mut sha = Sha256::engine();
69 sha.input(&revocation_base_point.serialize());
70 sha.input(&per_commitment_point.serialize());
72 Sha256::from_engine(sha).into_inner()
74 let commit_append_rev_hash_key = {
75 let mut sha = Sha256::engine();
76 sha.input(&per_commitment_point.serialize());
77 sha.input(&revocation_base_point.serialize());
79 Sha256::from_engine(sha).into_inner()
82 let mut part_a = revocation_base_secret.clone();
83 part_a.mul_assign(&rev_append_commit_hash_key)?;
84 let mut part_b = per_commitment_secret.clone();
85 part_b.mul_assign(&commit_append_rev_hash_key)?;
86 part_a.add_assign(&part_b[..])?;
90 pub(super) fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, revocation_base_point: &PublicKey) -> Result<PublicKey, secp256k1::Error> {
91 let rev_append_commit_hash_key = {
92 let mut sha = Sha256::engine();
93 sha.input(&revocation_base_point.serialize());
94 sha.input(&per_commitment_point.serialize());
96 Sha256::from_engine(sha).into_inner()
98 let commit_append_rev_hash_key = {
99 let mut sha = Sha256::engine();
100 sha.input(&per_commitment_point.serialize());
101 sha.input(&revocation_base_point.serialize());
103 Sha256::from_engine(sha).into_inner()
106 let mut part_a = revocation_base_point.clone();
107 part_a.mul_assign(&secp_ctx, &rev_append_commit_hash_key)?;
108 let mut part_b = per_commitment_point.clone();
109 part_b.mul_assign(&secp_ctx, &commit_append_rev_hash_key)?;
110 part_a.combine(&part_b)
113 /// The set of public keys which are used in the creation of one commitment transaction.
114 /// These are derived from the channel base keys and per-commitment data.
115 pub struct TxCreationKeys {
116 /// The per-commitment public key which was used to derive the other keys.
117 pub per_commitment_point: PublicKey,
118 /// The revocation key which is used to allow the owner of the commitment transaction to
119 /// provide their counterparty the ability to punish them if they broadcast an old state.
120 pub revocation_key: PublicKey,
122 pub a_htlc_key: PublicKey,
124 pub b_htlc_key: PublicKey,
125 /// A's Payment Key (which isn't allowed to be spent from for some delay)
126 pub a_delayed_payment_key: PublicKey,
128 pub b_payment_key: PublicKey,
131 impl TxCreationKeys {
132 pub(super) 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> {
134 per_commitment_point: per_commitment_point.clone(),
135 revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
136 a_htlc_key: derive_public_key(&secp_ctx, &per_commitment_point, &a_htlc_base)?,
137 b_htlc_key: derive_public_key(&secp_ctx, &per_commitment_point, &b_htlc_base)?,
138 a_delayed_payment_key: derive_public_key(&secp_ctx, &per_commitment_point, &a_delayed_payment_base)?,
139 b_payment_key: derive_public_key(&secp_ctx, &per_commitment_point, &b_payment_base)?,
144 /// Gets the "to_local" output redeemscript, ie the script which is time-locked or spendable by
145 /// the revocation key
146 pub(super) fn get_revokeable_redeemscript(revocation_key: &PublicKey, to_self_delay: u16, delayed_payment_key: &PublicKey) -> Script {
147 Builder::new().push_opcode(opcodes::all::OP_IF)
148 .push_slice(&revocation_key.serialize())
149 .push_opcode(opcodes::all::OP_ELSE)
150 .push_int(to_self_delay as i64)
151 .push_opcode(opcodes::all::OP_CSV)
152 .push_opcode(opcodes::all::OP_DROP)
153 .push_slice(&delayed_payment_key.serialize())
154 .push_opcode(opcodes::all::OP_ENDIF)
155 .push_opcode(opcodes::all::OP_CHECKSIG)
159 #[derive(Clone, PartialEq)]
160 /// Information about an HTLC as it appears in a commitment transaction
161 pub struct HTLCOutputInCommitment {
162 /// Whether the HTLC was "offered" (ie outbound in relation to this commitment transaction).
163 /// Note that this is not the same as whether it is ountbound *from us*. To determine that you
164 /// need to compare this value to whether the commitment transaction in question is that of
165 /// the remote party or our own.
167 /// The value, in msat, of the HTLC. The value as it appears in the commitment transaction is
168 /// this divided by 1000.
169 pub amount_msat: u64,
170 /// The CLTV lock-time at which this HTLC expires.
171 pub cltv_expiry: u32,
172 /// The hash of the preimage which unlocks this HTLC.
173 pub payment_hash: PaymentHash,
174 /// The position within the commitment transactions' outputs. This may be None if the value is
175 /// below the dust limit (in which case no output appears in the commitment transaction and the
176 /// value is spent to additional transaction fees).
177 pub transaction_output_index: Option<u32>,
181 pub(super) fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, a_htlc_key: &PublicKey, b_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script {
182 let payment_hash160 = Ripemd160::hash(&htlc.payment_hash.0[..]).into_inner();
184 Builder::new().push_opcode(opcodes::all::OP_DUP)
185 .push_opcode(opcodes::all::OP_HASH160)
186 .push_slice(&Hash160::hash(&revocation_key.serialize())[..])
187 .push_opcode(opcodes::all::OP_EQUAL)
188 .push_opcode(opcodes::all::OP_IF)
189 .push_opcode(opcodes::all::OP_CHECKSIG)
190 .push_opcode(opcodes::all::OP_ELSE)
191 .push_slice(&b_htlc_key.serialize()[..])
192 .push_opcode(opcodes::all::OP_SWAP)
193 .push_opcode(opcodes::all::OP_SIZE)
195 .push_opcode(opcodes::all::OP_EQUAL)
196 .push_opcode(opcodes::all::OP_NOTIF)
197 .push_opcode(opcodes::all::OP_DROP)
199 .push_opcode(opcodes::all::OP_SWAP)
200 .push_slice(&a_htlc_key.serialize()[..])
202 .push_opcode(opcodes::all::OP_CHECKMULTISIG)
203 .push_opcode(opcodes::all::OP_ELSE)
204 .push_opcode(opcodes::all::OP_HASH160)
205 .push_slice(&payment_hash160)
206 .push_opcode(opcodes::all::OP_EQUALVERIFY)
207 .push_opcode(opcodes::all::OP_CHECKSIG)
208 .push_opcode(opcodes::all::OP_ENDIF)
209 .push_opcode(opcodes::all::OP_ENDIF)
212 Builder::new().push_opcode(opcodes::all::OP_DUP)
213 .push_opcode(opcodes::all::OP_HASH160)
214 .push_slice(&Hash160::hash(&revocation_key.serialize())[..])
215 .push_opcode(opcodes::all::OP_EQUAL)
216 .push_opcode(opcodes::all::OP_IF)
217 .push_opcode(opcodes::all::OP_CHECKSIG)
218 .push_opcode(opcodes::all::OP_ELSE)
219 .push_slice(&b_htlc_key.serialize()[..])
220 .push_opcode(opcodes::all::OP_SWAP)
221 .push_opcode(opcodes::all::OP_SIZE)
223 .push_opcode(opcodes::all::OP_EQUAL)
224 .push_opcode(opcodes::all::OP_IF)
225 .push_opcode(opcodes::all::OP_HASH160)
226 .push_slice(&payment_hash160)
227 .push_opcode(opcodes::all::OP_EQUALVERIFY)
229 .push_opcode(opcodes::all::OP_SWAP)
230 .push_slice(&a_htlc_key.serialize()[..])
232 .push_opcode(opcodes::all::OP_CHECKMULTISIG)
233 .push_opcode(opcodes::all::OP_ELSE)
234 .push_opcode(opcodes::all::OP_DROP)
235 .push_int(htlc.cltv_expiry as i64)
236 .push_opcode(opcodes::all::OP_CLTV)
237 .push_opcode(opcodes::all::OP_DROP)
238 .push_opcode(opcodes::all::OP_CHECKSIG)
239 .push_opcode(opcodes::all::OP_ENDIF)
240 .push_opcode(opcodes::all::OP_ENDIF)
245 /// note here that 'a_revocation_key' is generated using b_revocation_basepoint and a's
246 /// commitment secret. 'htlc' does *not* need to have its previous_output_index filled.
248 pub fn get_htlc_redeemscript(htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Script {
249 get_htlc_redeemscript_with_explicit_keys(htlc, &keys.a_htlc_key, &keys.b_htlc_key, &keys.revocation_key)
252 /// panics if htlc.transaction_output_index.is_none()!
253 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 {
254 let mut txins: Vec<TxIn> = Vec::new();
256 previous_output: OutPoint {
257 txid: prev_hash.clone(),
258 vout: htlc.transaction_output_index.expect("Can't build an HTLC transaction for a dust output"),
260 script_sig: Script::new(),
265 let total_fee = if htlc.offered {
266 feerate_per_kw * HTLC_TIMEOUT_TX_WEIGHT / 1000
268 feerate_per_kw * HTLC_SUCCESS_TX_WEIGHT / 1000
271 let mut txouts: Vec<TxOut> = Vec::new();
273 script_pubkey: get_revokeable_redeemscript(revocation_key, to_self_delay, a_delayed_payment_key).to_v0_p2wsh(),
274 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)
279 lock_time: if htlc.offered { htlc.cltv_expiry } else { 0 },