@@ -528,6 +528,31 @@ pub enum Fallback {
528
528
#[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
529
529
pub struct Bolt11InvoiceSignature ( pub RecoverableSignature ) ;
530
530
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
+
531
556
impl PartialOrd for Bolt11InvoiceSignature {
532
557
fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
533
558
Some ( self . cmp ( other) )
@@ -998,6 +1023,84 @@ macro_rules! find_all_extract {
998
1023
} ;
999
1024
}
1000
1025
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
+
1001
1104
#[ allow( missing_docs) ]
1002
1105
impl RawBolt11Invoice {
1003
1106
/// Hash the HRP (as bytes) and signatureless data part (as Fe32 iterator)
@@ -1008,35 +1111,45 @@ impl RawBolt11Invoice {
1008
1111
1009
1112
/// Hash the HRP as bytes and signatureless data part.
1010
1113
fn hash_from_parts ( hrp_bytes : & [ u8 ] , data_without_signature : & [ Fe32 ] ) -> [ u8 ; 32 ] {
1011
- use crate :: de :: FromBase32 ;
1114
+ use crate :: bech32 :: Fe32IterExt ;
1012
1115
1116
+ let data_part = Vec :: from ( data_without_signature) ;
1013
1117
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
+ ) ;
1014
1127
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
+ }
1020
1132
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;
1026
1137
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);
1029
1141
1030
1142
let mut hash: [u8; 32] = Default::default();
1031
1143
hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
1032
1144
hash
1033
1145
}
1146
+ */
1034
1147
1035
1148
/// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed.
1036
1149
pub fn signable_hash ( & self ) -> [ u8 ; 32 ] {
1037
1150
use crate :: ser:: Base32Iterable ;
1038
1151
1039
- RawBolt11Invoice :: hash_from_parts_iter (
1152
+ Self :: hash_from_parts_iter (
1040
1153
self . hrp . to_string ( ) . as_bytes ( ) ,
1041
1154
self . data . fe_iter ( ) ,
1042
1155
)
0 commit comments