Skip to content

Commit a79d741

Browse files
Enable the construction of blinded routes
Blinded routes can be provided as destinations for onion messages, when the recipient prefers to remain anonymous. We also add supporting utilities for constructing blinded path keys, and a ControlTlvs struct representing blinded payloads prior to being encoded/encrypted. These utilities and struct will be re-used in upcoming commits for sending and receiving/forwarding onion messages.
1 parent 1b9bd8f commit a79d741

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

lightning/src/ln/onion_message.rs

+92
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,95 @@
88
// licenses.
99

1010
//! Onion Messages: sending, receiving, forwarding, and ancillary utilities live here
11+
12+
/// Onion messages have "control" TLVs and "data" TLVs. Control TLVs are used to control the
13+
/// direction and routing of an onion message from hop to hop, whereas data TLVs contain the onion
14+
/// message content itself.
15+
pub(crate) enum ControlTlvs {
16+
/// Control TLVs for the final recipient of an onion message.
17+
Receive {
18+
/// If `path_id` is `Some`, it is used to identify the blinded route that this onion message is
19+
/// sending to. This is useful for receivers to check that said blinded route is being used in
20+
/// the right context.
21+
path_id: Option<[u8; 32]>
22+
},
23+
/// Control TLVs for an intermediate forwarder of an onion message.
24+
Forward {
25+
/// The node id of the next hop in the onion message's path.
26+
next_node_id: PublicKey,
27+
/// Senders of onion messages have the option of specifying an overriding [`blinding_point`]
28+
/// for forwarding nodes along the path. If this field is absent, forwarding nodes will
29+
/// calculate the next hop's blinding point by multiplying the blinding point that they
30+
/// received by a blinding factor.
31+
///
32+
/// [`blinding_point`]: crate::ln::msgs::OnionMessage::blinding_point
33+
next_blinding_override: Option<PublicKey>,
34+
}
35+
}
36+
37+
impl Writeable for ControlTlvs {
38+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {}
39+
}
40+
41+
impl Readable for ControlTlvs {
42+
fn read<R: Read>(mut r: &mut R) -> Result<Self, DecodeError> {}
43+
}
44+
45+
/// Used to construct the blinded hops portion of a blinded route. These hops cannot be identified
46+
/// by outside observers and thus can be used to hide the identity of the recipient.
47+
pub struct BlindedNode {
48+
/// The blinded node id of this hop in a blinded route.
49+
pub blinded_node_id: PublicKey,
50+
/// The encrypted payload intended for this hop in a blinded route.
51+
// If we're sending to this blinded route, this payload will later be encoded into the
52+
// [`EncryptedTlvs`] for the hop when constructing the onion packet for sending.
53+
//
54+
// [`EncryptedTlvs`]: EncryptedTlvs
55+
pub encrypted_payload: Vec<u8>,
56+
}
57+
58+
/// Onion messages can be sent and received to blinded routes, which serve to hide the identity of
59+
/// the recipient.
60+
pub struct BlindedRoute {
61+
/// To send to a blinded route, the sender first finds a route to the unblinded
62+
/// `introduction_node_id`, which can unblind its [`encrypted_payload`] to find out the onion
63+
/// message's next hop and forward it along.
64+
///
65+
/// [`encrypted_payload`]: BlindedNode::encrypted_payload
66+
pub introduction_node_id: PublicKey,
67+
/// Creators of blinded routes supply the introduction node id's `blinding_point`, which the
68+
/// introduction node will use in decrypting its [`encrypted_payload`] to forward the onion
69+
/// message.
70+
///
71+
/// [`encrypted_payload`]: BlindedNode::encrypted_payload
72+
pub blinding_point: PublicKey,
73+
/// The blinded hops of the blinded route.
74+
pub blinded_hops: Vec<BlindedNode>,
75+
}
76+
77+
impl BlindedRoute {
78+
/// Create a blinded route to be forwarded along `hops`. The last node pubkey in `node_pks` will
79+
/// be the destination node.
80+
pub fn new<Signer: Sign, K: Deref>(node_pks: Vec<PublicKey>, keys_manager: &K) -> Result<Self, ()>
81+
where K::Target: KeysInterface<Signer = Signer>,
82+
{
83+
// calls Self::encrypt_payload
84+
}
85+
86+
fn encrypt_payload(payload: ControlTlvs, encrypted_tlvs_ss: SharedSecret) -> Vec<u8> {}
87+
}
88+
89+
#[allow(unused_assignments)]
90+
#[inline]
91+
fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification, FType: FnMut(PublicKey, SharedSecret, [u8; 32], PublicKey, SharedSecret)> (secp_ctx: &Secp256k1<T>, unblinded_path: &Vec<PublicKey>, session_priv: &SecretKey, mut callback: FType) -> Result<(), secp256k1::Error> {}
92+
93+
/// Construct keys for constructing a blinded route along the given `unblinded_path`.
94+
///
95+
/// Returns: `(encrypted_tlvs_keys, blinded_node_ids)`
96+
/// where the encrypted tlvs keys are used to encrypt the blinded route's blinded payloads and the
97+
/// blinded node ids are used to set the [`blinded_node_id`]s of the [`BlindedRoute`].
98+
fn construct_blinded_route_keys<T: secp256k1::Signing + secp256k1::Verification>(
99+
secp_ctx: &Secp256k1<T>, unblinded_path: &Vec<PublicKey>, session_priv: &SecretKey
100+
) -> Result<(Vec<SharedSecret>, Vec<PublicKey>), secp256k1::Error> {
101+
// calls construct_keys_callback
102+
}

0 commit comments

Comments
 (0)