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
@@ -23,16 +21,68 @@ use crate::blinded_path::utils;
23
21
use crate :: io;
24
22
use crate :: io:: Cursor ;
25
23
use crate :: ln:: channelmanager:: PaymentId ;
24
+ use crate :: ln:: msgs:: DecodeError ;
26
25
use crate :: ln:: { PaymentHash , onion_utils} ;
27
26
use crate :: offers:: nonce:: Nonce ;
28
27
use crate :: onion_message:: packet:: ControlTlvs ;
29
- use crate :: sign:: { NodeSigner , Recipient } ;
28
+ use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
30
29
use crate :: crypto:: streams:: ChaChaPolyReadAdapter ;
31
- use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , Writeable , Writer } ;
30
+ use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , Readable , Writeable , Writer } ;
32
31
33
32
use core:: mem;
34
33
use core:: ops:: Deref ;
35
34
35
+ /// A [`BlindedPath`] to be used for sending or receiving a message, hiding the identity of the
36
+ /// recipient.
37
+ #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
38
+ pub struct BlindedMessagePath ( pub BlindedPath ) ;
39
+
40
+ impl Writeable for BlindedMessagePath {
41
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
42
+ self . 0 . write ( w)
43
+ }
44
+ }
45
+
46
+ impl Readable for BlindedMessagePath {
47
+ fn read < R : io:: Read > ( r : & mut R ) -> Result < Self , DecodeError > {
48
+ Ok ( Self ( BlindedPath :: read ( r) ?) )
49
+ }
50
+ }
51
+
52
+ impl BlindedMessagePath {
53
+ /// Create a one-hop blinded path for a message.
54
+ pub fn one_hop < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
55
+ recipient_node_id : PublicKey , context : MessageContext , entropy_source : ES , secp_ctx : & Secp256k1 < T >
56
+ ) -> Result < Self , ( ) > where ES :: Target : EntropySource {
57
+ Self :: new ( & [ ] , recipient_node_id, context, entropy_source, secp_ctx)
58
+ }
59
+
60
+ /// Create a path for an onion message, to be forwarded along `node_pks`. The last node
61
+ /// pubkey in `node_pks` will be the destination node.
62
+ ///
63
+ /// Errors if no hops are provided or if `node_pk`(s) are invalid.
64
+ // TODO: make all payloads the same size with padding + add dummy hops
65
+ pub fn new < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
66
+ intermediate_nodes : & [ ForwardNode ] , recipient_node_id : PublicKey , context : MessageContext ,
67
+ entropy_source : ES , secp_ctx : & Secp256k1 < T >
68
+ ) -> Result < Self , ( ) > where ES :: Target : EntropySource {
69
+ let introduction_node = IntroductionNode :: NodeId (
70
+ intermediate_nodes. first ( ) . map_or ( recipient_node_id, |n| n. node_id )
71
+ ) ;
72
+ let blinding_secret_bytes = entropy_source. get_secure_random_bytes ( ) ;
73
+ let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
74
+
75
+ Ok ( Self ( BlindedPath {
76
+ introduction_node,
77
+ blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
78
+ blinded_hops : blinded_hops (
79
+ secp_ctx, intermediate_nodes, recipient_node_id,
80
+ context, & blinding_secret,
81
+ ) . map_err ( |_| ( ) ) ?,
82
+ } ) )
83
+ }
84
+ }
85
+
36
86
/// An intermediate node, and possibly a short channel id leading to the next node.
37
87
#[ derive( Clone , Copy , Debug , Hash , PartialEq , Eq ) ]
38
88
pub struct ForwardNode {
@@ -88,10 +138,10 @@ impl Writeable for ReceiveTlvs {
88
138
}
89
139
}
90
140
91
- /// Additional data included by the recipient in a [`BlindedPath `].
141
+ /// Additional data included by the recipient in a [`BlindedMessagePath `].
92
142
///
93
143
/// This data is encrypted by the recipient and will be given to the corresponding message handler
94
- /// when handling a message sent over the [`BlindedPath `]. The recipient can use this data to
144
+ /// when handling a message sent over the [`BlindedMessagePath `]. The recipient can use this data to
95
145
/// authenticate the message or for further processing if needed.
96
146
#[ derive( Clone , Debug ) ]
97
147
pub enum MessageContext {
@@ -110,7 +160,7 @@ pub enum MessageContext {
110
160
/// [`OffersMessage`]: crate::onion_message::offers::OffersMessage
111
161
#[ derive( Clone , Debug , Eq , PartialEq ) ]
112
162
pub enum OffersContext {
113
- /// Context used by a [`BlindedPath `] within an [`Offer`].
163
+ /// Context used by a [`BlindedMessagePath `] within an [`Offer`].
114
164
///
115
165
/// This variant is intended to be received when handling an [`InvoiceRequest`].
116
166
///
@@ -124,7 +174,7 @@ pub enum OffersContext {
124
174
/// [`Offer`]: crate::offers::offer::Offer
125
175
nonce : Nonce ,
126
176
} ,
127
- /// Context used by a [`BlindedPath `] within a [`Refund`] or as a reply path for an
177
+ /// Context used by a [`BlindedMessagePath `] within a [`Refund`] or as a reply path for an
128
178
/// [`InvoiceRequest`].
129
179
///
130
180
/// This variant is intended to be received when handling a [`Bolt12Invoice`] or an
@@ -155,7 +205,7 @@ pub enum OffersContext {
155
205
/// [`InvoiceError`]: crate::offers::invoice_error::InvoiceError
156
206
hmac : Option < Hmac < Sha256 > > ,
157
207
} ,
158
- /// Context used by a [`BlindedPath `] as a reply path for a [`Bolt12Invoice`].
208
+ /// Context used by a [`BlindedMessagePath `] as a reply path for a [`Bolt12Invoice`].
159
209
///
160
210
/// This variant is intended to be received when handling an [`InvoiceError`].
161
211
///
@@ -213,16 +263,16 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
213
263
//
214
264
// Will only modify `path` when returning `Ok`.
215
265
pub ( crate ) fn advance_path_by_one < NS : Deref , NL : Deref , T > (
216
- path : & mut BlindedPath , node_signer : & NS , node_id_lookup : & NL , secp_ctx : & Secp256k1 < T >
266
+ path : & mut BlindedMessagePath , node_signer : & NS , node_id_lookup : & NL , secp_ctx : & Secp256k1 < T >
217
267
) -> Result < ( ) , ( ) >
218
268
where
219
269
NS :: Target : NodeSigner ,
220
270
NL :: Target : NodeIdLookUp ,
221
271
T : secp256k1:: Signing + secp256k1:: Verification ,
222
272
{
223
- let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & path. blinding_point , None ) ?;
273
+ let control_tlvs_ss = node_signer. ecdh ( Recipient :: Node , & path. 0 . blinding_point , None ) ?;
224
274
let rho = onion_utils:: gen_rho_from_shared_secret ( & control_tlvs_ss. secret_bytes ( ) ) ;
225
- let encrypted_control_tlvs = & path. blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
275
+ let encrypted_control_tlvs = & path. 0 . blinded_hops . get ( 0 ) . ok_or ( ( ) ) ?. encrypted_payload ;
226
276
let mut s = Cursor :: new ( encrypted_control_tlvs) ;
227
277
let mut reader = FixedLengthReader :: new ( & mut s, encrypted_control_tlvs. len ( ) as u64 ) ;
228
278
match ChaChaPolyReadAdapter :: read ( & mut reader, rho) {
@@ -239,13 +289,13 @@ where
239
289
let mut new_blinding_point = match next_blinding_override {
240
290
Some ( blinding_point) => blinding_point,
241
291
None => {
242
- onion_utils:: next_hop_pubkey ( secp_ctx, path. blinding_point ,
292
+ onion_utils:: next_hop_pubkey ( secp_ctx, path. 0 . blinding_point ,
243
293
control_tlvs_ss. as_ref ( ) ) . map_err ( |_| ( ) ) ?
244
294
}
245
295
} ;
246
- mem:: swap ( & mut path. blinding_point , & mut new_blinding_point) ;
247
- path. introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
248
- path. blinded_hops . remove ( 0 ) ;
296
+ mem:: swap ( & mut path. 0 . blinding_point , & mut new_blinding_point) ;
297
+ path. 0 . introduction_node = IntroductionNode :: NodeId ( next_node_id) ;
298
+ path. 0 . blinded_hops . remove ( 0 ) ;
249
299
Ok ( ( ) )
250
300
} ,
251
301
_ => Err ( ( ) )
0 commit comments