@@ -8,12 +8,14 @@ use core::num::ParseIntError;
88use core:: str;
99use core:: str:: FromStr ;
1010
11- use bech32:: { u5, FromBase32 } ;
11+ use bech32:: Bech32 ;
12+ use bech32:: primitives:: decode:: { CheckedHrpstring , CheckedHrpstringError } ;
1213
1314use bitcoin:: { PubkeyHash , ScriptHash , WitnessVersion } ;
1415use bitcoin:: hashes:: Hash ;
1516use bitcoin:: hashes:: sha256;
1617use crate :: prelude:: * ;
18+ use lightning:: util:: bech32:: { Bech32Error , FromBase32 , u5} ;
1719use lightning:: ln:: types:: PaymentSecret ;
1820use lightning:: routing:: gossip:: RoutingFees ;
1921use lightning:: routing:: router:: { RouteHint , RouteHintHop } ;
@@ -270,31 +272,32 @@ impl FromStr for SignedRawBolt11Invoice {
270272 type Err = Bolt11ParseError ;
271273
272274 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
273- let ( hrp, data, var) = bech32:: decode ( s) ?;
274275
275- if var == bech32:: Variant :: Bech32m {
276- // Consider Bech32m addresses to be "Invalid Checksum", since that is what we'd get if
277- // we didn't support Bech32m (which lightning does not use).
278- return Err ( Bolt11ParseError :: Bech32Error ( bech32:: Error :: InvalidChecksum ) ) ;
279- }
276+ let parsed = CheckedHrpstring :: new :: < Bech32 > ( s) ?;
277+ let hrp = parsed. hrp ( ) ;
278+ // access the parse data part as chars, covert to u5
279+ let data: Vec < _ > = parsed. data_part_ascii_no_checksum ( ) . iter ( )
280+ . map ( |ch| u5:: try_from_char ( char:: from ( * ch) ) . expect ( "value should be < 32" ) )
281+ . collect ( ) ;
280282
281- if data. len ( ) < 104 {
283+ const MIN_LEN : usize = 104 ;
284+ if data. len ( ) < MIN_LEN {
282285 return Err ( Bolt11ParseError :: TooShortDataPart ) ;
283286 }
284287
285- let raw_hrp: RawHrp = hrp. parse ( ) ?;
286- let data_part = RawDataPart :: from_base32 ( & data[ ..data. len ( ) -104 ] ) ?;
288+ let raw_hrp: RawHrp = hrp. to_string ( ) . to_lowercase ( ) . parse ( ) ?;
289+ let data_part = RawDataPart :: from_base32 ( & data[ ..data. len ( ) -MIN_LEN ] ) ?;
287290
288291 Ok ( SignedRawBolt11Invoice {
289292 raw_invoice : RawBolt11Invoice {
290293 hrp : raw_hrp,
291294 data : data_part,
292295 } ,
293296 hash : RawBolt11Invoice :: hash_from_parts (
294- hrp. as_bytes ( ) ,
295- & data[ ..data. len ( ) -104 ]
297+ hrp. to_string ( ) . as_bytes ( ) ,
298+ & data[ ..data. len ( ) -MIN_LEN ]
296299 ) ,
297- signature : Bolt11InvoiceSignature :: from_base32 ( & data[ data. len ( ) -104 ..] ) ?,
300+ signature : Bolt11InvoiceSignature :: from_base32 ( & data[ data. len ( ) -MIN_LEN ..] ) ?,
298301 } )
299302 }
300303}
@@ -389,7 +392,7 @@ macro_rules! define_parse_int_be { ($name: ident, $ty: ty) => {
389392 digits. iter( ) . fold( Some ( Default :: default ( ) ) , |acc, b|
390393 acc
391394 . and_then( |x| x. checked_mul( 32 ) )
392- . and_then( |x| x. checked_add( ( Into :: < u8 > :: into ( * b) ) . into( ) ) )
395+ . and_then( |x| x. checked_add( ( * b) . as_u8 ( ) . into( ) ) )
393396 )
394397 }
395398} }
@@ -424,7 +427,7 @@ fn parse_tagged_parts(data: &[u5]) -> Result<Vec<RawTaggedField>, Bolt11ParseErr
424427 Ok ( field) => {
425428 parts. push ( RawTaggedField :: KnownSemantics ( field) )
426429 } ,
427- Err ( Bolt11ParseError :: Skip ) |Err ( Bolt11ParseError :: Bech32Error ( bech32 :: Error :: InvalidLength ) ) => {
430+ Err ( Bolt11ParseError :: Skip ) |Err ( Bolt11ParseError :: Bech32Error ( _ ) ) => {
428431 parts. push ( RawTaggedField :: UnknownSemantics ( field. into ( ) ) )
429432 } ,
430433 Err ( e) => { return Err ( e) }
@@ -444,7 +447,7 @@ impl FromBase32 for TaggedField {
444447 let tag = field[ 0 ] ;
445448 let field_data = & field[ 3 ..] ;
446449
447- match tag. to_u8 ( ) {
450+ match tag. as_u8 ( ) {
448451 constants:: TAG_PAYMENT_HASH =>
449452 Ok ( TaggedField :: PaymentHash ( Sha256 :: from_base32 ( field_data) ?) ) ,
450453 constants:: TAG_DESCRIPTION =>
@@ -550,7 +553,7 @@ impl FromBase32 for Fallback {
550553 return Err ( Bolt11ParseError :: UnexpectedEndOfTaggedFields ) ;
551554 }
552555
553- let version = field_data[ 0 ] . to_u8 ( ) ;
556+ let version = field_data[ 0 ] . as_u8 ( ) ;
554557 let bytes = Vec :: < u8 > :: from_base32 ( & field_data[ 1 ..] ) ?;
555558
556559 match version {
@@ -629,6 +632,9 @@ impl Display for Bolt11ParseError {
629632 Bolt11ParseError :: Bech32Error ( ref e) => {
630633 write ! ( f, "Invalid bech32: {}" , e)
631634 }
635+ Bolt11ParseError :: Bech32ExternalError ( ref e) => {
636+ write ! ( f, "Invalid bech32: {}" , e)
637+ }
632638 Bolt11ParseError :: ParseAmountError ( ref e) => {
633639 write ! ( f, "Invalid amount in hrp ({})" , e)
634640 }
@@ -703,10 +709,17 @@ from_error!(Bolt11ParseError::MalformedSignature, secp256k1::Error);
703709from_error ! ( Bolt11ParseError :: ParseAmountError , ParseIntError ) ;
704710from_error ! ( Bolt11ParseError :: DescriptionDecodeError , str :: Utf8Error ) ;
705711
706- impl From < bech32:: Error > for Bolt11ParseError {
707- fn from ( e : bech32:: Error ) -> Self {
712+ impl From < CheckedHrpstringError > for Bolt11ParseError {
713+ fn from ( e : CheckedHrpstringError ) -> Self {
714+ match e {
715+ _ => Bolt11ParseError :: Bech32ExternalError ( e)
716+ }
717+ }
718+ }
719+
720+ impl From < Bech32Error > for Bolt11ParseError {
721+ fn from ( e : Bech32Error ) -> Self {
708722 match e {
709- bech32:: Error :: InvalidPadding => Bolt11ParseError :: PaddingError ,
710723 _ => Bolt11ParseError :: Bech32Error ( e)
711724 }
712725 }
@@ -726,9 +739,9 @@ impl From<crate::Bolt11SemanticError> for ParseOrSemanticError {
726739
727740#[ cfg( test) ]
728741mod test {
742+ use super :: { u5, FromBase32 } ;
729743 use crate :: de:: Bolt11ParseError ;
730744 use secp256k1:: PublicKey ;
731- use bech32:: u5;
732745 use bitcoin:: hashes:: sha256;
733746 use std:: str:: FromStr ;
734747
@@ -779,7 +792,6 @@ mod test {
779792 #[ test]
780793 fn test_parse_sha256_hash ( ) {
781794 use crate :: Sha256 ;
782- use bech32:: FromBase32 ;
783795
784796 let input = from_bech32 (
785797 "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq" . as_bytes ( )
@@ -802,7 +814,6 @@ mod test {
802814 #[ test]
803815 fn test_parse_description ( ) {
804816 use crate :: Description ;
805- use bech32:: FromBase32 ;
806817
807818 let input = from_bech32 ( "xysxxatsyp3k7enxv4js" . as_bytes ( ) ) ;
808819 let expected = Ok ( Description :: new ( "1 cup coffee" . to_owned ( ) ) . unwrap ( ) ) ;
@@ -812,7 +823,6 @@ mod test {
812823 #[ test]
813824 fn test_parse_payee_pub_key ( ) {
814825 use crate :: PayeePubKey ;
815- use bech32:: FromBase32 ;
816826
817827 let input = from_bech32 ( "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66" . as_bytes ( ) ) ;
818828 let pk_bytes = [
@@ -836,7 +846,6 @@ mod test {
836846 #[ test]
837847 fn test_parse_expiry_time ( ) {
838848 use crate :: ExpiryTime ;
839- use bech32:: FromBase32 ;
840849
841850 let input = from_bech32 ( "pu" . as_bytes ( ) ) ;
842851 let expected = Ok ( ExpiryTime :: from_seconds ( 60 ) ) ;
@@ -849,7 +858,6 @@ mod test {
849858 #[ test]
850859 fn test_parse_min_final_cltv_expiry_delta ( ) {
851860 use crate :: MinFinalCltvExpiryDelta ;
852- use bech32:: FromBase32 ;
853861
854862 let input = from_bech32 ( "pr" . as_bytes ( ) ) ;
855863 let expected = Ok ( MinFinalCltvExpiryDelta ( 35 ) ) ;
@@ -860,7 +868,6 @@ mod test {
860868 #[ test]
861869 fn test_parse_fallback ( ) {
862870 use crate :: Fallback ;
863- use bech32:: FromBase32 ;
864871 use bitcoin:: { PubkeyHash , ScriptHash , WitnessVersion } ;
865872 use bitcoin:: hashes:: Hash ;
866873
@@ -921,7 +928,6 @@ mod test {
921928 use lightning:: routing:: gossip:: RoutingFees ;
922929 use lightning:: routing:: router:: { RouteHint , RouteHintHop } ;
923930 use crate :: PrivateRoute ;
924- use bech32:: FromBase32 ;
925931
926932 let input = from_bech32 (
927933 "q20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqa\
@@ -967,7 +973,7 @@ mod test {
967973 assert_eq ! ( PrivateRoute :: from_base32( & input) , Ok ( PrivateRoute ( RouteHint ( expected) ) ) ) ;
968974
969975 assert_eq ! (
970- PrivateRoute :: from_base32( & [ u5:: try_from_u8 ( 0 ) . unwrap ( ) ; 40 ] [ ..] ) ,
976+ PrivateRoute :: from_base32( & [ u5:: ZERO ; 40 ] [ ..] ) ,
971977 Err ( Bolt11ParseError :: UnexpectedEndOfTaggedFields )
972978 ) ;
973979 }
0 commit comments