Skip to content

Commit b133e80

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 4c43a5b commit b133e80

File tree

8 files changed

+74
-10
lines changed

8 files changed

+74
-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+
[0; 32]
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+
[0; 32]
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: 1 addition & 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!() }

lightning/src/ln/channelmanager.rs

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

16389-
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a);
1639016389
let seed_a = [1u8; 32];
1639116390
let keys_manager_a = KeysManager::new(&seed_a, 42, 42);
16391+
let chain_monitor_a = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_a, keys_manager_a.get_peer_storage_key());
1639216392
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 {
1639316393
network,
1639416394
best_block: BestBlock::from_network(network),
1639516395
}, genesis_block.header.time);
1639616396
let node_a_holder = ANodeHolder { node: &node_a };
1639716397

1639816398
let logger_b = test_utils::TestLogger::with_id("node a".to_owned());
16399-
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b);
1640016399
let seed_b = [2u8; 32];
1640116400
let keys_manager_b = KeysManager::new(&seed_b, 42, 42);
16401+
let chain_monitor_b = ChainMonitor::new(None, &tx_broadcaster, &logger_a, &fee_estimator, &persister_b, keys_manager_b.get_peer_storage_key());
1640216402
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 {
1640316403
network,
1640416404
best_block: BestBlock::from_network(network),

lightning/src/sign/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,30 @@ pub trait NodeSigner {
829829
/// [phantom node payments]: PhantomKeysManager
830830
fn get_inbound_payment_key(&self) -> ExpandedKey;
831831

832+
/// Defines a method to derive a 32-byte encryption key for peer storage.
833+
///
834+
/// Implementations of this method must derive a secure encryption key using a
835+
/// cryptographically strong key derivation function (e.g., HKDF or a hardened
836+
/// child key derivation). The derived key is used to encrypt or decrypt peer
837+
/// storage data, ensuring confidentiality and integrity.
838+
///
839+
/// # Implementation Details
840+
///
841+
/// - The key must be derived from a node-specific secret to ensure uniqueness.
842+
/// - The derived key must be exactly **32 bytes** and suitable for symmetric
843+
/// encryption algorithms.
844+
///
845+
/// # Returns
846+
///
847+
/// A **32-byte array** representing the encryption key for peer storage.
848+
///
849+
/// # Usage
850+
///
851+
/// This method is invoked when encrypting or decrypting peer storage data.
852+
/// It must return the same key every time it is called, ensuring consistency
853+
/// for encryption and decryption operations.
854+
fn get_peer_storage_key(&self) -> [u8; 32];
855+
832856
/// Get node id based on the provided [`Recipient`].
833857
///
834858
/// This method must return the same value each time it is called with a given [`Recipient`]
@@ -1778,6 +1802,7 @@ pub struct KeysManager {
17781802
shutdown_pubkey: PublicKey,
17791803
channel_master_key: Xpriv,
17801804
channel_child_index: AtomicUsize,
1805+
peer_storage_key: SecretKey,
17811806

17821807
#[cfg(test)]
17831808
pub(crate) entropy_source: RandomBytes,
@@ -1846,6 +1871,10 @@ impl KeysManager {
18461871
.private_key;
18471872
let mut inbound_pmt_key_bytes = [0; 32];
18481873
inbound_pmt_key_bytes.copy_from_slice(&inbound_payment_key[..]);
1874+
let peer_storage_key: SecretKey = master_key
1875+
.derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(6).unwrap())
1876+
.expect("Your RNG is busted")
1877+
.private_key;
18491878

18501879
let mut rand_bytes_engine = Sha256::engine();
18511880
rand_bytes_engine.input(&starting_time_secs.to_be_bytes());
@@ -1861,6 +1890,8 @@ impl KeysManager {
18611890
node_id,
18621891
inbound_payment_key: ExpandedKey::new(inbound_pmt_key_bytes),
18631892

1893+
peer_storage_key,
1894+
18641895
destination_script,
18651896
shutdown_pubkey,
18661897

@@ -2086,6 +2117,10 @@ impl NodeSigner for KeysManager {
20862117
self.inbound_payment_key.clone()
20872118
}
20882119

2120+
fn get_peer_storage_key(&self) -> [u8; 32] {
2121+
self.peer_storage_key.secret_bytes()
2122+
}
2123+
20892124
fn sign_invoice(
20902125
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
20912126
) -> Result<RecoverableSignature, ()> {
@@ -2247,6 +2282,10 @@ impl NodeSigner for PhantomKeysManager {
22472282
self.inbound_payment_key.clone()
22482283
}
22492284

2285+
fn get_peer_storage_key(&self) -> [u8; 32] {
2286+
self.inner.peer_storage_key.secret_bytes()
2287+
}
2288+
22502289
fn sign_invoice(
22512290
&self, invoice: &RawBolt11Invoice, recipient: Recipient,
22522291
) -> Result<RecoverableSignature, ()> {

lightning/src/util/dyn_signer.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ inner,
220220
fn sign_bolt12_invoice(,
221221
invoice: &crate::offers::invoice::UnsignedBolt12Invoice
222222
) -> Result<secp256k1::schnorr::Signature, ()>,
223-
fn get_inbound_payment_key(,) -> ExpandedKey
223+
fn get_inbound_payment_key(,) -> ExpandedKey,
224+
fn get_peer_storage_key(,) -> [u8; 32]
224225
);
225226

226227
delegate!(DynKeysInterface, SignerProvider,
@@ -288,7 +289,8 @@ delegate!(DynPhantomKeysInterface, NodeSigner,
288289
fn sign_invoice(, invoice: &RawBolt11Invoice, recipient: Recipient) -> Result<RecoverableSignature, ()>,
289290
fn sign_bolt12_invoice(, invoice: &crate::offers::invoice::UnsignedBolt12Invoice
290291
) -> Result<secp256k1::schnorr::Signature, ()>,
291-
fn get_inbound_payment_key(,) -> ExpandedKey
292+
fn get_inbound_payment_key(,) -> ExpandedKey,
293+
fn get_peer_storage_key(,) -> [u8; 32]
292294
);
293295

294296
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)