Skip to content

Commit 46c5b42

Browse files
Aditya Sharmaadi2011
Aditya Sharma
authored andcommitted
Add method to derive Peer Storage encryption key
Add get_peer_storage_key method to derive a 32-byte encryption key for securing Peer Storage. This method utilizes HKDF with the node's secret key as input and a fixed info string to generate the encryption key. - Add 'get_peer_storage_key' to NodeSigner. - Implement 'get_peer_storage_key' for KeysManager & PhantomKeysManager.
1 parent 02b5564 commit 46c5b42

File tree

8 files changed

+81
-15
lines changed

8 files changed

+81
-15
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessa
6262
use lightning::routing::router::{
6363
InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters, Router,
6464
};
65-
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
65+
use lightning::sign::{
66+
EntropySource, InMemorySigner, NodeSigner, PeerStorageKey, Recipient, SignerProvider,
67+
};
6668
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6769
use lightning::util::config::UserConfig;
6870
use lightning::util::hash_tables::*;
@@ -338,6 +340,10 @@ impl NodeSigner for KeyProvider {
338340
unreachable!()
339341
}
340342

343+
fn get_peer_storage_key(&self) -> PeerStorageKey {
344+
PeerStorageKey { inner: [42; 32] }
345+
}
346+
341347
fn sign_bolt12_invoice(
342348
&self, _invoice: &UnsignedBolt12Invoice,
343349
) -> Result<schnorr::Signature, ()> {

fuzz/src/full_stack.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use lightning::routing::router::{
5656
InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router,
5757
};
5858
use lightning::routing::utxo::UtxoLookup;
59+
use lightning::sign::PeerStorageKey;
5960
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
6061
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6162
use lightning::util::config::{ChannelConfig, UserConfig};
@@ -428,6 +429,10 @@ impl NodeSigner for KeyProvider {
428429
let secp_ctx = Secp256k1::signing_only();
429430
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
430431
}
432+
433+
fn get_peer_storage_key(&self) -> PeerStorageKey {
434+
PeerStorageKey { inner: [42; 32] }
435+
}
431436
}
432437

433438
impl SignerProvider for KeyProvider {
@@ -560,6 +565,14 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
560565
];
561566

562567
let broadcast = Arc::new(TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()) });
568+
569+
let keys_manager = Arc::new(KeyProvider {
570+
node_secret: our_network_key.clone(),
571+
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
572+
counter: AtomicU64::new(0),
573+
signer_state: RefCell::new(new_hash_map()),
574+
});
575+
563576
let monitor = Arc::new(chainmonitor::ChainMonitor::new(
564577
None,
565578
broadcast.clone(),
@@ -568,12 +581,6 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
568581
Arc::new(TestPersister { update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed) }),
569582
));
570583

571-
let keys_manager = Arc::new(KeyProvider {
572-
node_secret: our_network_key.clone(),
573-
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
574-
counter: AtomicU64::new(0),
575-
signer_state: RefCell::new(new_hash_map()),
576-
});
577584
let network = Network::Bitcoin;
578585
let best_block_timestamp = genesis_block(network).header.time;
579586
let params = ChainParameters { network, best_block: BestBlock::from_network(network) };

fuzz/src/onion_message.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use lightning::onion_message::messenger::{
2323
};
2424
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
2525
use lightning::onion_message::packet::OnionMessageContents;
26-
use lightning::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
26+
use lightning::sign::{EntropySource, NodeSigner, PeerStorageKey, Recipient, SignerProvider};
2727
use lightning::types::features::InitFeatures;
2828
use lightning::util::logger::Logger;
2929
use lightning::util::ser::{LengthReadable, Writeable, Writer};
@@ -249,6 +249,10 @@ impl NodeSigner for KeyProvider {
249249
) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
250250
unreachable!()
251251
}
252+
253+
fn get_peer_storage_key(&self) -> PeerStorageKey {
254+
unreachable!()
255+
}
252256
}
253257

