Skip to content

Commit 7697e7c

Browse files
committed
Introduce SharedSecretProduce
1 parent 2114c80 commit 7697e7c

File tree

9 files changed

+265
-170
lines changed

9 files changed

+265
-170
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: 107 additions & 62 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,32 +393,59 @@ pub enum Recipient {
392393
PhantomNode,
393394
}
394395

395-
/// A transport and onion encryptor / decryptor that uses the node key
396-
pub trait ProtocolEncrypt {
397-
/// Get node secret key (aka node_id or network_key) based on the provided [`Recipient`].
396+
///
397+
pub trait SharedSecretProduce: Send + Sync {
398398
///
399-
/// This method must return the same value each time it is called with a given `Recipient`
400-
/// parameter.
401-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
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+
}
402431
}
403432

404433
/// A trait to describe an object which can get user secrets and key material.
405434
pub trait KeysInterface {
406435
/// A type which implements Sign which will be returned by get_channel_signer.
407436
type Signer : Sign;
408-
/// A type which implements ProtoconCnrypt which will be returned by get_protocol_keys.
409-
type ProtocolEncryptor: ProtocolEncrypt;
410437

411-
/// A protocol encryptor / decryptor that uses the node secret key
412-
fn get_protocol_keys(&self) -> Self::ProtocolEncryptor;
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, ()>;
413443

414-
/// Get node secret key (aka node_id or network_key) based on the provided [`Recipient`].
444+
/// Get node public key (AKA node ID)
415445
///
416446
/// This method must return the same value each time it is called with a given `Recipient`
417447
/// parameter.
418-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
419-
self.get_protocol_keys().get_node_secret(recipient)
420-
}
448+
fn get_node_key(&self, recipient: Recipient, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<PublicKey, ()>;
421449

422450
/// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
423451
///
@@ -458,6 +486,12 @@ pub trait KeysInterface {
458486
/// The secret key used to sign the invoice is dependent on the [`Recipient`].
459487
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result<RecoverableSignature, ()>;
460488

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+
461495
/// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
462496
///
463497
/// If the implementor of this trait supports [phantom node payments], then every node that is
@@ -845,21 +879,6 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
845879
}
846880
}
847881

848-
/// A protocol encryptor that keeps the key in memory
849-
pub struct InMemoryProtocolEncryptor {
850-
/// Private key of our node secret, used for signing channel announcements
851-
pub node_secret: SecretKey,
852-
}
853-
854-
impl ProtocolEncrypt for InMemoryProtocolEncryptor {
855-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
856-
match recipient {
857-
Recipient::Node => Ok(self.node_secret.clone()),
858-
Recipient::PhantomNode => Err(())
859-
}
860-
}
861-
}
862-
863882
/// Simple KeysInterface implementor that takes a 32-byte seed for use as a BIP 32 extended key
864883
/// and derives keys from that.
865884
///
@@ -1150,14 +1169,20 @@ impl KeysManager {
11501169

11511170
Ok(spend_tx)
11521171
}
1172+
1173+
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
1174+
match recipient {
1175+
Recipient::Node => Ok(self.node_secret.clone()),
1176+
Recipient::PhantomNode => Err(())
1177+
}
1178+
}
11531179
}
11541180

11551181
impl KeysInterface for KeysManager {
11561182
type Signer = InMemorySigner;
1157-
type ProtocolEncryptor = InMemoryProtocolEncryptor;
11581183

1159-
fn get_protocol_keys(&self) -> Self::ProtocolEncryptor {
1160-
InMemoryProtocolEncryptor { node_secret: self.node_secret }
1184+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> {
1185+
EphemeralSharedSecretProducer::new(self.node_secret)
11611186
}
11621187

11631188
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
@@ -1199,12 +1224,30 @@ impl KeysInterface for KeysManager {
11991224

12001225
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
12011226
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
1202-
let secret = match recipient {
1203-
Recipient::Node => self.get_protocol_keys().get_node_secret(Recipient::Node)?,
1204-
Recipient::PhantomNode => return Err(()),
1205-
};
1227+
let secret = self.get_node_secret(recipient)?;
12061228
Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
12071229
}
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+
}
12081251
}
12091252

12101253
/// Similar to [`KeysManager`], but allows the node using this struct to receive phantom node
@@ -1234,33 +1277,11 @@ pub struct PhantomKeysManager {
12341277
phantom_secret: SecretKey,
12351278
}
12361279

1237-
/// A protocol encryptor that keeps the key in memory, with phantom node support
1238-
pub struct PhantomProtocolEncryptor {
1239-
/// Private key of our node secret
1240-
pub node_secret: SecretKey,
1241-
/// Private key of our phantom node secret
1242-
pub phantom_secret: SecretKey,
1243-
}
1244-
1245-
impl ProtocolEncrypt for PhantomProtocolEncryptor {
1246-
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
1247-
match recipient {
1248-
Recipient::Node => Ok(self.node_secret.clone()),
1249-
Recipient::PhantomNode => Ok(self.phantom_secret.clone())
1250-
}
1251-
}
1252-
}
1253-
1254-
12551280
impl KeysInterface for PhantomKeysManager {
12561281
type Signer = InMemorySigner;
1257-
type ProtocolEncryptor = PhantomProtocolEncryptor;
12581282

1259-
fn get_protocol_keys(&self) -> Self::ProtocolEncryptor {
1260-
PhantomProtocolEncryptor {
1261-
node_secret: self.inner.node_secret,
1262-
phantom_secret: self.phantom_secret,
1263-
}
1283+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> {
1284+
EphemeralSharedSecretProducer::new(self.inner.node_secret)
12641285
}
12651286

12661287
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
@@ -1292,6 +1313,23 @@ impl KeysInterface for PhantomKeysManager {
12921313
let secret = self.get_node_secret(recipient)?;
12931314
Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
12941315
}
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+
}
12951333
}
12961334

12971335
impl PhantomKeysManager {
@@ -1324,6 +1362,13 @@ impl PhantomKeysManager {
13241362
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemorySigner {
13251363
self.inner.derive_channel_keys(channel_value_satoshis, params)
13261364
}
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+
}
13271372
}
13281373

13291374
// Ensure that BaseSign can have a vtable

lightning/src/ln/channel.rs

Lines changed: 8 additions & 4 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, InMemoryProtocolEncryptor};
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;
@@ -6318,9 +6319,8 @@ mod tests {
63186319
}
63196320
impl KeysInterface for Keys {
63206321
type Signer = InMemorySigner;
6321-
type ProtocolEncryptor = InMemoryProtocolEncryptor;
63226322

6323-
fn get_protocol_keys(&self) -> Self::ProtocolEncryptor { panic!(); }
6323+
fn get_shared_secret_producer(&self) -> Box<dyn SharedSecretProduce> { panic!(); }
63246324
fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
63256325
fn get_destination_script(&self) -> Script {
63266326
let secp_ctx = Secp256k1::signing_only();
@@ -6341,6 +6341,10 @@ mod tests {
63416341
fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
63426342
fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::Signer, DecodeError> { panic!(); }
63436343
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!(); }
63446348
}
63456349

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

0 commit comments

Comments
 (0)