@@ -26,6 +26,7 @@ use crate::blech32::{Blech32, Blech32m};
2626use crate :: hashes:: Hash ;
2727use bitcoin:: base58;
2828use bitcoin:: PublicKey ;
29+ use internals:: array:: ArrayExt as _;
2930use secp256k1_zkp;
3031use secp256k1_zkp:: Secp256k1 ;
3132use secp256k1_zkp:: Verification ;
@@ -486,35 +487,39 @@ impl Address {
486487
487488 // data.len() should be >= 1 when this method is called
488489 fn from_base58 ( data : & [ u8 ] , params : & ' static AddressParams ) -> Result < Address , AddressError > {
490+ let len_error = AddressError :: InvalidLength ( data. len ( ) ) ;
489491 // When unblinded, the structure is:
490492 // <1: regular prefix> <20: hash160>
491493 // When blinded, the structure is:
492494 // <1: blinding prefix> <1: regular prefix> <33: blinding pubkey> <20: hash160>
493495
494- let blinded = data[ 0 ] == params. blinded_prefix ;
495- let prefix = match ( blinded, data. len ( ) ) {
496- ( true , 55 ) => data[ 1 ] ,
497- ( false , 21 ) => data[ 0 ] ,
498- ( _, len) => return Err ( AddressError :: InvalidLength ( len) ) ,
496+ let Some ( ( blinding_prefix, blinded_data) ) = data. split_first ( ) else {
497+ return Err ( len_error) ;
499498 } ;
500499
501- let ( blinding_pubkey, payload_data) = match blinded {
502- true => (
503- Some (
504- secp256k1_zkp:: PublicKey :: from_slice ( & data[ 2 ..35 ] )
505- . map_err ( AddressError :: InvalidBlindingPubKey ) ?,
506- ) ,
507- & data[ 35 ..] ,
508- ) ,
509- false => ( None , & data[ 1 ..] ) ,
500+ let ( prefix, blinding_pubkey, hash) = if * blinding_prefix == params. blinded_prefix {
501+ let Some ( ( prefix, pubkey_and_hash) ) = blinded_data. split_first ( ) else {
502+ return Err ( len_error) ;
503+ } ;
504+
505+ let pubkey_and_hash = <& [ u8 ; 53 ] >:: try_from ( pubkey_and_hash) . map_err ( |_| len_error) ?;
506+ let ( pubkey, hash) = pubkey_and_hash. split_array :: < 33 , 20 > ( ) ;
507+
508+ let blinding_pubkey = secp256k1_zkp:: PublicKey :: from_slice ( pubkey)
509+ . map_err ( AddressError :: InvalidBlindingPubKey ) ?;
510+
511+ ( prefix, Some ( blinding_pubkey) , hash)
512+ } else {
513+ let hash = <& [ u8 ; 20 ] >:: try_from ( blinded_data) . map_err ( |_| len_error) ?;
514+ ( blinding_prefix, None , hash)
510515 } ;
511516
512- let payload = if prefix == params. p2pkh_prefix {
513- Payload :: PubkeyHash ( PubkeyHash :: from_slice ( payload_data ) . unwrap ( ) )
514- } else if prefix == params. p2sh_prefix {
515- Payload :: ScriptHash ( ScriptHash :: from_slice ( payload_data ) . unwrap ( ) )
517+ let payload = if * prefix == params. p2pkh_prefix {
518+ Payload :: PubkeyHash ( PubkeyHash :: from_byte_array ( * hash ) )
519+ } else if * prefix == params. p2sh_prefix {
520+ Payload :: ScriptHash ( ScriptHash :: from_byte_array ( * hash ) )
516521 } else {
517- return Err ( AddressError :: InvalidAddressVersion ( prefix) ) ;
522+ return Err ( AddressError :: InvalidAddressVersion ( * prefix) ) ;
518523 } ;
519524
520525 Ok ( Address {
0 commit comments