254258
impl SignerProvider for KeyProvider {

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::offers::invoice::UnsignedBolt12Invoice;
3434
use crate::offers::nonce::Nonce;
3535
use crate::prelude::*;
3636
use crate::routing::router::{BlindedTail, Path, Payee, PaymentParameters, RouteHop, RouteParameters, TrampolineHop};
37-
use crate::sign::{NodeSigner, Recipient};
37+
use crate::sign::{NodeSigner, PeerStorageKey, Recipient};
3838
use crate::util::config::UserConfig;
3939
use crate::util::ser::{WithoutLength, Writeable};
4040
use crate::util::test_utils;
@@ -1629,6 +1629,7 @@ fn route_blinding_spec_test_vector() {
16291629
fn sign_invoice(
16301630
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
16311631
) -> Result<RecoverableSignature, ()> { unreachable!() }
1632+
fn get_peer_storage_key(&self) -> PeerStorageKey { unreachable!() }
16321633
fn sign_bolt12_invoice(
16331634
&self, _invoice: &UnsignedBolt12Invoice,
16341635
) -> Result<schnorr::Signature, ()> { unreachable!() }
@@ -1938,6 +1939,7 @@ fn test_trampoline_inbound_payment_decoding() {
19381939
fn sign_invoice(
19391940
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
19401941
) -> Result<RecoverableSignature, ()> { unreachable!() }
1942+
fn get_peer_storage_key(&self) -> PeerStorageKey { unreachable!() }
19411943
fn sign_bolt12_invoice(
19421944
&self, _invoice: &UnsignedBolt12Invoice,
19431945
) -> Result<schnorr::Signature, ()> { unreachable!() }

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16468,19 +16468,19 @@ pub mod bench {
1646816468
config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253);
1646916469
config.channel_handshake_config.minimum_depth = 1;
1647016470

16471-
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a);
1647216471
let seed_a = [1u8; 32];
1647316472
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
16473+
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a, keys_manager_a.get_peer_storage_key());
1647416474
let node_a = ChannelManager::new(&fee_estimator, &chain_monitor_a, &tx_broadcaster, &router, &message_router, &logger_a, &keys_manager_a, &keys_manager_a, &keys_manager_a, config.clone(), ChainParameters {
1647516475
network,
1647616476
best_block: BestBlock::from_network(network),
1647716477
}, genesis_block.header.time);
1647816478
let node_a_holder = ANodeHolder { node: &node_a };
1647916479

1648016480
let logger_b = test_utils::TestLogger::with_id("node a".to_owned());
16481-
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b);
1648216481
let seed_b = [2u8; 32];
1648316482
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
16483+
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b, keys_manager_b.get_peer_storage_key());
1648416484
let node_b = ChannelManager::new(&fee_estimator, &chain_monitor_b, &tx_broadcaster, &router, &message_router, &logger_b, &keys_manager_b, &keys_manager_b, &keys_manager_b, config.clone(), ChainParameters {
1648516485
network,
1648616486
best_block: BestBlock::from_network(network),

lightning/src/sign/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,17 @@ pub trait ChannelSigner {
796796
fn channel_keys_id(&self) -> [u8; 32];
797797
}
798798

799+
/// Represents Secret Key used for encrypting Peer Storage.
800+
#[derive(Clone, Copy, PartialEq, Eq)]
801+
pub struct PeerStorageKey {
802+
/// In chanmon_consistency we derive this key.
803+
#[cfg(fuzzing)]
804+
pub inner: [u8; 32],
805+
/// Represents the key used to encrypt and decrypt Peer Storage.
806+
#[cfg(not(fuzzing))]
807+
pub inner: [u8; 32],
808+
}
809+
799810
/// Specifies the recipient of an invoice.
800811
///
801812
/// This indicates to [`NodeSigner::sign_invoice`] what node secret key should be used to sign
@@ -834,6 +845,15 @@ pub trait NodeSigner {
834845
/// [phantom node payments]: PhantomKeysManager
835846
fn get_inbound_payment_key(&self) -> ExpandedKey;
836847

848+
/// Defines a method to derive a 32-byte encryption key for peer storage.
849+
///
850+
/// Implementations of this method must derive a secure encryption key.
851+
/// The key is used to encrypt or decrypt backups of our state stored with our peers.
852+
///
853+
/// Thus, if you wish to rely on recovery using this method, you should use a key which
854+
/// can be re-derived from data which would be available after state loss (eg the wallet seed).
855+
fn get_peer_storage_key(&self) -> PeerStorageKey;
856+
837857
/// Get node id based on the provided [`Recipient`].
838858
///
839859
/// This method must return the same value each time it is called with a given [`Recipient`]
@@ -1809,6 +1829,7 @@ pub struct KeysManager {
18091829
shutdown_pubkey: PublicKey,
18101830
channel_master_key: Xpriv,
18111831
channel_child_index: AtomicUsize,
1832+
peer_storage_key: PeerStorageKey,
18121833

18131834
#[cfg(test)]
18141835
pub(crate) entropy_source: RandomBytes,
@@ -1877,6 +1898,10 @@ impl KeysManager {
18771898
.private_key;
18781899
let mut inbound_pmt_key_bytes = [0; 32];
18791900
inbound_pmt_key_bytes.copy_from_slice(&inbound_payment_key[..]);
1901+
let peer_storage_key: SecretKey = master_key
1902+
.derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(6).unwrap())
1903+
.expect("Your RNG is busted")
1904+
.private_key;
18801905

18811906
let mut rand_bytes_engine = Sha256::engine();
18821907
rand_bytes_engine.input(&starting_time_secs.to_be_bytes());
@@ -1892,6 +1917,8 @@ impl KeysManager {
18921917
node_id,
18931918
inbound_payment_key: ExpandedKey::new(inbound_pmt_key_bytes),
18941919

1920+
peer_storage_key: PeerStorageKey { inner: peer_storage_key.secret_bytes() },
1921+
18951922
destination_script,
18961923
shutdown_pubkey,
18971924

@@ -2117,6 +2144,10 @@ impl NodeSigner for KeysManager {
21172144
self.inbound_payment_key.clone()
21182145
}
21192146

2147+
fn get_peer_storage_key(&self) -> PeerStorageKey {
2148+
self.peer_storage_key.clone()
2149+
}
2150+
21202151
fn sign_invoice(
21212152
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
21222153
) -> Result<RecoverableSignature, ()> {
@@ -2278,6 +2309,10 @@ impl NodeSigner for PhantomKeysManager {
22782309
self.inbound_payment_key.clone()
22792310
}
22802311

2312+
fn get_peer_storage_key(&self) -> PeerStorageKey {
2313+
self.inner.peer_storage_key.clone()
2314+
}
2315+
22812316
fn sign_invoice(
22822317
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
22832318
) -> Result<RecoverableSignature, ()> {

lightning/src/util/dyn_signer.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ use crate::sign::taproot::TaprootChannelSigner;
1717
use crate::sign::ChannelSigner;
1818
use crate::sign::InMemorySigner;
1919
use crate::sign::{EntropySource, HTLCDescriptor, OutputSpender, PhantomKeysManager};
20-
use crate::sign::{NodeSigner, Recipient, SignerProvider, SpendableOutputDescriptor};
20+
use crate::sign::{
21+
NodeSigner, PeerStorageKey, Recipient, SignerProvider, SpendableOutputDescriptor,
22+
};
2123
use bitcoin;
2224
use bitcoin::absolute::LockTime;
2325
use bitcoin::secp256k1::All;
@@ -214,7 +216,8 @@ inner,
214216
fn sign_bolt12_invoice(,
215217
invoice: &crate::offers::invoice::UnsignedBolt12Invoice
216218
) -> Result<secp256k1::schnorr::Signature, ()>,
217-
fn get_inbound_payment_key(,) -> ExpandedKey
219+
fn get_inbound_payment_key(,) -> ExpandedKey,
220+
fn get_peer_storage_key(,) -> PeerStorageKey
218221
);
219222

220223
delegate!(DynKeysInterface, SignerProvider,
@@ -278,7 +281,8 @@ delegate!(DynPhantomKeysInterface, NodeSigner,
278281
fn sign_invoice(, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>,
279282
fn sign_bolt12_invoice(, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
280283
) -> Result<secp256k1::schnorr::Signature, ()>,
281-
fn get_inbound_payment_key(,) -> ExpandedKey
284+
fn get_inbound_payment_key(,) -> ExpandedKey,
285+
fn get_peer_storage_key(,) -> PeerStorageKey
282286
);
283287

284288
impl SignerProvider for DynPhantomKeysInterface {

lightning/src/util/test_utils.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use crate::routing::router::{
4646
use crate::routing::scoring::{ChannelUsage, ScoreLookUp, ScoreUpdate};
4747
use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult};
4848
use crate::sign;
49-
use crate::sign::ChannelSigner;
49+
use crate::sign::{ChannelSigner, PeerStorageKey};
5050
use crate::sync::RwLock;
5151
use crate::types::features::{ChannelFeatures, InitFeatures, NodeFeatures};
5252
use crate::util::config::UserConfig;
@@ -1490,6 +1490,10 @@ impl NodeSigner for TestNodeSigner {
14901490
unreachable!()
14911491
}
14921492

1493+
fn get_peer_storage_key(&self) -> PeerStorageKey {
1494+
unreachable!()
1495+
}
1496+
14931497
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
14941498
let node_secret = match recipient {
14951499
Recipient::Node => Ok(&self.node_secret),
@@ -1570,6 +1574,10 @@ impl NodeSigner for TestKeysInterface {
15701574
self.backing.sign_invoice(invoice, recipient)
15711575
}
15721576

1577+
fn get_peer_storage_key(&self) -> PeerStorageKey {
1578+
self.backing.get_peer_storage_key()
1579+
}
1580+
15731581
fn sign_bolt12_invoice(
15741582
&self, invoice: &UnsignedBolt12Invoice,
15751583
) -> Result<schnorr::Signature, ()> {

0 commit comments

Comments
 (0)