@@ -28,6 +28,9 @@ use io::{self, Read};
2828use prelude:: * ;
2929use sync:: { Arc , Mutex } ;
3030
31+ pub ( crate ) const SMALL_PACKET_HOP_DATA_LEN : usize = 1300 ;
32+ pub ( crate ) const BIG_PACKET_HOP_DATA_LEN : usize = 32768 ;
33+
3134#[ derive( Clone , Debug , PartialEq ) ]
3235pub ( crate ) struct Packet {
3336 pub ( crate ) version : u8 ,
@@ -39,6 +42,13 @@ pub(crate) struct Packet {
3942 pub ( crate ) hmac : [ u8 ; 32 ] ,
4043}
4144
45+ impl Packet {
46+ fn len ( & self ) -> u16 {
47+ // 32 (hmac) + 33 (public_key) + 1 (version) = 66
48+ self . hop_data . len ( ) as u16 + 66
49+ }
50+ }
51+
4252impl Writeable for Packet {
4353 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
4454 self . version . write ( w) ?;
@@ -79,6 +89,59 @@ impl ReadableArgs<u16> for Packet {
7989 }
8090}
8191
92+ /// The payload of an onion message.
93+ pub ( crate ) struct Payload {
94+ /// Onion message payloads contain an encrypted TLV stream, containing both "control" TLVs and
95+ /// sometimes user-provided custom "data" TLVs. See [`EncryptedTlvs`] for more information.
96+ encrypted_tlvs : EncryptedTlvs ,
97+ // Coming soon:
98+ // * custom TLVs
99+ // * `message: Message` field
100+ // * `reply_path: Option<BlindedRoute>` field
101+ }
102+
103+ // Coming soon:
104+ // enum Message {
105+ // InvoiceRequest(InvoiceRequest),
106+ // Invoice(Invoice),
107+ // InvoiceError(InvoiceError),
108+ // CustomMessage<T>,
109+ // }
110+
111+ /// We want to avoid encoding and encrypting separately in order to avoid an intermediate Vec, thus
112+ /// we encode and encrypt at the same time using the `SharedSecret` here.
113+ impl Writeable for ( Payload , SharedSecret ) {
114+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
115+ match & self . 0 . encrypted_tlvs {
116+ EncryptedTlvs :: Blinded ( encrypted_bytes) => {
117+ encode_varint_length_prefixed_tlv ! ( w, {
118+ ( 4 , encrypted_bytes, vec_type)
119+ } )
120+ } ,
121+ EncryptedTlvs :: Unblinded ( control_tlvs) => {
122+ encode_varint_length_prefixed_tlv ! ( w, {
123+ ( 4 , control_tlvs, ( chacha, self . 1 ) )
124+ } )
125+ }
126+ }
127+ Ok ( ( ) )
128+ }
129+ }
130+
131+ /// Onion messages contain an encrypted TLV stream. This can be supplied by someone else, in the
132+ /// case that we're sending to a blinded route, or created by us if we're constructing payloads for
133+ /// unblinded hops in the onion message's path.
134+ pub ( crate ) enum EncryptedTlvs {
135+ /// If we're sending to a blinded route, the node that constructed the blinded route has provided
136+ /// our onion message's `EncryptedTlvs`, already encrypted and encoded into bytes.
137+ Blinded ( Vec < u8 > ) ,
138+ /// If we're receiving an onion message or constructing an onion message to send through any
139+ /// unblinded nodes, we'll need to construct the onion message's `EncryptedTlvs` in their
140+ /// unblinded state to avoid encoding them into an intermediate `Vec`.
141+ // Below will later have an additional Vec<CustomTlv>
142+ Unblinded ( ControlTlvs ) ,
143+ }
144+
82145/// Onion messages have "control" TLVs and "data" TLVs. Control TLVs are used to control the
83146/// direction and routing of an onion message from hop to hop, whereas data TLVs contain the onion
84147/// message content itself.
@@ -243,6 +306,23 @@ impl BlindedRoute {
243306 }
244307}
245308
309+ /// The destination of an onion message.
310+ pub enum Destination {
311+ /// We're sending this onion message to a node.
312+ Node ( PublicKey ) ,
313+ /// We're sending this onion message to a blinded route.
314+ BlindedRoute ( BlindedRoute ) ,
315+ }
316+
317+ impl Destination {
318+ fn num_hops ( & self ) -> usize {
319+ match self {
320+ Destination :: Node ( _) => 1 ,
321+ Destination :: BlindedRoute ( BlindedRoute { blinded_hops, .. } ) => blinded_hops. len ( ) ,
322+ }
323+ }
324+ }
325+
246326/// A sender, receiver and forwarder of onion messages. In upcoming releases, this object will be
247327/// used to retrieve invoices and fulfill invoice requests from offers.
248328pub struct OnionMessenger < Signer : Sign , K : Deref , L : Deref >
@@ -274,6 +354,38 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
274354 logger,
275355 }
276356 }
357+
358+ /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
359+ pub fn send_onion_message ( & self , intermediate_nodes : Vec < PublicKey > , destination : Destination ) -> Result < ( ) , secp256k1:: Error > {
360+ let blinding_secret_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
361+ let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
362+ let ( introduction_node_id, blinding_point) = if intermediate_nodes. len ( ) != 0 {
363+ ( intermediate_nodes[ 0 ] . clone ( ) , PublicKey :: from_secret_key ( & self . secp_ctx , & blinding_secret) )
364+ } else {
365+ match destination {
366+ Destination :: Node ( pk) => ( pk. clone ( ) , PublicKey :: from_secret_key ( & self . secp_ctx , & blinding_secret) ) ,
367+ Destination :: BlindedRoute ( BlindedRoute { introduction_node_id, blinding_point, .. } ) =>
368+ ( introduction_node_id. clone ( ) , blinding_point. clone ( ) ) ,
369+ }
370+ } ;
371+ let ( encrypted_data_keys, onion_packet_keys) = construct_sending_keys (
372+ & self . secp_ctx , & intermediate_nodes, & destination, & blinding_secret) ?;
373+ let payloads = build_payloads ( intermediate_nodes, destination, encrypted_data_keys) ;
374+
375+ let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
376+ let onion_packet = onion_utils:: construct_onion_message_packet ( payloads, onion_packet_keys, prng_seed) ;
377+
378+ let mut pending_msg_events = self . pending_msg_events . lock ( ) . unwrap ( ) ;
379+ pending_msg_events. push ( MessageSendEvent :: SendOnionMessage {
380+ node_id : introduction_node_id,
381+ msg : msgs:: OnionMessage {
382+ blinding_point,
383+ len : onion_packet. len ( ) ,
384+ onion_routing_packet : onion_packet,
385+ }
386+ } ) ;
387+ Ok ( ( ) )
388+ }
277389}
278390
279391impl < Signer : Sign , K : Deref , L : Deref > OnionMessageHandler for OnionMessenger < Signer , K , L >
@@ -295,9 +407,59 @@ impl<Signer: Sign, K: Deref, L: Deref> MessageSendEventsProvider for OnionMessen
295407 }
296408}
297409
410+ /// Build an onion message's payloads for encoding in the onion packet.
411+ fn build_payloads ( intermediate_nodes : Vec < PublicKey > , destination : Destination , mut encrypted_tlvs_keys : Vec < SharedSecret > ) -> Vec < ( Payload , SharedSecret ) > {
412+ let num_intermediate_nodes = intermediate_nodes. len ( ) ;
413+ let num_payloads = num_intermediate_nodes + destination. num_hops ( ) ;
414+ assert_eq ! ( encrypted_tlvs_keys. len( ) , num_payloads) ;
415+ let mut payloads = Vec :: with_capacity ( num_payloads) ;
416+ let mut enc_tlv_keys = encrypted_tlvs_keys. drain ( ..) ;
417+ for pk in intermediate_nodes. into_iter ( ) . skip ( 1 ) {
418+ payloads. push ( ( Payload {
419+ encrypted_tlvs : EncryptedTlvs :: Unblinded ( ControlTlvs :: Forward {
420+ next_node_id : pk,
421+ next_blinding_override : None ,
422+ } )
423+ } , enc_tlv_keys. next ( ) . unwrap ( ) ) ) ;
424+ }
425+ match destination {
426+ Destination :: Node ( pk) => {
427+ if num_intermediate_nodes != 0 {
428+ payloads. push ( ( Payload {
429+ encrypted_tlvs : EncryptedTlvs :: Unblinded ( ControlTlvs :: Forward {
430+ next_node_id : pk,
431+ next_blinding_override : None ,
432+ } )
433+ } , enc_tlv_keys. next ( ) . unwrap ( ) ) ) ;
434+ }
435+ payloads. push ( ( Payload {
436+ encrypted_tlvs : EncryptedTlvs :: Unblinded ( ControlTlvs :: Receive {
437+ path_id : None ,
438+ } )
439+ } , enc_tlv_keys. next ( ) . unwrap ( ) ) ) ;
440+ } ,
441+ Destination :: BlindedRoute ( BlindedRoute { introduction_node_id, blinding_point, blinded_hops } ) => {
442+ if num_intermediate_nodes != 0 {
443+ payloads. push ( ( Payload {
444+ encrypted_tlvs : EncryptedTlvs :: Unblinded ( ControlTlvs :: Forward {
445+ next_node_id : introduction_node_id,
446+ next_blinding_override : Some ( blinding_point) ,
447+ } )
448+ } , enc_tlv_keys. next ( ) . unwrap ( ) ) ) ;
449+ }
450+ for hop in blinded_hops {
451+ payloads. push ( ( Payload {
452+ encrypted_tlvs : EncryptedTlvs :: Blinded ( hop. encrypted_payload ) ,
453+ } , enc_tlv_keys. next ( ) . unwrap ( ) ) ) ;
454+ }
455+ }
456+ }
457+ payloads
458+ }
459+
298460#[ allow( unused_assignments) ]
299461#[ inline]
300- 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 > {
462+ 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 > , destination : Option < & Destination > , session_priv : & SecretKey , mut callback : FType ) -> Result < ( ) , secp256k1:: Error > {
301463 let mut msg_blinding_point_priv = session_priv. clone ( ) ;
302464 let mut msg_blinding_point = PublicKey :: from_secret_key ( secp_ctx, & msg_blinding_point_priv) ;
303465 let mut onion_packet_pubkey_priv = msg_blinding_point_priv. clone ( ) ;
@@ -345,6 +507,18 @@ fn construct_keys_callback<T: secp256k1::Signing + secp256k1::Verification, FTyp
345507 for pk in unblinded_path {
346508 build_keys ! ( pk, false ) ;
347509 }
510+ if let Some ( dest) = destination {
511+ match dest {
512+ Destination :: Node ( pk) => {
513+ build_keys ! ( pk, false ) ;
514+ } ,
515+ Destination :: BlindedRoute ( BlindedRoute { blinded_hops, .. } ) => {
516+ for hop in blinded_hops {
517+ build_keys ! ( hop. blinded_node_id, true ) ;
518+ }
519+ } ,
520+ }
521+ }
348522 Ok ( ( ) )
349523}
350524
@@ -359,14 +533,44 @@ fn construct_blinded_route_keys<T: secp256k1::Signing + secp256k1::Verification>
359533 let mut encrypted_data_keys = Vec :: with_capacity ( unblinded_path. len ( ) ) ;
360534 let mut blinded_node_pks = Vec :: with_capacity ( unblinded_path. len ( ) ) ;
361535
362- construct_keys_callback ( secp_ctx, unblinded_path, session_priv, |blinded_hop_pubkey, _, _, _, encrypted_data_ss| {
536+ construct_keys_callback ( secp_ctx, unblinded_path, None , session_priv, |blinded_hop_pubkey, _, _, _, encrypted_data_ss| {
363537 blinded_node_pks. push ( blinded_hop_pubkey) ;
364538 encrypted_data_keys. push ( encrypted_data_ss) ;
365539 } ) ?;
366540
367541 Ok ( ( encrypted_data_keys, blinded_node_pks) )
368542}
369543
544+ /// Construct keys for sending an onion message along the given `path`.
545+ ///
546+ /// Returns: `(encrypted_tlvs_keys, onion_packet_keys)`
547+ /// where the encrypted tlvs keys are used to encrypt the [`EncryptedTlvs`] of the onion message and the
548+ /// onion packet keys are used to encrypt the onion packet.
549+ fn construct_sending_keys < T : secp256k1:: Signing + secp256k1:: Verification > (
550+ secp_ctx : & Secp256k1 < T > , unblinded_path : & Vec < PublicKey > , destination : & Destination , session_priv : & SecretKey
551+ ) -> Result < ( Vec < SharedSecret > , Vec < onion_utils:: OnionKeys > ) , secp256k1:: Error > {
552+ let num_hops = unblinded_path. len ( ) + destination. num_hops ( ) ;
553+ let mut encrypted_data_keys = Vec :: with_capacity ( num_hops) ;
554+ let mut onion_packet_keys = Vec :: with_capacity ( num_hops) ;
555+
556+ construct_keys_callback ( secp_ctx, unblinded_path, Some ( destination) , session_priv, |_, onion_packet_ss, _blinding_factor, ephemeral_pubkey, encrypted_data_ss| {
557+ encrypted_data_keys. push ( encrypted_data_ss) ;
558+
559+ let ( rho, mu) = onion_utils:: gen_rho_mu_from_shared_secret ( onion_packet_ss. as_ref ( ) ) ;
560+ onion_packet_keys. push ( onion_utils:: OnionKeys {
561+ #[ cfg( test) ]
562+ shared_secret : onion_packet_ss,
563+ #[ cfg( test) ]
564+ blinding_factor : _blinding_factor,
565+ ephemeral_pubkey,
566+ rho,
567+ mu,
568+ } ) ;
569+ } ) ?;
570+
571+ Ok ( ( encrypted_data_keys, onion_packet_keys) )
572+ }
573+
370574/// Useful for simplifying the parameters of [`SimpleArcChannelManager`] and
371575/// [`SimpleArcPeerManager`]. See their docs for more details.
372576pub type SimpleArcOnionMessenger < L > = OnionMessenger < InMemorySigner , Arc < KeysManager > , Arc < L > > ;
0 commit comments