Skip to content

Commit 3de8c72

Browse files
committed
Introduce SharedSecretProduce
1 parent ca163c3 commit 3de8c72

File tree

9 files changed

+270
-121
lines changed

9 files changed

+270
-121
lines changed

lightning-background-processor/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ mod tests {
345345
use bitcoin::network::constants::Network;
346346
use lightning::chain::{BestBlock, Confirm, chainmonitor};
347347
use lightning::chain::channelmonitor::ANTI_REORG_DELAY;
348-
use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeysInterface, KeysManager};
348+
use lightning::chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager};
349349
use lightning::chain::transaction::OutPoint;
350350
use lightning::get_event_msg;
351351
use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager};
@@ -428,7 +428,7 @@ mod tests {
428428
let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash()));
429429
let net_graph_msg_handler = Some(Arc::new(NetGraphMsgHandler::new(network_graph.clone(), Some(chain_source.clone()), logger.clone())));
430430
let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )};
431-
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), &seed, logger.clone(), IgnoringMessageHandler{}));
431+
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_shared_secret_producer(), &seed, logger.clone(), IgnoringMessageHandler{}));
432432
let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block };
433433
nodes.push(node);
434434
}

lightning-net-tokio/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ mod tests {
475475
use std::sync::atomic::{AtomicBool, Ordering};
476476
use std::sync::{Arc, Mutex};
477477
use std::time::Duration;
478+
use lightning::chain::keysinterface::EphemeralSharedSecretProducer;
478479

479480
pub struct TestLogger();
480481
impl lightning::util::logger::Logger for TestLogger {
@@ -560,7 +561,7 @@ mod tests {
560561
let a_manager = Arc::new(PeerManager::new(MessageHandler {
561562
chan_handler: Arc::clone(&a_handler),
562563
route_handler: Arc::clone(&a_handler),
563-
}, a_key.clone(), &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
564+
}, EphemeralSharedSecretProducer::new(a_key.clone()), &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
564565

565566
let (b_connected_sender, mut b_connected) = mpsc::channel(1);
566567
let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1);
@@ -574,7 +575,7 @@ mod tests {
574575
let b_manager = Arc::new(PeerManager::new(MessageHandler {
575576
chan_handler: Arc::clone(&b_handler),
576577
route_handler: Arc::clone(&b_handler),
577-
}, b_key.clone(), &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
578+
}, EphemeralSharedSecretProducer::new(b_key.clone()), &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
578579

579580
// We bind on localhost, hoping the environment is properly configured with a local
580581
// address. This may not always be the case in containers and the like, so if this test is

lightning/src/chain/keysinterface.rs

Lines changed: 111 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ use bitcoin::hashes::sha256::Hash as Sha256;
2525
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
2626
use bitcoin::hash_types::WPubkeyHash;
2727

28+
use bitcoin::secp256k1::ecdh::SharedSecret;
2829
use bitcoin::secp256k1::key::{SecretKey, PublicKey};
29-
use bitcoin::secp256k1::{Secp256k1, Signature, Signing};
30+
use bitcoin::secp256k1::{Secp256k1, Signature, Signing, All, SignOnly};
3031
use bitcoin::secp256k1::recovery::RecoverableSignature;
3132
use bitcoin::secp256k1;
3233

@@ -37,7 +38,7 @@ use util::ser::{Writeable, Writer, Readable, ReadableArgs};
3738
use chain::transaction::OutPoint;
3839
use ln::{chan_utils, PaymentPreimage};
3940
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
40-
use ln::msgs::UnsignedChannelAnnouncement;
41+
use ln::msgs::{UnsignedChannelAnnouncement, UnsignedChannelUpdate, UnsignedNodeAnnouncement};
4142
use ln::script::ShutdownScript;
4243

4344
use prelude::*;
@@ -392,16 +393,60 @@ pub enum Recipient {
392393
PhantomNode,
393394
}
394395

396+
///
397+
pub trait SharedSecretProduce: Send + Sync {
398+
///
399+
fn public_key(&self, secp_ctx: &secp256k1::Secp256k1<SignOnly>) -> PublicKey;
400+
///
401+
fn shared_secret(&self, other: &PublicKey) -> SharedSecret;
402+
///
403+
fn do_clone(&self) -> Box<dyn SharedSecretProduce>;
404+
}
405+
406+
///
407+
pub struct EphemeralSharedSecretProducer {
408+
///
409+
pub secret_key: SecretKey
410+
}
411+
412+
impl SharedSecretProduce for EphemeralSharedSecretProducer {
413+
fn public_key(&self, secp_ctx: &Secp256k1<SignOnly>) -> PublicKey {
414+
PublicKey::from_secret_key(&secp_ctx, &self.secret_key)
415+
}
416+
417+
fn shared_secret(&self, other: &PublicKey) -> SharedSecret {
418+
SharedSecret::new(other, &self.secret_key)
419+
}
420+
421+
fn do_clone(&self) -> Box<dyn SharedSecretProduce> {
422+
Box::new(Self { secret_key: self.secret_key })
423+
}
424+
}
425+
426+
impl EphemeralSharedSecretProducer {
427+
///
428+
pub fn new(secret_key: SecretKey) -> Box<dyn SharedSecretProduce> {
429+
Box::new( Self { secret_key })
430+
}
431+
}
432+
395433
/// A trait to describe an object which can get user secrets and key material.
396434
pub trait KeysInterface {
397435
/// A type which implements Sign which will be returned by get_channel_signer.
398436
type Signer : Sign;
399437

400-
/// Get node secret key (aka node_id or network_key) based on the provided [`Recipient`].
438+
/// A shared secret producer using the node key
439+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce>;
440+
441+
/// ECDH
442+
fn shared_secret(&self, recipient: Recipient, other: &PublicKey) -> Result<SharedSecret, ()>;
443+
444+
/// Get node public key (AKA node ID)
401445
///
402446
/// This method must return the same value each time it is called with a given `Recipient`
403447
/// parameter.
404-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
448+
fn get_node_key(&self, recipient: Recipient, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<PublicKey, ()>;
449+
405450
/// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
406451
///
407452
/// This method should return a different value each time it is called, to avoid linking
@@ -441,6 +486,12 @@ pub trait KeysInterface {
441486
/// The secret key used to sign the invoice is dependent on the [`Recipient`].
442487
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result<RecoverableSignature, ()>;
443488

489+
/// Sign a node announcement
490+
fn sign_node_announcement(&self, msg: &UnsignedNodeAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
491+
492+
/// Sign a channel update
493+
fn sign_channel_update(&self, msg: &UnsignedChannelUpdate, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
494+
444495
/// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
445496
///
446497
/// If the implementor of this trait supports [phantom node payments], then every node that is
@@ -1118,17 +1169,21 @@ impl KeysManager {
11181169

11191170
Ok(spend_tx)
11201171
}
1121-
}
1122-
1123-
impl KeysInterface for KeysManager {
1124-
type Signer = InMemorySigner;
11251172

11261173
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
11271174
match recipient {
11281175
Recipient::Node => Ok(self.node_secret.clone()),
11291176
Recipient::PhantomNode => Err(())
11301177
}
11311178
}
1179+
}
1180+
1181+
impl KeysInterface for KeysManager {
1182+
type Signer = InMemorySigner;
1183+
1184+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> {
1185+
EphemeralSharedSecretProducer::new(self.node_secret)
1186+
}
11321187

11331188
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
11341189
self.inbound_payment_key.clone()
@@ -1169,12 +1224,30 @@ impl KeysInterface for KeysManager {
11691224

11701225
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
11711226
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
1172-
let secret = match recipient {
1173-
Recipient::Node => self.get_node_secret(Recipient::Node)?,
1174-
Recipient::PhantomNode => return Err(()),
1175-
};
1227+
let secret = self.get_node_secret(recipient)?;
11761228
Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
11771229
}
1230+
1231+
fn sign_node_announcement(&self, msg: &UnsignedNodeAnnouncement, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> {
1232+
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
1233+
Ok(secp_ctx.sign(&msghash, &self.node_secret))
1234+
1235+
}
1236+
1237+
fn sign_channel_update(&self, msg: &UnsignedChannelUpdate, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> {
1238+
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
1239+
Ok(secp_ctx.sign(&msghash, &self.node_secret))
1240+
}
1241+
1242+
fn shared_secret(&self, recipient: Recipient, other: &PublicKey) -> Result<SharedSecret, ()> {
1243+
let secret = self.get_node_secret(recipient)?;
1244+
Ok(SharedSecret::new(other, &secret))
1245+
}
1246+
1247+
fn get_node_key(&self, recipient: Recipient, secp_ctx: &Secp256k1<All>) -> Result<PublicKey, ()> {
1248+
let secret = self.get_node_secret(recipient)?;
1249+
Ok(PublicKey::from_secret_key(&secp_ctx, &secret))
1250+
}
11781251
}
11791252

11801253
/// Similar to [`KeysManager`], but allows the node using this struct to receive phantom node
@@ -1207,11 +1280,8 @@ pub struct PhantomKeysManager {
12071280
impl KeysInterface for PhantomKeysManager {
12081281
type Signer = InMemorySigner;
12091282

1210-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
1211-
match recipient {
1212-
Recipient::Node => self.inner.get_node_secret(Recipient::Node),
1213-
Recipient::PhantomNode => Ok(self.phantom_secret.clone()),
1214-
}
1283+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> {
1284+
EphemeralSharedSecretProducer::new(self.inner.node_secret)
12151285
}
12161286

12171287
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
@@ -1243,6 +1313,23 @@ impl KeysInterface for PhantomKeysManager {
12431313
let secret = self.get_node_secret(recipient)?;
12441314
Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
12451315
}
1316+
1317+
fn sign_node_announcement(&self, msg: &UnsignedNodeAnnouncement, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> {
1318+
self.inner.sign_node_announcement(msg, secp_ctx)
1319+
}
1320+
1321+
fn sign_channel_update(&self, msg: &UnsignedChannelUpdate, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> {
1322+
self.inner.sign_channel_update(msg, secp_ctx)
1323+
}
1324+
1325+
fn shared_secret(&self, recipient: Recipient, other: &PublicKey) -> Result<SharedSecret, ()> {
1326+
let secret = self.get_node_secret(recipient)?;
1327+
Ok(SharedSecret::new(other, &secret))
1328+
}
1329+
1330+
fn get_node_key(&self, recipient: Recipient, secp_ctx: &Secp256k1<All>) -> Result<PublicKey, ()> {
1331+
Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
1332+
}
12461333
}
12471334

12481335
impl PhantomKeysManager {
@@ -1275,6 +1362,13 @@ impl PhantomKeysManager {
12751362
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemorySigner {
12761363
self.inner.derive_channel_keys(channel_value_satoshis, params)
12771364
}
1365+
1366+
pub(crate) fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
1367+
match recipient {
1368+
Recipient::Node => Ok(self.inner.node_secret.clone()),
1369+
Recipient::PhantomNode => Ok(self.phantom_secret.clone())
1370+
}
1371+
}
12781372
}
12791373

12801374
// Ensure that BaseSign can have a vtable

lightning/src/ln/channel.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6265,13 +6265,13 @@ mod tests {
62656265
use ln::channel::{Channel,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,HTLCCandidate,HTLCInitiator,TxCreationKeys};
62666266
use ln::channel::MAX_FUNDING_SATOSHIS;
62676267
use ln::features::InitFeatures;
6268-
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
6268+
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate, UnsignedNodeAnnouncement};
62696269
use ln::script::ShutdownScript;
62706270
use ln::chan_utils;
62716271
use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters, htlc_success_tx_weight, htlc_timeout_tx_weight};
62726272
use chain::BestBlock;
62736273
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
6274-
use chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface, BaseSign};
6274+
use chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, KeysInterface, BaseSign, SharedSecretProduce};
62756275
use chain::transaction::OutPoint;
62766276
use util::config::UserConfig;
62776277
use util::enforcing_trait_impls::EnforcingSigner;
@@ -6280,6 +6280,7 @@ mod tests {
62806280
use util::test_utils::OnGetShutdownScriptpubkey;
62816281
use util::logger::Logger;
62826282
use bitcoin::secp256k1::{Secp256k1, Message, Signature, All};
6283+
use bitcoin::secp256k1::ecdh::SharedSecret;
62836284
use bitcoin::secp256k1::ffi::Signature as FFISignature;
62846285
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
62856286
use bitcoin::secp256k1::recovery::RecoverableSignature;
@@ -6319,7 +6320,7 @@ mod tests {
63196320
impl KeysInterface for Keys {
63206321
type Signer = InMemorySigner;
63216322

6322-
fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { panic!(); }
6323+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> { panic!(); }
63236324
fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
63246325
fn get_destination_script(&self) -> Script {
63256326
let secp_ctx = Secp256k1::signing_only();
@@ -6340,6 +6341,10 @@ mod tests {
63406341
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
63416342
fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::Signer, DecodeError> { panic!(); }
63426343
fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> { panic!(); }
6344+
fn sign_node_announcement(&self, _msg: &UnsignedNodeAnnouncement, _secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> { panic!(); }
6345+
fn sign_channel_update(&self, _msg: &UnsignedChannelUpdate, _secp_ctx: &Secp256k1<All>) -> Result<Signature, ()> { panic!(); }
6346+
fn shared_secret(&self, _recipient: Recipient, _other: &PublicKey) -> Result<SharedSecret, ()> { panic!(); }
6347+
fn get_node_key(&self, _recipient: Recipient, _secp_ctx: &Secp256k1<secp256k1::All>) -> Result<PublicKey, ()> { panic!(); }
63436348
}
63446349

63456350
fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {

0 commit comments

Comments
 (0)