Skip to content

Commit 0e89b22

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 1d98abd commit 0e89b22

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
local_node_receive_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+
local_node_receive_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, local_node_receive_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
local_node_receive_key,
@@ -660,15 +688,19 @@ pub(crate) const PAYMENT_PADDING_ROUND_OFF: usize = 30;
660688
/// Construct blinded payment hops for the given `intermediate_nodes` and payee info.
661689
pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
662690
secp_ctx: &Secp256k1<T>, intermediate_nodes: &[PaymentForwardNode], payee_node_id: PublicKey,
663-
payee_tlvs: ReceiveTlvs, session_priv: &SecretKey, local_node_receive_key: ReceiveAuthKey,
691+
dummy_hop_count: usize, payee_tlvs: ReceiveTlvs, session_priv: &SecretKey,
692+
local_node_receive_key: ReceiveAuthKey,
664693
) -> Vec<BlindedHop> {
694+
let dummy_count = core::cmp::min(dummy_hop_count, MAX_DUMMY_HOPS_COUNT);
665695
let pks = intermediate_nodes
666696
.iter()
667697
.map(|node| (node.node_id, None))
698+
.chain(core::iter::repeat((payee_node_id, Some(local_node_receive_key))).take(dummy_count))
668699
.chain(core::iter::once((payee_node_id, Some(local_node_receive_key))));
669700
let tlvs = intermediate_nodes
670701
.iter()
671702
.map(|node| BlindedPaymentTlvsRef::Forward(&node.tlvs))
703+
.chain((0..dummy_count).map(|_| BlindedPaymentTlvsRef::Dummy(&PaymentDummyTlv)))
672704
.chain(core::iter::once(BlindedPaymentTlvsRef::Receive(&payee_tlvs)));
673705

674706
let path = pks.zip(

0 commit comments

Comments
 (0)