Skip to content

Commit 61f0ead

Browse files
committed
Introduce Dummy Hop support in Blinded Path Constructor
Adds a new constructor for blinded paths that allows specifying the number of dummy hops. This enables users to insert arbitrary hops before the real destination, enhancing privacy by making it harder to infer the sender–receiver distance or identify the final destination. Lays the groundwork for future use of dummy hops in blinded path construction.
1 parent e8a0a76 commit 61f0ead

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

lightning/src/blinded_path/payment.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use bitcoin::secp256k1::ecdh::SharedSecret;
1313
use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
1414

15+
use crate::blinded_path::message::MAX_DUMMY_HOPS_COUNT;
1516
use crate::blinded_path::utils::{self, BlindedPathWithPadding};
1617
use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NodeIdLookUp};
1718
use crate::crypto::streams::ChaChaDualPolyReadAdapter;
@@ -121,6 +122,32 @@ impl BlindedPaymentPath {
121122
receive_auth_key: ReceiveAuthKey, payee_tlvs: ReceiveTlvs, htlc_maximum_msat: u64,
122123
min_final_cltv_expiry_delta: u16, entropy_source: ES, secp_ctx: &Secp256k1<T>,
123124
) -> Result<Self, ()>
125+
where
126+
ES::Target: EntropySource,
127+
{
128+
BlindedPaymentPath::new_with_dummy_hops(
129+
intermediate_nodes,
130+
payee_node_id,
131+
0,
132+
receive_auth_key,
133+
payee_tlvs,
134+
htlc_maximum_msat,
135+
min_final_cltv_expiry_delta,
136+
entropy_source,
137+
secp_ctx,
138+
)
139+
}
140+
141+
/// Same as [`BlindedPaymentPath::new`], but allows specifying a number of dummy hops.
142+
///
143+
/// Note:
144+
/// At most [`MAX_DUMMY_HOPS_COUNT`] dummy hops can be added to the blinded path.
145+
pub fn new_with_dummy_hops<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
146+
intermediate_nodes: &[PaymentForwardNode], payee_node_id: PublicKey,
147+
dummy_hop_count: usize, receive_auth_key: ReceiveAuthKey, payee_tlvs: ReceiveTlvs,
148+
htlc_maximum_msat: u64, min_final_cltv_expiry_delta: u16, entropy_source: ES,
149+
secp_ctx: &Secp256k1<T>,
150+
) -> Result<Self, ()>
124151
where
125152
ES::Target: EntropySource,
126153
{
@@ -145,6 +172,7 @@ impl BlindedPaymentPath {
145172
secp_ctx,
146173
intermediate_nodes,
147174
payee_node_id,
175+
dummy_hop_count,
148176
payee_tlvs,
149177
&blinding_secret,
150178
receive_auth_key,
@@ -654,15 +682,19 @@ pub(crate) const PAYMENT_PADDING_ROUND_OFF: usize = 30;
654682
/// Construct blinded payment hops for the given `intermediate_nodes` and payee info.
655683
pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
656684
secp_ctx: &Secp256k1<T>, intermediate_nodes: &[PaymentForwardNode], payee_node_id: PublicKey,
657-
payee_tlvs: ReceiveTlvs, session_priv: &SecretKey, local_node_receive_key: ReceiveAuthKey,
685+
dummy_hop_count: usize, payee_tlvs: ReceiveTlvs, session_priv: &SecretKey,
686+
local_node_receive_key: ReceiveAuthKey,
658687
) -> Vec<BlindedHop> {
688+
let dummy_count = core::cmp::min(dummy_hop_count, MAX_DUMMY_HOPS_COUNT);
659689
let pks = intermediate_nodes
660690
.iter()
661691
.map(|node| (node.node_id, None))
692+
.chain(core::iter::repeat((payee_node_id, Some(local_node_receive_key))).take(dummy_count))
662693
.chain(core::iter::once((payee_node_id, Some(local_node_receive_key))));
663694
let tlvs = intermediate_nodes
664695
.iter()
665696
.map(|node| BlindedPaymentTlvsRef::Forward(&node.tlvs))
697+
.chain((0..dummy_count).map(|_| BlindedPaymentTlvsRef::Dummy(&PaymentDummyTlv)))
666698
.chain(core::iter::once(BlindedPaymentTlvsRef::Receive(&payee_tlvs)));
667699

668700
let path = pks.zip(

0 commit comments

Comments
 (0)