Skip to content

Commit 80299af

Browse files
committed
Use NodeSigner::ecdh to compute SharedSecrets
1 parent d2043bc commit 80299af

File tree

6 files changed

+146
-52
lines changed

6 files changed

+146
-52
lines changed

fuzz/src/peer_crypt.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use lightning::ln::peer_channel_encryptor::PeerChannelEncryptor;
1111

1212
use bitcoin::secp256k1::{Secp256k1, PublicKey, SecretKey};
1313

14-
use crate::utils::test_logger;
14+
use crate::utils::{test_logger, test_node_signer};
1515

1616
#[inline]
1717
fn slice_to_be16(v: &[u8]) -> u16 {
@@ -41,6 +41,7 @@ pub fn do_test(data: &[u8]) {
4141
Ok(key) => key,
4242
Err(_) => return,
4343
};
44+
let node_signer = test_node_signer::TestNodeSigner::new(our_network_key);
4445
let ephemeral_key = match SecretKey::from_slice(get_slice!(32)) {
4546
Ok(key) => key,
4647
Err(_) => return,
@@ -53,15 +54,15 @@ pub fn do_test(data: &[u8]) {
5354
};
5455
let mut crypter = PeerChannelEncryptor::new_outbound(their_pubkey, ephemeral_key);
5556
crypter.get_act_one(&secp_ctx);
56-
match crypter.process_act_two(get_slice!(50), &our_network_key, &secp_ctx) {
57+
match crypter.process_act_two(get_slice!(50), &&node_signer) {
5758
Ok(_) => {},
5859
Err(_) => return,
5960
}
6061
assert!(crypter.is_ready_for_encryption());
6162
crypter
6263
} else {
63-
let mut crypter = PeerChannelEncryptor::new_inbound(&our_network_key, &secp_ctx);
64-
match crypter.process_act_one_with_keys(get_slice!(50), &our_network_key, ephemeral_key, &secp_ctx) {
64+
let mut crypter = PeerChannelEncryptor::new_inbound(&&node_signer);
65+
match crypter.process_act_one_with_keys(get_slice!(50), &&node_signer, ephemeral_key, &secp_ctx) {
6566
Ok(_) => {},
6667
Err(_) => return,
6768
}

fuzz/src/utils/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99

1010
pub mod test_logger;
1111
pub mod test_persister;
12+
pub mod test_node_signer;

fuzz/src/utils/test_node_signer.rs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
10+
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
11+
use bitcoin::secp256k1::ecdh::SharedSecret;
12+
13+
use lightning::chain::keysinterface::{NodeSigner, Recipient};
14+
15+
pub struct TestNodeSigner {
16+
node_secret: SecretKey,
17+
}
18+
19+
impl TestNodeSigner {
20+
pub fn new(node_secret: SecretKey) -> Self {
21+
Self { node_secret }
22+
}
23+
}
24+
25+
impl NodeSigner for TestNodeSigner {
26+
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
27+
let node_secret = match recipient {
28+
Recipient::Node => Ok(self.node_secret.clone()),
29+
Recipient::PhantomNode => Err(())
30+
}?;
31+
Ok(node_secret)
32+
}
33+
34+
fn get_inbound_payment_key_material(&self) -> lightning::chain::keysinterface::KeyMaterial {
35+
unreachable!()
36+
}
37+
38+
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
39+
let node_secret = match recipient {
40+
Recipient::Node => Ok(&self.node_secret),
41+
Recipient::PhantomNode => Err(())
42+
}?;
43+
Ok(PublicKey::from_secret_key(&Secp256k1::new(), node_secret))
44+
}
45+
46+
fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&bitcoin::secp256k1::Scalar>) -> Result<SharedSecret, ()> {
47+
let mut node_secret = match recipient {
48+
Recipient::Node => Ok(self.node_secret.clone()),
49+
Recipient::PhantomNode => Err(())
50+
}?;
51+
if let Some(tweak) = tweak {
52+
node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
53+
}
54+
Ok(SharedSecret::new(other_key, &node_secret))
55+
}
56+
57+
fn sign_invoice(&self, _: &[u8], _: &[bitcoin::bech32::u5], _: Recipient) -> Result<bitcoin::secp256k1::ecdsa::RecoverableSignature, ()> {
58+
unreachable!()
59+
}
60+
61+
fn sign_gossip_message(&self, _: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
62+
unreachable!()
63+
}
64+
}

lightning/src/ln/channelmanager.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use bitcoin::hash_types::{BlockHash, Txid};
3030

3131
use bitcoin::secp256k1::{SecretKey,PublicKey};
3232
use bitcoin::secp256k1::Secp256k1;
33-
use bitcoin::secp256k1::ecdh::SharedSecret;
3433
use bitcoin::{LockTime, secp256k1, Sequence};
3534

3635
use crate::chain;
@@ -2016,7 +2015,9 @@ where
20162015
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
20172016
}
20182017

2019-
let shared_secret = SharedSecret::new(&msg.onion_routing_packet.public_key.unwrap(), &self.our_network_key).secret_bytes();
2018+
let shared_secret = self.node_signer.ecdh(
2019+
Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), None
2020+
).unwrap().secret_bytes();
20202021

20212022
if msg.onion_routing_packet.version != 0 {
20222023
//TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
@@ -2924,9 +2925,9 @@ where
29242925
}
29252926
}
29262927
if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
2927-
let phantom_secret_res = self.node_signer.get_node_secret(Recipient::PhantomNode);
2928-
if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
2929-
let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
2928+
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
2929+
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
2930+
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
29302931
let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
29312932
Ok(res) => res,
29322933
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {

0 commit comments

Comments
 (0)