@@ -194,6 +194,26 @@ impl OnionPacket {
194194 bytes
195195 }
196196
197+ /// Converts back from a byte vector.
198+ pub fn from_bytes ( bytes : Vec < u8 > ) -> Result < Self , SphinxError > {
199+ if bytes. len ( ) < 66 {
200+ return Err ( SphinxError :: PacketDataLenTooSmall ) ;
201+ }
202+ let version = bytes[ 0 ] ;
203+ let public_key =
204+ PublicKey :: from_slice ( & bytes[ 1 ..34 ] ) . map_err ( |_| SphinxError :: PublicKeyInvalid ) ?;
205+ let packet_data = ( & bytes[ 34 ..( bytes. len ( ) - 32 ) ] ) . into ( ) ;
206+ let mut hmac = [ 0u8 ; 32 ] ;
207+ hmac. copy_from_slice ( & bytes[ ( bytes. len ( ) - 32 ) ..] ) ;
208+
209+ Ok ( Self {
210+ version,
211+ public_key,
212+ packet_data,
213+ hmac,
214+ } )
215+ }
216+
197217 /// Derives the shared secret using the node secret key and the ephemeral public key in the onion packet.
198218 pub fn shared_secret ( & self , secret_key : & SecretKey ) -> [ u8 ; 32 ] {
199219 SharedSecret :: new ( & self . public_key , secret_key) . secret_bytes ( )
@@ -342,6 +362,10 @@ impl OnionErrorPacket {
342362 pub fn into_bytes ( self ) -> Vec < u8 > {
343363 self . packet_data
344364 }
365+
366+ pub fn from_bytes ( bytes : Vec < u8 > ) -> Self {
367+ Self { packet_data : bytes }
368+ }
345369}
346370
347371#[ derive( Error , Debug , Eq , PartialEq ) ]
@@ -360,6 +384,12 @@ pub enum SphinxError {
360384
361385 #[ error( "The parsed data len is larger than the onion packet len" ) ]
362386 HopDataLenTooLarge ,
387+
388+ #[ error( "The parsed data len is too small" ) ]
389+ PacketDataLenTooSmall ,
390+
391+ #[ error( "Invalid public key" ) ]
392+ PublicKeyInvalid ,
363393}
364394
365395/// Keys used to forward the onion packet.
@@ -703,6 +733,26 @@ mod tests {
703733 ]
704734 }
705735
736+ #[ test]
737+ fn test_onion_packet_from_bytes ( ) {
738+ let public_key = PublicKey :: from_slice (
739+ Vec :: from_hex ( "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619" )
740+ . expect ( "valid hex" )
741+ . as_ref ( ) ,
742+ )
743+ . expect ( "valid public key" ) ;
744+ let packet = OnionPacket {
745+ version : 1 ,
746+ public_key,
747+ packet_data : vec ! [ 2 ] ,
748+ hmac : [ 3 ; 32 ] ,
749+ } ;
750+ let packet_from_bytes_res = OnionPacket :: from_bytes ( packet. clone ( ) . into_bytes ( ) ) ;
751+ assert ! ( packet_from_bytes_res. is_ok( ) ) ;
752+ let packet_from_bytes = packet_from_bytes_res. unwrap ( ) ;
753+ assert_eq ! ( packet_from_bytes, packet) ;
754+ }
755+
706756 #[ test]
707757 fn test_derive_hops_keys ( ) {
708758 let hops_path = get_test_hops_path ( ) ;
0 commit comments