@@ -13,9 +13,11 @@ use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
1313
1414use chain:: keysinterface:: KeysInterface ;
1515use super :: utils;
16+ use :: get_control_tlv_length;
1617use ln:: msgs:: DecodeError ;
1718use util:: chacha20poly1305rfc:: ChaChaPolyWriteAdapter ;
1819use util:: ser:: { Readable , VecWriter , Writeable , Writer } ;
20+ use super :: packet:: { ControlTlvs , Padding } ;
1921
2022use io;
2123use prelude:: * ;
@@ -54,10 +56,11 @@ impl BlindedRoute {
5456 /// will be the destination node.
5557 ///
5658 /// Errors if less than two hops are provided or if `node_pk`(s) are invalid.
57- // TODO: make all payloads the same size with padding + add dummy hops
58- pub fn new < K : KeysInterface , T : secp256k1:: Signing + secp256k1:: Verification >
59- ( node_pks : & [ PublicKey ] , keys_manager : & K , secp_ctx : & Secp256k1 < T > ) -> Result < Self , ( ) >
60- {
59+ // TODO: Add dummy hops
60+ pub fn new < K : KeysInterface , T : secp256k1:: Signing + secp256k1:: Verification > (
61+ node_pks : & [ PublicKey ] , keys_manager : & K , secp_ctx : & Secp256k1 < T > ,
62+ include_next_blinding_override_padding : bool
63+ ) -> Result < Self , ( ) > {
6164 if node_pks. len ( ) < 2 { return Err ( ( ) ) }
6265 let blinding_secret_bytes = keys_manager. get_secure_random_bytes ( ) ;
6366 let blinding_secret = SecretKey :: from_slice ( & blinding_secret_bytes[ ..] ) . expect ( "RNG is busted" ) ;
@@ -66,16 +69,18 @@ impl BlindedRoute {
6669 Ok ( BlindedRoute {
6770 introduction_node_id,
6871 blinding_point : PublicKey :: from_secret_key ( secp_ctx, & blinding_secret) ,
69- blinded_hops : blinded_hops ( secp_ctx, node_pks, & blinding_secret) . map_err ( |_| ( ) ) ?,
72+ blinded_hops : blinded_hops ( secp_ctx, node_pks, & blinding_secret, include_next_blinding_override_padding ) . map_err ( |_| ( ) ) ?,
7073 } )
7174 }
7275}
7376
7477/// Construct blinded hops for the given `unblinded_path`.
7578fn blinded_hops < T : secp256k1:: Signing + secp256k1:: Verification > (
76- secp_ctx : & Secp256k1 < T > , unblinded_path : & [ PublicKey ] , session_priv : & SecretKey
79+ secp_ctx : & Secp256k1 < T > , unblinded_path : & [ PublicKey ] , session_priv : & SecretKey ,
80+ include_next_blinding_override_padding : bool
7781) -> Result < Vec < BlindedHop > , secp256k1:: Error > {
7882 let mut blinded_hops = Vec :: with_capacity ( unblinded_path. len ( ) ) ;
83+ let max_length = get_control_tlv_length ! ( true , include_next_blinding_override_padding) ;
7984
8085 let mut prev_ss_and_blinded_node_id = None ;
8186 utils:: construct_keys_callback ( secp_ctx, unblinded_path, None , session_priv, |blinded_node_id, _, _, encrypted_payload_ss, unblinded_pk, _| {
@@ -84,6 +89,7 @@ fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
8489 let payload = ForwardTlvs {
8590 next_node_id : pk,
8691 next_blinding_override : None ,
92+ total_length : max_length,
8793 } ;
8894 blinded_hops. push ( BlindedHop {
8995 blinded_node_id : prev_blinded_node_id,
@@ -95,7 +101,7 @@ fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
95101 } ) ?;
96102
97103 if let Some ( ( final_ss, final_blinded_node_id) ) = prev_ss_and_blinded_node_id {
98- let final_payload = ReceiveTlvs { path_id : None } ;
104+ let final_payload = ReceiveTlvs { path_id : None , total_length : max_length , } ;
99105 blinded_hops. push ( BlindedHop {
100106 blinded_node_id : final_blinded_node_id,
101107 encrypted_payload : encrypt_payload ( final_payload, final_ss) ,
@@ -150,37 +156,45 @@ impl_writeable!(BlindedHop, {
150156
151157/// TLVs to encode in an intermediate onion message packet's hop data. When provided in a blinded
152158/// route, they are encoded into [`BlindedHop::encrypted_payload`].
159+ #[ derive( Clone , Copy ) ]
153160pub ( crate ) struct ForwardTlvs {
154161 /// The node id of the next hop in the onion message's path.
155162 pub ( super ) next_node_id : PublicKey ,
156163 /// Senders to a blinded route use this value to concatenate the route they find to the
157164 /// introduction node with the blinded route.
158165 pub ( super ) next_blinding_override : Option < PublicKey > ,
166+ /// The length the tlv should have when it's serialized, with padding included if needed.
167+ /// Used to ensure that all control tlvs in a blinded route have the same length.
168+ pub ( super ) total_length : u16 ,
159169}
160170
161171/// Similar to [`ForwardTlvs`], but these TLVs are for the final node.
172+ #[ derive( Clone , Copy ) ]
162173pub ( crate ) struct ReceiveTlvs {
163174 /// If `path_id` is `Some`, it is used to identify the blinded route that this onion message is
164175 /// sending to. This is useful for receivers to check that said blinded route is being used in
165176 /// the right context.
166177 pub ( super ) path_id : Option < [ u8 ; 32 ] > ,
178+ /// The length the tlv should have when it's serialized, with padding included if needed.
179+ /// Used to ensure that all control tlvs in a blinded route have the same length.
180+ pub ( super ) total_length : u16 ,
167181}
168182
169183impl Writeable for ForwardTlvs {
170184 fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
171- // TODO: write padding
172185 encode_tlv_stream ! ( writer, {
186+ ( 1 , Padding :: new_from_tlv( ControlTlvs :: Forward ( * self ) ) , option) ,
173187 ( 4 , self . next_node_id, required) ,
174- ( 8 , self . next_blinding_override, option)
188+ ( 8 , self . next_blinding_override, option) ,
175189 } ) ;
176190 Ok ( ( ) )
177191 }
178192}
179193
180194impl Writeable for ReceiveTlvs {
181195 fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
182- // TODO: write padding
183196 encode_tlv_stream ! ( writer, {
197+ ( 1 , Padding :: new_from_tlv( ControlTlvs :: Receive ( * self ) ) , option) ,
184198 ( 6 , self . path_id, option) ,
185199 } ) ;
186200 Ok ( ( ) )
0 commit comments