Skip to content

Commit 0468fce

Browse files
Aditya Sharmaadi2011
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 aaef672 commit 0468fce

File tree

8 files changed

+60
-10
lines changed

8 files changed

+60
-10
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ impl NodeSigner for KeyProvider {
337337
unreachable!()
338338
}
339339

340+
fn get_peer_storage_key(&self) -> [u8; 32] {
341+
SecretKey::from_slice(&[42; 32]).unwrap().secret_bytes()
342+
}
343+
340344
fn sign_bolt12_invoice(
341345
&self, _invoice: &UnsignedBolt12Invoice,
342346
) -> Result<schnorr::Signature, ()> {

fuzz/src/full_stack.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ impl NodeSigner for KeyProvider {
420420
let secp_ctx = Secp256k1::signing_only();
421421
Ok(secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
422422
}
423+
424+
fn get_peer_storage_key(&self) -> [u8; 32] {
425+
SecretKey::from_slice(&[42; 32]).unwrap().secret_bytes()
426+
}
423427
}
424428

425429
impl SignerProvider for KeyProvider {
@@ -608,6 +612,14 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
608612
];
609613

610614
let broadcast = Arc::new(TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()) });
615+
616+
let keys_manager = Arc::new(KeyProvider {
617+
node_secret: our_network_key.clone(),
618+
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
619+
counter: AtomicU64::new(0),
620+
signer_state: RefCell::new(new_hash_map()),
621+
});
622+
611623
let monitor = Arc::new(chainmonitor::ChainMonitor::new(
612624
None,
613625
broadcast.clone(),
@@ -616,12 +628,6 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
616628
Arc::new(TestPersister { update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed) }),
617629
));
618630

619-
let keys_manager = Arc::new(KeyProvider {
620-
node_secret: our_network_key.clone(),
621-
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
622-
counter: AtomicU64::new(0),
623-
signer_state: RefCell::new(new_hash_map()),
624-
});
625631
let network = Network::Bitcoin;
626632
let best_block_timestamp = genesis_block(network).header.time;
627633
let params = ChainParameters { network, best_block: BestBlock::from_network(network) };

fuzz/src/onion_message.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ impl NodeSigner for KeyProvider {
246246
) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
247247
unreachable!()
248248
}
249+
250+
fn get_peer_storage_key(&self) -> [u8; 32] {
251+
unreachable!()
252+
}
249253
}
250254

251255
impl SignerProvider for KeyProvider {

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,7 @@ fn route_blinding_spec_test_vector() {
16091609
fn sign_invoice(
16101610
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
16111611
) -> Result<RecoverableSignature, ()> { unreachable!() }
1612+
fn get_peer_storage_key(&self) -> [u8; 32] { unreachable!() }
16121613
fn sign_bolt12_invoice(
16131614
&self, _invoice: &UnsignedBolt12Invoice,
16141615
) -> Result<schnorr::Signature, ()> { unreachable!() }
@@ -1918,6 +1919,7 @@ fn test_trampoline_inbound_payment_decoding() {
19181919
fn sign_invoice(
19191920
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
19201921
) -> Result<RecoverableSignature, ()> { unreachable!() }
1922+
fn get_peer_storage_key(&self) -> [u8; 32] { unreachable!() }
19211923
fn sign_bolt12_invoice(
19221924
&self, _invoice: &UnsignedBolt12Invoice,
19231925
) -> Result<schnorr::Signature, ()> { unreachable!() }

lightning/src/ln/channelmanager.rs

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

16392-
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a);
1639316392
let seed_a = [1u8; 32];
1639416393
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
16394+
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a, keys_manager_a.get_peer_storage_key());
1639516395
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 {
1639616396
network,
1639716397
best_block: BestBlock::from_network(network),
1639816398
}, genesis_block.header.time);
1639916399
let node_a_holder = ANodeHolder { node: &node_a };
1640016400

