@@ -137,7 +137,6 @@ pub use secp256k1_sys as ffi;
137
137
#[ cfg( all( test, target_arch = "wasm32" ) ) ] extern crate wasm_bindgen_test;
138
138
#[ cfg( feature = "alloc" ) ] extern crate alloc;
139
139
140
- use core:: { fmt, ptr, str} ;
141
140
142
141
#[ macro_use]
143
142
mod macros;
@@ -156,7 +155,7 @@ pub use key::PublicKey;
156
155
pub use context:: * ;
157
156
use core:: marker:: PhantomData ;
158
157
use core:: ops:: Deref ;
159
- use core:: mem;
158
+ use core:: { mem, fmt , ptr , str } ;
160
159
use ffi:: { CPtr , types:: AlignedType } ;
161
160
162
161
#[ cfg( feature = "global-context-less-secure" ) ]
@@ -851,6 +850,28 @@ fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
851
850
Ok ( idx / 2 )
852
851
}
853
852
853
+ /// Utility function used to encode hex into a target u8 buffer. Returns
854
+ /// a reference to the target buffer as an str.
855
+ // it returns an error if the target buffer isn't big enough
856
+ #[ inline]
857
+ fn to_hex < ' a > ( src : & [ u8 ] , target : & ' a mut [ u8 ] ) -> Result < & ' a str , ( ) > {
858
+ let hex_len = src. len ( ) * 2 ;
859
+ if target. len ( ) < hex_len {
860
+ return Err ( ( ) ) ;
861
+ }
862
+ const HEX_TABLE : [ u8 ; 16 ] = * b"0123456789abcdef" ;
863
+
864
+ let mut i = 0 ;
865
+ for & b in src {
866
+ target[ i] = HEX_TABLE [ usize:: from ( b >> 4 ) ] ;
867
+ target[ i+1 ] = HEX_TABLE [ usize:: from ( b & 0b00001111 ) ] ;
868
+ i +=2 ;
869
+ }
870
+ let result = & target[ ..hex_len] ;
871
+ debug_assert ! ( str :: from_utf8( result) . is_ok( ) ) ;
872
+ return unsafe { Ok ( str:: from_utf8_unchecked ( result) ) } ;
873
+ }
874
+
854
875
855
876
#[ cfg( test) ]
856
877
mod tests {
@@ -859,7 +880,7 @@ mod tests {
859
880
use std:: marker:: PhantomData ;
860
881
861
882
use key:: { SecretKey , PublicKey } ;
862
- use super :: from_hex;
883
+ use super :: { from_hex, to_hex } ;
863
884
use super :: constants;
864
885
use super :: { Secp256k1 , Signature , Message } ;
865
886
use super :: Error :: { InvalidMessage , IncorrectSignature , InvalidSignature } ;
@@ -1186,6 +1207,32 @@ mod tests {
1186
1207
assert ! ( Message :: from_slice( & [ 1 ; constants:: MESSAGE_SIZE ] ) . is_ok( ) ) ;
1187
1208
}
1188
1209
1210
+ #[ test]
1211
+ fn test_hex ( ) {
1212
+ let mut rng = thread_rng ( ) ;
1213
+ const AMOUNT : usize = 1024 ;
1214
+ for i in 0 ..AMOUNT {
1215
+ // 255 isn't a valid utf8 character.
1216
+ let mut hex_buf = [ 255u8 ; AMOUNT * 2 ] ;
1217
+ let mut src_buf = [ 0u8 ; AMOUNT ] ;
1218
+ let mut result_buf = [ 0u8 ; AMOUNT ] ;
1219
+ let src = & mut src_buf[ 0 ..i] ;
1220
+ rng. fill_bytes ( src) ;
1221
+
1222
+ let hex = to_hex ( src, & mut hex_buf) . unwrap ( ) ;
1223
+ assert_eq ! ( from_hex( hex, & mut result_buf) . unwrap( ) , i) ;
1224
+ assert_eq ! ( src, & result_buf[ ..i] ) ;
1225
+ }
1226
+
1227
+
1228
+ assert ! ( to_hex( & [ 1 ; 2 ] , & mut [ 0u8 ; 3 ] ) . is_err( ) ) ;
1229
+ assert ! ( to_hex( & [ 1 ; 2 ] , & mut [ 0u8 ; 4 ] ) . is_ok( ) ) ;
1230
+ assert ! ( from_hex( "deadbeaf" , & mut [ 0u8 ; 3 ] ) . is_err( ) ) ;
1231
+ assert ! ( from_hex( "deadbeaf" , & mut [ 0u8 ; 4 ] ) . is_ok( ) ) ;
1232
+ assert ! ( from_hex( "a" , & mut [ 0u8 ; 4 ] ) . is_err( ) ) ;
1233
+ assert ! ( from_hex( "ag" , & mut [ 0u8 ; 4 ] ) . is_err( ) ) ;
1234
+ }
1235
+
1189
1236
#[ test]
1190
1237
#[ cfg( not( fuzzing) ) ] // fixed sig vectors can't work with fuzz-sigs
1191
1238
fn test_low_s ( ) {
0 commit comments