Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ use util::byte_utils;
use util::ser::{Writeable, Writer, Readable};

use ln::chan_utils;
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::msgs;

use std::sync::atomic::{AtomicUsize, Ordering};
Expand DownExpand Up@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
// TODO: Document the things someone using this interface should enforce before signing.
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
// making the callee generate it via some util function we expose)!
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;

/// Create a signature for a local commitment transaction. This will only ever be called with
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
Expand DownExpand Up@@ -461,8 +461,9 @@ impl ChannelKeys for InMemoryChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { return Err(()); }
let keys = pre_keys.trust_key_derivation();

let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
Expand Down
49 changes: 42 additions & 7 deletions lightning/src/ln/chan_utils.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -267,23 +267,52 @@ pub fn derive_public_revocation_key<T: secp256k1::Verification>(secp_ctx: &Secp2

/// The set of public keys which are used in the creation of one commitment transaction.
/// These are derived from the channel base keys and per-commitment data.
///
/// These keys are assumed to be good, either because the code derived them from
/// channel basepoints via the new function, or they were obtained via
/// PreCalculatedTxCreationKeys.trust_key_derivation because we trusted the source of the
/// pre-calculated keys.
#[derive(PartialEq, Clone)]
pub struct TxCreationKeys {
/// The per-commitment public key which was used to derive the other keys.
pub per_commitment_point: PublicKey,
/// The revocation key which is used to allow the owner of the commitment transaction to
/// provide their counterparty the ability to punish them if they broadcast an old state.
pub(crate) revocation_key: PublicKey,
pub revocation_key: PublicKey,
/// A's HTLC Key
pub(crate) a_htlc_key: PublicKey,
pub a_htlc_key: PublicKey,
/// B's HTLC Key
pub(crate) b_htlc_key: PublicKey,
pub b_htlc_key: PublicKey,
/// A's Payment Key (which isn't allowed to be spent from for some delay)
pub(crate) a_delayed_payment_key: PublicKey,
pub a_delayed_payment_key: PublicKey,
}
impl_writeable!(TxCreationKeys, 33*6,
{ per_commitment_point, revocation_key, a_htlc_key, b_htlc_key, a_delayed_payment_key });

/// The per-commitment point and a set of pre-calculated public keys used for transaction creation
/// in the signer.
/// The pre-calculated keys are an optimization, because ChannelKeys has enough
/// information to re-derive them.
pub struct PreCalculatedTxCreationKeys(TxCreationKeys);

impl PreCalculatedTxCreationKeys {
/// Create a new PreCalculatedTxCreationKeys from TxCreationKeys
pub fn new(keys: TxCreationKeys) -> Self {
PreCalculatedTxCreationKeys(keys)
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.0
}

/// The transaction per-commitment point
pub fn per_comitment_point(&self) -> &PublicKey {
&self.0.per_commitment_point
}
}

/// One counterparty's public keys which do not change over the life of a channel.
#[derive(Clone, PartialEq)]
pub struct ChannelPublicKeys {
Expand DownExpand Up@@ -318,7 +347,8 @@ impl_writeable!(ChannelPublicKeys, 33*5, {


impl TxCreationKeys {
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
/// Create a new TxCreationKeys from channel base points and the per-commitment point
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_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
Ok(TxCreationKeys {
per_commitment_point: per_commitment_point.clone(),
revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
Expand DownExpand Up@@ -510,8 +540,7 @@ pub struct LocalCommitmentTransaction {
// Which order the signatures should go in when constructing the final commitment tx witness.
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
our_sig_first: bool,
/// The key derivation parameters for this commitment transaction
pub local_keys: TxCreationKeys,
pub(crate) local_keys: TxCreationKeys,
/// The feerate paid per 1000-weight-unit in this commitment transaction. This value is
/// controlled by the channel initiator.
pub feerate_per_kw: u32,
Expand DownExpand Up@@ -576,6 +605,12 @@ impl LocalCommitmentTransaction {
}
}

/// The pre-calculated transaction creation public keys.
/// An external validating signer should not trust these keys.
pub fn trust_key_derivation(&self) -> &TxCreationKeys {
&self.local_keys
}

/// Get the txid of the local commitment transaction contained in this
/// LocalCommitmentTransaction
pub fn txid(&self) -> Txid {
Expand Down
14 changes: 9 additions & 5 deletions lightning/src/ln/channel.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
Expand DownExpand Up@@ -1484,7 +1484,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {

let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;

// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
Expand DownExpand Up@@ -3525,7 +3526,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw, logger).0;
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}

Expand DownExpand Up@@ -3878,10 +3880,12 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
htlcs.push(htlc);
}

let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
let remote_keys = pre_remote_keys.trust_key_derivation();

log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
Expand All@@ -3891,7 +3895,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/functional_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,6 +52,7 @@ use std::sync::atomic::Ordering;
use std::{mem, io};

use ln::functional_test_utils::*;
use ln::chan_utils::PreCalculatedTxCreationKeys;

#[test]
fn test_insane_channel_opens() {
Expand DownExpand Up@@ -1694,7 +1695,8 @@ fn test_fee_spike_violation_fails_htlc() {
let local_chan_lock = nodes[0].node.channel_state.lock().unwrap();
let local_chan = local_chan_lock.by_id.get(&chan.2).unwrap();
let local_chan_keys = local_chan.get_local_keys();
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
let pre_commit_tx_keys = PreCalculatedTxCreationKeys::new(commit_tx_keys);
local_chan_keys.sign_remote_commitment(feerate_per_kw, &commit_tx, &pre_commit_tx_keys, &[&accepted_htlc_info], &secp_ctx).unwrap()
};

let commit_signed_msg = msgs::CommitmentSigned {
Expand Down
8 changes: 4 additions & 4 deletions lightning/src/util/enforcing_trait_impls.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction};
use ln::chan_utils::{HTLCOutputInCommitment, TxCreationKeys, ChannelPublicKeys, LocalCommitmentTransaction, PreCalculatedTxCreationKeys};
use ln::{chan_utils, msgs};
use chain::keysinterface::{ChannelKeys, InMemoryChannelKeys};

Expand DownExpand Up@@ -60,9 +60,9 @@ impl ChannelKeys for EnforcingChannelKeys {
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
fn key_derivation_params(&self) -> (u64, u64) { self.inner.key_derivation_params() }

fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, pre_keys: &PreCalculatedTxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
if commitment_tx.input.len() != 1 { panic!("lightning commitment transactions have a single input"); }
self.check_keys(secp_ctx, keys);
self.check_keys(secp_ctx, pre_keys.trust_key_derivation());
let obscured_commitment_transaction_number = (commitment_tx.lock_time & 0xffffff) as u64 | ((commitment_tx.input[0].sequence as u64 & 0xffffff) << 3*8);

{
Expand All@@ -75,7 +75,7 @@ impl ChannelKeys for EnforcingChannelKeys {
commitment_data.1 = cmp::max(commitment_number, commitment_data.1)
}

Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, keys, htlcs, secp_ctx).unwrap())
Ok(self.inner.sign_remote_commitment(feerate_per_kw, commitment_tx, pre_keys, htlcs, secp_ctx).unwrap())
}

fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
Expand Down