Skip to content

Commit f263b37

Browse files
authored
Merge pull request #451 from lightning-signer/txkeys
Provide remote channel public keys to signer
2 parents 0b5b282 + b206492 commit f263b37

File tree

7 files changed

+167
-100
lines changed

7 files changed

+167
-100
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/target/
2+
/hfuzz_target/
23
/net-tokio/target/
34
**/*.rs.bk
45
Cargo.lock

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl KeysInterface for KeyProvider {
158158
delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, self.node_id]).unwrap(),
159159
htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, self.node_id]).unwrap(),
160160
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, self.node_id],
161-
remote_funding_pubkey: None,
161+
remote_channel_pubkeys: None,
162162
})
163163
}
164164

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl KeysInterface for KeyProvider {
257257
delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ctr]).unwrap(),
258258
htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, ctr]).unwrap(),
259259
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, ctr],
260-
remote_funding_pubkey: None,
260+
remote_channel_pubkeys: None,
261261
}
262262
} else {
263263
InMemoryChannelKeys {
@@ -267,7 +267,7 @@ impl KeysInterface for KeyProvider {
267267
delayed_payment_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, ctr]).unwrap(),
268268
htlc_base_key: SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ctr]).unwrap(),
269269
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, ctr],
270-
remote_funding_pubkey: None,
270+
remote_channel_pubkeys: None,
271271
}
272272
})
273273
}

lightning/src/chain/keysinterface.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use util::logger::Logger;
2424
use util::ser::Writeable;
2525

2626
use ln::chan_utils;
27-
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript};
27+
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys};
2828
use ln::msgs;
2929

3030
use std::sync::Arc;
@@ -142,7 +142,7 @@ pub trait ChannelKeys : Send {
142142
/// TODO: Document the things someone using this interface should enforce before signing.
143143
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
144144
/// making the callee generate it via some util function we expose)!
145-
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
145+
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
146146

147147
/// Create a signature for a (proposed) closing transaction.
148148
///
@@ -158,11 +158,11 @@ pub trait ChannelKeys : Send {
158158
/// protocol.
159159
fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
160160

161-
/// Set the remote funding key. This is done immediately on incoming channels
161+
/// Set the remote channel basepoints. This is done immediately on incoming channels
162162
/// and as soon as the channel is accepted on outgoing channels.
163163
///
164164
/// Will be called before any signatures are applied.
165-
fn set_remote_funding_pubkey(&mut self, key: &PublicKey);
165+
fn set_remote_channel_pubkeys(&mut self, channel_points: &ChannelPublicKeys);
166166
}
167167

168168
#[derive(Clone)]
@@ -181,7 +181,7 @@ pub struct InMemoryChannelKeys {
181181
/// Commitment seed
182182
pub commitment_seed: [u8; 32],
183183
/// Remote funding pubkey
184-
pub remote_funding_pubkey: Option<PublicKey>,
184+
pub remote_channel_pubkeys: Option<ChannelPublicKeys>,
185185
}
186186

187187
impl ChannelKeys for InMemoryChannelKeys {
@@ -192,12 +192,12 @@ impl ChannelKeys for InMemoryChannelKeys {
192192
fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key }
193193
fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed }
194194

195-
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
195+
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_value_satoshis: u64, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
196196
if commitment_tx.input.len() != 1 { return Err(()); }
197197

198198
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
199-
let remote_funding_pubkey = self.remote_funding_pubkey.as_ref().expect("must set remote funding key before signing");
200-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, remote_funding_pubkey);
199+
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
200+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
201201

202202
let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, channel_value_satoshis)[..]);
203203
let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key);
@@ -236,9 +236,9 @@ impl ChannelKeys for InMemoryChannelKeys {
236236
Ok(secp_ctx.sign(&msghash, &self.funding_key))
237237
}
238238

239-
fn set_remote_funding_pubkey(&mut self, key: &PublicKey) {
240-
assert!(self.remote_funding_pubkey.is_none(), "Already set remote funding key");
241-
self.remote_funding_pubkey = Some(*key);
239+
fn set_remote_channel_pubkeys(&mut self, channel_pubkeys: &ChannelPublicKeys) {
240+
assert!(self.remote_channel_pubkeys.is_none(), "Already set remote channel pubkeys");
241+
self.remote_channel_pubkeys = Some(channel_pubkeys.clone());
242242
}
243243
}
244244

@@ -249,7 +249,7 @@ impl_writeable!(InMemoryChannelKeys, 0, {
249249
delayed_payment_base_key,
250250
htlc_base_key,
251251
commitment_seed,
252-
remote_funding_pubkey
252+
remote_channel_pubkeys
253253
});
254254

255255
/// Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key
@@ -398,7 +398,7 @@ impl KeysInterface for KeysManager {
398398
delayed_payment_base_key,
399399
htlc_base_key,
400400
commitment_seed,
401-
remote_funding_pubkey: None,
401+
remote_channel_pubkeys: None,
402402
}
403403
}
404404

lightning/src/ln/chan_utils.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use ln::channelmanager::{PaymentHash, PaymentPreimage};
1818
use ln::msgs::DecodeError;
1919
use util::ser::{Readable, Writeable, Writer, WriterWriteAdaptor};
2020

21-
use secp256k1::key::{SecretKey,PublicKey};
21+
use secp256k1::key::{SecretKey, PublicKey};
2222
use secp256k1::{Secp256k1, Signature};
2323
use secp256k1;
2424

@@ -137,24 +137,57 @@ pub(super) fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx:
137137

138138
/// The set of public keys which are used in the creation of one commitment transaction.
139139
/// These are derived from the channel base keys and per-commitment data.
140+
#[derive(PartialEq)]
140141
pub struct TxCreationKeys {
141142
/// The per-commitment public key which was used to derive the other keys.
142143
pub per_commitment_point: PublicKey,
143144
/// The revocation key which is used to allow the owner of the commitment transaction to
144145
/// provide their counterparty the ability to punish them if they broadcast an old state.
145-
pub revocation_key: PublicKey,
146+
pub(crate) revocation_key: PublicKey,
146147
/// A's HTLC Key
147-
pub a_htlc_key: PublicKey,
148+
pub(crate) a_htlc_key: PublicKey,
148149
/// B's HTLC Key
149-
pub b_htlc_key: PublicKey,
150+
pub(crate) b_htlc_key: PublicKey,
150151
/// A's Payment Key (which isn't allowed to be spent from for some delay)
151-
pub a_delayed_payment_key: PublicKey,
152+
pub(crate) a_delayed_payment_key: PublicKey,
152153
/// B's Payment Key
153-
pub b_payment_key: PublicKey,
154+
pub(crate) b_payment_key: PublicKey,
155+
}
156+
157+
/// One counterparty's public keys which do not change over the life of a channel.
158+
#[derive(Clone)]
159+
pub struct ChannelPublicKeys {
160+
/// The public key which is used to sign all commitment transactions, as it appears in the
161+
/// on-chain channel lock-in 2-of-2 multisig output.
162+
pub funding_pubkey: PublicKey,
163+
/// The base point which is used (with derive_public_revocation_key) to derive per-commitment
164+
/// revocation keys. The per-commitment revocation private key is then revealed by the owner of
165+
/// a commitment transaction so that their counterparty can claim all available funds if they
166+
/// broadcast an old state.
167+
pub revocation_basepoint: PublicKey,
168+
/// The base point which is used (with derive_public_key) to derive a per-commitment payment
169+
/// public key which receives immediately-spendable non-HTLC-encumbered funds.
170+
pub payment_basepoint: PublicKey,
171+
/// The base point which is used (with derive_public_key) to derive a per-commitment payment
172+
/// public key which receives non-HTLC-encumbered funds which are only available for spending
173+
/// after some delay (or can be claimed via the revocation path).
174+
pub delayed_payment_basepoint: PublicKey,
175+
/// The base point which is used (with derive_public_key) to derive a per-commitment public key
176+
/// which is used to encumber HTLC-in-flight outputs.
177+
pub htlc_basepoint: PublicKey,
154178
}
155179

180+
impl_writeable!(ChannelPublicKeys, 33*5, {
181+
funding_pubkey,
182+
revocation_basepoint,
183+
payment_basepoint,
184+
delayed_payment_basepoint,
185+
htlc_basepoint
186+
});
187+
188+
156189
impl TxCreationKeys {
157-
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> {
190+
pub(crate) 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> {
158191
Ok(TxCreationKeys {
159192
per_commitment_point: per_commitment_point.clone(),
160193
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,

0 commit comments

Comments
 (0)