99
1010//! Onion message utility methods live here.
1111
12- use bitcoin:: hashes:: { Hash , HashEngine } ;
1312use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
1413use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
15- use bitcoin:: secp256k1 :: { self , PublicKey , Secp256k1 , SecretKey , Scalar } ;
14+ use bitcoin:: hashes :: { Hash , HashEngine } ;
1615use bitcoin:: secp256k1:: ecdh:: SharedSecret ;
16+ use bitcoin:: secp256k1:: { self , PublicKey , Scalar , Secp256k1 , SecretKey } ;
1717
18- use super :: { BlindedHop , BlindedPath } ;
1918use super :: message:: BlindedMessagePath ;
19+ use super :: { BlindedHop , BlindedPath } ;
20+ use crate :: crypto:: streams:: ChaChaPolyWriteAdapter ;
2021use crate :: ln:: msgs:: DecodeError ;
2122use crate :: ln:: onion_utils;
2223use crate :: onion_message:: messenger:: Destination ;
23- use crate :: crypto:: streams:: ChaChaPolyWriteAdapter ;
2424use crate :: util:: ser:: { Readable , Writeable } ;
2525
2626use crate :: io;
@@ -32,60 +32,80 @@ use crate::prelude::*;
3232
3333// TODO: DRY with onion_utils::construct_onion_keys_callback
3434macro_rules! build_keys_helper {
35- ( $session_priv: ident, $secp_ctx: ident, $callback: ident) =>
36- {
37- let mut msg_blinding_point_priv = $session_priv. clone( ) ;
38- let mut msg_blinding_point = PublicKey :: from_secret_key( $secp_ctx, & msg_blinding_point_priv) ;
39- let mut onion_packet_pubkey_priv = msg_blinding_point_priv. clone( ) ;
40- let mut onion_packet_pubkey = msg_blinding_point. clone( ) ;
41-
42- macro_rules! build_keys {
43- ( $hop: expr, $blinded: expr, $encrypted_payload: expr) => { {
44- let pk = * $hop. borrow( ) ;
45- let encrypted_data_ss = SharedSecret :: new( & pk, & msg_blinding_point_priv) ;
46-
47- let blinded_hop_pk = if $blinded { pk } else {
48- let hop_pk_blinding_factor = {
49- let mut hmac = HmacEngine :: <Sha256 >:: new( b"blinded_node_id" ) ;
50- hmac. input( encrypted_data_ss. as_ref( ) ) ;
51- Hmac :: from_engine( hmac) . to_byte_array( )
35+ ( $session_priv: ident, $secp_ctx: ident, $callback: ident) => {
36+ let mut msg_blinding_point_priv = $session_priv. clone( ) ;
37+ let mut msg_blinding_point =
38+ PublicKey :: from_secret_key( $secp_ctx, & msg_blinding_point_priv) ;
39+ let mut onion_packet_pubkey_priv = msg_blinding_point_priv. clone( ) ;
40+ let mut onion_packet_pubkey = msg_blinding_point. clone( ) ;
41+
42+ macro_rules! build_keys {
43+ ( $hop: expr, $blinded: expr, $encrypted_payload: expr) => { {
44+ let pk = * $hop. borrow( ) ;
45+ let encrypted_data_ss = SharedSecret :: new( & pk, & msg_blinding_point_priv) ;
46+
47+ let blinded_hop_pk = if $blinded {
48+ pk
49+ } else {
50+ let hop_pk_blinding_factor = {
51+ let mut hmac = HmacEngine :: <Sha256 >:: new( b"blinded_node_id" ) ;
52+ hmac. input( encrypted_data_ss. as_ref( ) ) ;
53+ Hmac :: from_engine( hmac) . to_byte_array( )
54+ } ;
55+ pk. mul_tweak(
56+ $secp_ctx,
57+ & Scalar :: from_be_bytes( hop_pk_blinding_factor) . unwrap( ) ,
58+ ) ?
5259 } ;
53- pk. mul_tweak( $secp_ctx, & Scalar :: from_be_bytes( hop_pk_blinding_factor) . unwrap( ) ) ?
54- } ;
55- let onion_packet_ss = SharedSecret :: new( & blinded_hop_pk, & onion_packet_pubkey_priv) ;
56-
57- let rho = onion_utils:: gen_rho_from_shared_secret( encrypted_data_ss. as_ref( ) ) ;
58- let unblinded_hop_opt = if $blinded { None } else { Some ( $hop) } ;
59- $callback( blinded_hop_pk, onion_packet_ss, onion_packet_pubkey, rho, unblinded_hop_opt, $encrypted_payload) ;
60- ( encrypted_data_ss, onion_packet_ss)
61- } }
62- }
63-
64- macro_rules! build_keys_in_loop {
65- ( $pk: expr, $blinded: expr, $encrypted_payload: expr) => {
66- let ( encrypted_data_ss, onion_packet_ss) = build_keys!( $pk, $blinded, $encrypted_payload) ;
60+ let onion_packet_ss = SharedSecret :: new( & blinded_hop_pk, & onion_packet_pubkey_priv) ;
61+
62+ let rho = onion_utils:: gen_rho_from_shared_secret( encrypted_data_ss. as_ref( ) ) ;
63+ let unblinded_hop_opt = if $blinded { None } else { Some ( $hop) } ;
64+ $callback(
65+ blinded_hop_pk,
66+ onion_packet_ss,
67+ onion_packet_pubkey,
68+ rho,
69+ unblinded_hop_opt,
70+ $encrypted_payload,
71+ ) ;
72+ ( encrypted_data_ss, onion_packet_ss)
73+ } } ;
74+ }
6775
68- let msg_blinding_point_blinding_factor = {
69- let mut sha = Sha256 :: engine( ) ;
70- sha. input( & msg_blinding_point. serialize( ) [ ..] ) ;
71- sha. input( encrypted_data_ss. as_ref( ) ) ;
72- Sha256 :: from_engine( sha) . to_byte_array( )
73- } ;
76+ macro_rules! build_keys_in_loop {
77+ ( $pk: expr, $blinded: expr, $encrypted_payload: expr) => {
78+ let ( encrypted_data_ss, onion_packet_ss) =
79+ build_keys!( $pk, $blinded, $encrypted_payload) ;
7480
75- msg_blinding_point_priv = msg_blinding_point_priv. mul_tweak( & Scalar :: from_be_bytes( msg_blinding_point_blinding_factor) . unwrap( ) ) ?;
76- msg_blinding_point = PublicKey :: from_secret_key( $secp_ctx, & msg_blinding_point_priv) ;
81+ let msg_blinding_point_blinding_factor = {
82+ let mut sha = Sha256 :: engine( ) ;
83+ sha. input( & msg_blinding_point. serialize( ) [ ..] ) ;
84+ sha. input( encrypted_data_ss. as_ref( ) ) ;
85+ Sha256 :: from_engine( sha) . to_byte_array( )
86+ } ;
7787
78- let onion_packet_pubkey_blinding_factor = {
79- let mut sha = Sha256 :: engine( ) ;
80- sha. input( & onion_packet_pubkey. serialize( ) [ ..] ) ;
81- sha. input( onion_packet_ss. as_ref( ) ) ;
82- Sha256 :: from_engine( sha) . to_byte_array( )
88+ msg_blinding_point_priv = msg_blinding_point_priv. mul_tweak(
89+ & Scalar :: from_be_bytes( msg_blinding_point_blinding_factor) . unwrap( ) ,
90+ ) ?;
91+ msg_blinding_point =
92+ PublicKey :: from_secret_key( $secp_ctx, & msg_blinding_point_priv) ;
93+
94+ let onion_packet_pubkey_blinding_factor = {
95+ let mut sha = Sha256 :: engine( ) ;
96+ sha. input( & onion_packet_pubkey. serialize( ) [ ..] ) ;
97+ sha. input( onion_packet_ss. as_ref( ) ) ;
98+ Sha256 :: from_engine( sha) . to_byte_array( )
99+ } ;
100+ onion_packet_pubkey_priv = onion_packet_pubkey_priv. mul_tweak(
101+ & Scalar :: from_be_bytes( onion_packet_pubkey_blinding_factor) . unwrap( ) ,
102+ ) ?;
103+ onion_packet_pubkey =
104+ PublicKey :: from_secret_key( $secp_ctx, & onion_packet_pubkey_priv) ;
83105 } ;
84- onion_packet_pubkey_priv = onion_packet_pubkey_priv. mul_tweak( & Scalar :: from_be_bytes( onion_packet_pubkey_blinding_factor) . unwrap( ) ) ?;
85- onion_packet_pubkey = PublicKey :: from_secret_key( $secp_ctx, & onion_packet_pubkey_priv) ;
86- } ;
87- }
88- } }
106+ }
107+ } ;
108+ }
89109
90110#[ inline]
91111pub ( crate ) fn construct_keys_for_onion_message < ' a , T , I , F > (
@@ -94,7 +114,7 @@ pub(crate) fn construct_keys_for_onion_message<'a, T, I, F>(
94114) -> Result < ( ) , secp256k1:: Error >
95115where
96116 T : secp256k1:: Signing + secp256k1:: Verification ,
97- I : Iterator < Item = PublicKey > ,
117+ I : Iterator < Item = PublicKey > ,
98118 F : FnMut ( PublicKey , SharedSecret , PublicKey , [ u8 ; 32 ] , Option < PublicKey > , Option < Vec < u8 > > ) ,
99119{
100120 build_keys_helper ! ( session_priv, secp_ctx, callback) ;
@@ -122,7 +142,7 @@ pub(super) fn construct_keys_for_blinded_path<'a, T, I, F, H>(
122142where
123143 T : secp256k1:: Signing + secp256k1:: Verification ,
124144 H : Borrow < PublicKey > ,
125- I : Iterator < Item = H > ,
145+ I : Iterator < Item = H > ,
126146 F : FnMut ( PublicKey , SharedSecret , PublicKey , [ u8 ; 32 ] , Option < H > , Option < Vec < u8 > > ) ,
127147{
128148 build_keys_helper ! ( session_priv, secp_ctx, callback) ;
@@ -134,8 +154,8 @@ where
134154}
135155
136156struct PublicKeyWithTlvs < W : Writeable > {
137- pubkey : PublicKey ,
138- tlvs : W ,
157+ pubkey : PublicKey ,
158+ tlvs : W ,
139159}
140160
141161impl < W : Writeable > Borrow < PublicKey > for PublicKeyWithTlvs < W > {
@@ -149,18 +169,24 @@ pub(crate) fn construct_blinded_hops<'a, T, I, W>(
149169) -> Result < Vec < BlindedHop > , secp256k1:: Error >
150170where
151171 T : secp256k1:: Signing + secp256k1:: Verification ,
152- I : Iterator < Item = ( PublicKey , W ) > ,
153- W : Writeable
172+ I : Iterator < Item = ( PublicKey , W ) > ,
173+ W : Writeable ,
154174{
155175 let mut blinded_hops = Vec :: with_capacity ( unblinded_path. size_hint ( ) . 0 ) ;
156176 construct_keys_for_blinded_path (
157- secp_ctx, unblinded_path. map ( |( pubkey, tlvs) | PublicKeyWithTlvs { pubkey, tlvs } ) , session_priv,
177+ secp_ctx,
178+ unblinded_path. map ( |( pubkey, tlvs) | PublicKeyWithTlvs { pubkey, tlvs } ) ,
179+ session_priv,
158180 |blinded_node_id, _, _, encrypted_payload_rho, unblinded_hop_data, _| {
159181 blinded_hops. push ( BlindedHop {
160182 blinded_node_id,
161- encrypted_payload : encrypt_payload ( unblinded_hop_data. unwrap ( ) . tlvs , encrypted_payload_rho) ,
183+ encrypted_payload : encrypt_payload (
184+ unblinded_hop_data. unwrap ( ) . tlvs ,
185+ encrypted_payload_rho,
186+ ) ,
162187 } ) ;
163- } ) ?;
188+ } ,
189+ ) ?;
164190 Ok ( blinded_hops)
165191}
166192
@@ -179,7 +205,9 @@ impl Readable for Padding {
179205 fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
180206 loop {
181207 let mut buf = [ 0 ; 8192 ] ;
182- if reader. read ( & mut buf[ ..] ) ? == 0 { break ; }
208+ if reader. read ( & mut buf[ ..] ) ? == 0 {
209+ break ;
210+ }
183211 }
184212 Ok ( Self { } )
185213 }
0 commit comments