1640116401
let logger_b = test_utils::TestLogger::with_id("node a".to_owned());
16402-
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b);
1640316402
let seed_b = [2u8; 32];
1640416403
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
16404+
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b, keys_manager_b.get_peer_storage_key());
1640516405
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 {
1640616406
network,
1640716407
best_block: BestBlock::from_network(network),

lightning/src/sign/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,15 @@ pub trait NodeSigner {
832832
/// [phantom node payments]: PhantomKeysManager
833833
fn get_inbound_payment_key(&self) -> ExpandedKey;
834834

835+
/// Defines a method to derive a 32-byte encryption key for peer storage.
836+
///
837+
/// Implementations of this method must derive a secure encryption key.
838+
/// The key is used to encrypt or decrypt backups of our state stored with our peers.
839+
///
840+
/// Thus, if you wish to rely on recovery using this method, you should use a key which
841+
/// can be re-derived from data which would be available after state loss (eg the wallet seed)
842+
fn get_peer_storage_key(&self) -> [u8; 32];
843+
835844
/// Get node id based on the provided [`Recipient`].
836845
///
837846
/// This method must return the same value each time it is called with a given [`Recipient`]
@@ -1771,6 +1780,7 @@ pub struct KeysManager {
17711780
shutdown_pubkey: PublicKey,
17721781
channel_master_key: Xpriv,
17731782
channel_child_index: AtomicUsize,
1783+
peer_storage_key: SecretKey,
17741784

17751785
#[cfg(test)]
17761786
pub(crate) entropy_source: RandomBytes,
@@ -1839,6 +1849,10 @@ impl KeysManager {
18391849
.private_key;
18401850
let mut inbound_pmt_key_bytes = [0; 32];
18411851
inbound_pmt_key_bytes.copy_from_slice(&inbound_payment_key[..]);
1852+
let peer_storage_key: SecretKey = master_key
1853+
.derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(6).unwrap())
1854+
.expect("Your RNG is busted")
1855+
.private_key;
18421856

18431857
let mut rand_bytes_engine = Sha256::engine();
18441858
rand_bytes_engine.input(&starting_time_secs.to_be_bytes());
@@ -1854,6 +1868,8 @@ impl KeysManager {
18541868
node_id,
18551869
inbound_payment_key: ExpandedKey::new(inbound_pmt_key_bytes),
18561870

1871+
peer_storage_key,
1872+
18571873
destination_script,
18581874
shutdown_pubkey,
18591875

@@ -2079,6 +2095,10 @@ impl NodeSigner for KeysManager {
20792095
self.inbound_payment_key.clone()
20802096
}
20812097

2098+
fn get_peer_storage_key(&self) -> [u8; 32] {
2099+
self.peer_storage_key.secret_bytes()
2100+
}
2101+
20822102
fn sign_invoice(
20832103
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
20842104
) -> Result<RecoverableSignature, ()> {
@@ -2240,6 +2260,10 @@ impl NodeSigner for PhantomKeysManager {
22402260
self.inbound_payment_key.clone()
22412261
}
22422262

2263+
fn get_peer_storage_key(&self) -> [u8; 32] {
2264+
self.inner.peer_storage_key.secret_bytes()
2265+
}
2266+
22432267
fn sign_invoice(
22442268
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
22452269
) -> Result<RecoverableSignature, ()> {

lightning/src/util/dyn_signer.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ inner,
214214
fn sign_bolt12_invoice(,
215215
invoice: &crate::offers::invoice::UnsignedBolt12Invoice
216216
) -> Result<secp256k1::schnorr::Signature, ()>,
217-
fn get_inbound_payment_key(,) -> ExpandedKey
217+
fn get_inbound_payment_key(,) -> ExpandedKey,
218+
fn get_peer_storage_key(,) -> [u8; 32]
218219
);
219220

220221
delegate!(DynKeysInterface, SignerProvider,
@@ -282,7 +283,8 @@ delegate!(DynPhantomKeysInterface, NodeSigner,
282283
fn sign_invoice(, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>,
283284
fn sign_bolt12_invoice(, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
284285
) -> Result<secp256k1::schnorr::Signature, ()>,
285-
fn get_inbound_payment_key(,) -> ExpandedKey
286+
fn get_inbound_payment_key(,) -> ExpandedKey,
287+
fn get_peer_storage_key(,) -> [u8; 32]
286288
);
287289

288290
impl SignerProvider for DynPhantomKeysInterface {

lightning/src/util/test_utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,10 @@ impl NodeSigner for TestNodeSigner {
14511451
unreachable!()
14521452
}
14531453

1454+
fn get_peer_storage_key(&self) -> [u8; 32] {
1455+
unreachable!()
1456+
}
1457+
14541458
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
14551459
let node_secret = match recipient {
14561460
Recipient::Node => Ok(&self.node_secret),
@@ -1529,6 +1533,10 @@ impl NodeSigner for TestKeysInterface {
15291533
self.backing.sign_invoice(invoice, recipient)
15301534
}
15311535

1536+
fn get_peer_storage_key(&self) -> [u8; 32] {
1537+
self.backing.get_peer_storage_key()
1538+
}
1539+
15321540
fn sign_bolt12_invoice(
15331541
&self, invoice: &UnsignedBolt12Invoice,
15341542
) -> Result<schnorr::Signature, ()> {

0 commit comments

Comments
 (0)