@@ -528,6 +528,31 @@ pub enum Fallback {
528528#[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
529529pub struct Bolt11InvoiceSignature ( pub RecoverableSignature ) ;
530530
531+ /*
532+ impl Bolt11InvoiceSignature {
533+ fn from_bytes(data: &[u8]) -> Result<Self, Bolt11ParseError> {
534+ use bitcoin::secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
535+
536+ const SIGNATURE_LEN: usize = 65;
537+ if data.len() != SIGNATURE_LEN {
538+ return Err(Bolt11ParseError::InvalidSliceLength(
539+ data.len(),
540+ SIGNATURE_LEN,
541+ "Bolt11InvoiceSignature::from_bytes()".into(),
542+ ));
543+ }
544+ let signature = &data[0..64];
545+ let recovery_id = RecoveryId::from_i32(data[64] as i32)?;
546+ debug_assert_eq!(recovery_id.to_i32(), 0);
547+
548+ Ok(Bolt11InvoiceSignature(RecoverableSignature::from_compact(
549+ signature,
550+ recovery_id
551+ )?))
552+ }
553+ }
554+ */
555+
531556impl PartialOrd for Bolt11InvoiceSignature {
532557 fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
533558 Some ( self . cmp ( other) )
@@ -998,6 +1023,84 @@ macro_rules! find_all_extract {
9981023 } ;
9991024}
10001025
1026+ /// Adaptor to pad a Fe32 iter
1027+ // #[derive(Clone, PartialEq, Eq)]
1028+ pub struct FesPadder < I : Iterator < Item = Fe32 > > {
1029+ end_reached : bool ,
1030+ fe32_count : usize ,
1031+ pad_count : u8 ,
1032+ iter : I ,
1033+ }
1034+
1035+ impl < I > FesPadder < I >
1036+ where
1037+ I : Iterator < Item = Fe32 > ,
1038+ {
1039+ // type Item = u8;
1040+
1041+ fn new ( iter : I ) -> Self {
1042+ Self {
1043+ end_reached : false ,
1044+ fe32_count : 0 ,
1045+ pad_count : 0 ,
1046+ iter,
1047+ }
1048+ }
1049+
1050+ fn pad_count_from_fe32_count ( fe32_count : usize ) -> u8 {
1051+ let remainder = ( fe32_count * 5 ) % 8 ;
1052+ if remainder == 0 { 0 } else if remainder < 3 { 2 } else { 1 }
1053+ }
1054+
1055+ fn padded_count ( fe32_count : usize ) -> usize {
1056+ fe32_count + Self :: pad_count_from_fe32_count ( fe32_count) as usize
1057+ }
1058+ }
1059+
1060+ impl < I > Iterator for FesPadder < I >
1061+ where
1062+ I : Iterator < Item = Fe32 > ,
1063+ {
1064+ type Item = Fe32 ;
1065+
1066+ fn next ( & mut self ) -> Option < Self :: Item > {
1067+ if let Some ( elem) = self . iter . next ( ) {
1068+ self . fe32_count += 1 ;
1069+ Some ( elem)
1070+ } else {
1071+ // end reached
1072+ if !self . end_reached {
1073+ self . end_reached = true ;
1074+ self . pad_count = Self :: pad_count_from_fe32_count ( self . fe32_count ) ;
1075+ }
1076+ if self . pad_count > 0 {
1077+ self . pad_count -= 1 ;
1078+ Some ( Fe32 :: Q )
1079+ } else {
1080+ None
1081+ }
1082+ }
1083+ }
1084+
1085+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1086+ let ( fes_min, fes_max) = self . iter . size_hint ( ) ;
1087+ // +1 because we set last_fe with call to `next`.
1088+ let min = Self :: padded_count ( fes_min + 1 ) ;
1089+ let max = fes_max. map ( |max| Self :: padded_count ( max) ) ;
1090+ ( min, max)
1091+ }
1092+ }
1093+
1094+ /// Trait to pad an Fe32 iterator
1095+ pub trait FesPaddable : Sized + Iterator < Item = Fe32 > {
1096+ /// Pad the iterator
1097+ fn pad_fes ( self ) -> FesPadder < Self > {
1098+ FesPadder :: new ( self )
1099+ }
1100+ }
1101+
1102+ impl < I > FesPaddable for I where I : Iterator < Item = Fe32 > { }
1103+
10011104#[ allow( missing_docs) ]
10021105impl RawBolt11Invoice {
10031106 /// Hash the HRP (as bytes) and signatureless data part (as Fe32 iterator)
@@ -1008,35 +1111,45 @@ impl RawBolt11Invoice {
10081111
10091112 /// Hash the HRP as bytes and signatureless data part.
10101113 fn hash_from_parts ( hrp_bytes : & [ u8 ] , data_without_signature : & [ Fe32 ] ) -> [ u8 ; 32 ] {
1011- use crate :: de :: FromBase32 ;
1114+ use crate :: bech32 :: Fe32IterExt ;
10121115
1116+ let data_part = Vec :: from ( data_without_signature) ;
10131117 let mut preimage = Vec :: < u8 > :: from ( hrp_bytes) ;
1118+ preimage. extend_from_slice (
1119+ & data_part
1120+ . iter ( )
1121+ . copied ( )
1122+ // fes_to_bytes() trims, input needs to be padded
1123+ . pad_fes ( )
1124+ . fes_to_bytes ( )
1125+ . collect :: < Vec < u8 > > ( )
1126+ ) ;
10141127
1015- let mut data_part = Vec :: from ( data_without_signature) ;
1016- let overhang = ( data_part. len ( ) * 5 ) % 8 ;
1017- if overhang > 0 {
1018- // add padding if data does not end at a byte boundary
1019- data_part. push ( Fe32 :: try_from ( 0 ) . unwrap ( ) ) ;
1128+ let mut hash: [ u8 ; 32 ] = Default :: default ( ) ;
1129+ hash. copy_from_slice ( & sha256:: Hash :: hash ( & preimage) [ ..] ) ;
1130+ hash
1131+ }
10201132
1021- // if overhang is in (1..3) we need to add Fe32(0) padding two times
1022- if overhang < 3 {
1023- data_part. push ( Fe32 :: try_from ( 0 ) . unwrap ( ) ) ;
1024- }
1025- }
1133+ /*
1134+ /// Hash the HRP as bytes and signatureless data part.
1135+ fn hash_from_parts_u8(hrp_bytes: &[u8], data_without_signature: &[u8]) -> [u8; 32] {
1136+ // use crate::de::FromBase32;
10261137
1027- preimage. extend_from_slice ( & Vec :: < u8 > :: from_base32 ( & data_part)
1028- . expect ( "No padding error may occur due to appended zero above." ) ) ;
1138+ let mut preimage = Vec::<u8>::from(hrp_bytes);
1139+ let data_part = Vec::from(data_without_signature);
1140+ preimage.extend(data_part);
10291141
10301142 let mut hash: [u8; 32] = Default::default();
10311143 hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
10321144 hash
10331145 }
1146+ */
10341147
10351148 /// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed.
10361149 pub fn signable_hash ( & self ) -> [ u8 ; 32 ] {
10371150 use crate :: ser:: Base32Iterable ;
10381151
1039- RawBolt11Invoice :: hash_from_parts_iter (
1152+ Self :: hash_from_parts_iter (
10401153 self . hrp . to_string ( ) . as_bytes ( ) ,
10411154 self . data . fe_iter ( ) ,
10421155 )
0 commit comments