7
7
// You may not use this file except in accordance with one or both of these
8
8
// licenses.
9
9
10
- //! Data structures and methods for constructing [`BlindedPath`]s to send a message over.
11
- //!
12
- //! [`BlindedPath`]: crate::blinded_path::BlindedPath
10
+ //! Data structures and methods for constructing [`BlindedMessagePath`]s to send a message over.
13
11
14
12
use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 , SecretKey } ;
15
13
@@ -21,16 +19,61 @@ use crate::blinded_path::utils;
21
19
use crate :: io;
22
20
use crate :: io:: Cursor ;
23
21
use crate :: ln:: channelmanager:: PaymentId ;
22
+ use crate :: ln:: msgs:: DecodeError ;
24
23
use crate :: ln:: { PaymentHash , onion_utils} ;
25
24
use crate :: offers:: nonce:: Nonce ;
26
25
use crate :: onion_message:: packet:: ControlTlvs ;
27
- use crate :: sign:: { NodeSigner , Recipient } ;
26
+ use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
28
27
use crate :: crypto:: streams:: ChaChaPolyReadAdapter ;
29
- use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , Writeable , Writer } ;
28
+ use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , Readable , Writeable , Writer } ;
30
29
31
30
use core:: mem;
32
31
use core:: ops:: Deref ;
33
32
33
+ /// A [`BlindedPath`] to be used for sending or receiving a message, hiding the identity of the
34
+ /// recipient.
35
+ #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
36
+ pub struct BlindedMessagePath ( pub BlindedPath ) ;
37
+
38
+ impl Writeable for BlindedMessagePath {
39
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
40
+ self . 0 . write ( w)
41
+ }
42
+ }
43
+
44
+ impl Readable for BlindedMessagePath {
45
+ fn read < R : io:: Read > ( r : & mut R ) -> Result < Self , DecodeError > {
46
+ Ok ( Self ( BlindedPath :: read ( r) ?) )
47
+ }
48
+ }
49
+
50
+ impl BlindedMessagePath {
51
+ /// Create a path for an onion message, to be forwarded along `node_pks`. The last node
52
+ /// pubkey in `node_pks` will be the destination node.
53
+ ///
54
+ /// Errors if no hops are provided or if `node_pk`(s) are invalid.
55
+ // TODO: make all payloads the same size with padding + add dummy hops
56
+ pub fn new < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
57
+ intermediate_nodes : & [ ForwardNode ] , recipient_node_id : PublicKey , context : MessageContext ,
58
+ entropy_source : ES , secp_ctx : & Secp256k1 < T >
59
+ ) -> Result < Self , ( ) > where ES :: Target : EntropySource {
60
+ let introduction_node = IntroductionNode :: NodeId (
61
+ intermediate_nodes. first ( ) . map_or ( recipient_node_id, |n| n. node_id )
62
+ ) ;
63
+ let blinding_secret_bytes = entropy_source. get_secure_random_bytes ( ) ;
64
+ let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
65
+
66
+ Ok ( BlindedMessagePath ( BlindedPath {
67
+ introduction_node,
68
+ blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
69
+ blinded_hops : blinded_hops (
70
+ secp_ctx, intermediate_nodes, recipient_node_id,
71
+ context, & blinding_secret,
72
+ ) . map_err ( |_| ( ) ) ?,
73
+ } ) )
74
+ }
75
+ }
76
+
34
77
/// An intermediate node, and possibly a short channel id leading to the next node.
35
78
#[ derive( Clone , Copy , Debug , Hash , PartialEq , Eq ) ]
36
79
pub struct ForwardNode {
@@ -86,10 +129,10 @@ impl Writeable for ReceiveTlvs {
86
129
}
87
130
}
88
131
89
- /// Additional data included by the recipient in a [`BlindedPath `].
132
+ /// Additional data included by the recipient in a [`BlindedMessagePath `].
90
133
///
91
134
/// This data is encrypted by the recipient and will be given to the corresponding message handler
92
- /// when handling a message sent over the [`BlindedPath `]. The recipient can use this data to
135
+ /// when handling a message sent over the [`BlindedMessagePath `]. The recipient can use this data to
93
136
/// authenticate the message or for further processing if needed.
94
137
#[ derive( Clone , Debug ) ]
95
138
pub enum MessageContext {
@@ -108,7 +151,7 @@ pub enum MessageContext {
108
151
/// [`OffersMessage`]: crate::onion_message::offers::OffersMessage
109
152
#[ derive( Clone , Debug , Eq , PartialEq ) ]
110
153
pub enum OffersContext {
111
- /// Context used by a [`BlindedPath `] within an [`Offer`].
154
+ /// Context used by a [`BlindedMessagePath `] within an [`Offer`].
112
155
///
113
156
/// This variant is intended to be received when handling an [`InvoiceRequest`].
114
157
///
@@ -122,7 +165,7 @@ pub enum OffersContext {
122
165
/// [`Offer`]: crate::offers::offer::Offer
123
166
nonce : Nonce ,
124
167
} ,
125
- /// Context used by a [`BlindedPath `] within a [`Refund`] or as a reply path for an
168
+ /// Context used by a [`BlindedMessagePath `] within a [`Refund`] or as a reply path for an
126
169
/// [`InvoiceRequest`].
127
170
///
128
171
/// This variant is intended to be received when handling a [`Bolt12Invoice`] or an
@@ -147,7 +190,7 @@ pub enum OffersContext {
147
190
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
148
191
nonce : Nonce ,
149
192
} ,
150
- /// Context used by a [`BlindedPath `] as a reply path for a [`Bolt12Invoice`].
193
+ /// Context used by a [`BlindedMessagePath `] as a reply path for a [`Bolt12Invoice`].
151
194
///
152
195
/// This variant is intended to be received when handling an [`InvoiceError`].
153
196
///
@@ -204,16 +247,16 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
204
247
//
205
248
// Will only modify `path` when returning `Ok`.
206
249
pub ( crate ) fn advance_path_by_one < NS : Deref , NL : Deref , T > (
207
- path : & mut BlindedPath , node_signer : & NS , node_id_lookup : & NL , secp_ctx : & Secp256k1 < T >
250
+ path : & mut BlindedMessagePath , node_signer : & NS , node_id_lookup : & NL , secp_ctx : & Secp256k1 < T >
208
251
) -> Result < ( ) , ( ) >
209
252
where
210
253
NS :: Target : NodeSigner ,
211
254
NL :: Target : NodeIdLookUp ,
212
255
T : secp256k1:: Signing + secp256k1:: Verification ,
213
256
{
214
- let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & path. blinding_point , None ) ?;
257
+ let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & path. 0 . blinding_point , None ) ?;
215
258
let rho = onion_utils:: gen_rho_from_shared_secret ( & control_tlvs_ss. secret_bytes ( ) ) ;
216
- let encrypted_control_tlvs = & path. blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
259
+ let encrypted_control_tlvs = & path. 0 . blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
217
260
let mut s = Cursor :: new ( encrypted_control_tlvs) ;
218
261
let mut reader = FixedLengthReader :: new ( & mut s, encrypted_control_tlvs. len ( ) as u64 ) ;
219
262
match ChaChaPolyReadAdapter :: read ( & mut reader, rho) {
@@ -230,13 +273,13 @@ where
230
273
let mut new_blinding_point = match next_blinding_override {
231
274
Some ( blinding_point) => blinding_point,
232
275
None => {
233
- onion_utils:: next_hop_pubkey ( secp_ctx, path. blinding_point ,
276
+ onion_utils:: next_hop_pubkey ( secp_ctx, path. 0 . blinding_point ,
234
277
control_tlvs_ss. as_ref ( ) ) . map_err ( |_| ( ) ) ?
235
278
}
236
279
} ;
237
- mem:: swap ( & mut path. blinding_point , & mut new_blinding_point) ;
238
- path. introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
239
- path. blinded_hops . remove ( 0 ) ;
280
+ mem:: swap ( & mut path. 0 . blinding_point , & mut new_blinding_point) ;
281
+ path. 0 . introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
282
+ path. 0 . blinded_hops . remove ( 0 ) ;
240
283
Ok ( ( ) )
241
284
} ,
242
285
_ => Err ( ( ) )
0 commit comments