142
142
#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
143
143
#[ cfg( any( test, feature = "std" ) ) ] extern crate core;
144
144
145
- extern crate arrayvec;
146
-
147
- use arrayvec:: ArrayVec ;
148
145
use core:: { fmt, ptr, str} ;
149
146
150
147
#[ macro_use]
@@ -337,10 +334,11 @@ impl Signature {
337
334
& mut self . 0 as * mut _
338
335
}
339
336
337
+ #[ cfg( feature = "std" ) ]
340
338
#[ inline]
341
339
/// Serializes the signature in DER format
342
- pub fn serialize_der ( & self ) -> ArrayVec < [ u8 ; 72 ] > {
343
- let mut ret = ArrayVec :: < [ _ ; 72 ] > :: new ( ) ;
340
+ pub fn serialize_der ( & self ) -> Vec < u8 > {
341
+ let mut ret = Vec :: with_capacity ( 72 ) ;
344
342
let mut len: usize = ret. capacity ( ) as usize ;
345
343
unsafe {
346
344
let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
@@ -350,12 +348,30 @@ impl Signature {
350
348
self . as_ptr ( ) ,
351
349
) ;
352
350
debug_assert ! ( err == 1 ) ;
353
- // ret.set_len(len as usize);
354
351
ret. set_len ( len as usize ) ;
355
352
}
356
353
ret
357
354
}
358
355
356
+ #[ inline]
357
+ /// Serializes the signature in DER format without allocating memory
358
+ /// The signature can be anywhere from 8 bytes to 72 bytes
359
+ /// So the function needs a buffer that is equal or larger than 72 bytes
360
+ /// It will write into that buffer and return a slice containing only the signature
361
+ pub fn serialize_der_no_alloc < ' a > ( & self , buf : & ' a mut [ u8 ] ) -> & ' a [ u8 ] {
362
+ let mut len: usize = buf. len ( ) ;
363
+ unsafe {
364
+ let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
365
+ ffi:: secp256k1_context_no_precomp,
366
+ buf. as_mut_ptr ( ) ,
367
+ & mut len,
368
+ self . as_ptr ( ) ,
369
+ ) ;
370
+ debug_assert ! ( err == 1 ) ;
371
+ }
372
+ & buf[ ..len]
373
+ }
374
+
359
375
#[ inline]
360
376
/// Serializes the signature in compact format
361
377
pub fn serialize_compact ( & self ) -> [ u8 ; 64 ] {
@@ -900,6 +916,34 @@ mod tests {
900
916
}
901
917
}
902
918
919
+ #[ test]
920
+ fn signature_serialize_no_alloc_roundtrip ( ) {
921
+ let mut s = Secp256k1 :: new ( ) ;
922
+ s. randomize ( & mut thread_rng ( ) ) ;
923
+
924
+ let mut msg = [ 0 ; 32 ] ;
925
+ for _ in 0 ..100 {
926
+ thread_rng ( ) . fill_bytes ( & mut msg) ;
927
+ let msg = Message :: from_slice ( & msg) . unwrap ( ) ;
928
+
929
+ let ( sk, _) = s. generate_keypair ( & mut thread_rng ( ) ) ;
930
+ let sig1 = s. sign ( & msg, & sk) ;
931
+ let mut buf = vec ! [ 0u8 ; 72 ] ;
932
+ let der = sig1. serialize_der_no_alloc ( & mut buf) ;
933
+ let sig2 = Signature :: from_der ( & der[ ..] ) . unwrap ( ) ;
934
+ assert_eq ! ( sig1, sig2) ;
935
+
936
+ let compact = sig1. serialize_compact ( ) ;
937
+ let sig2 = Signature :: from_compact ( & compact[ ..] ) . unwrap ( ) ;
938
+ assert_eq ! ( sig1, sig2) ;
939
+
940
+ assert ! ( Signature :: from_compact( & der[ ..] ) . is_err( ) ) ;
941
+ assert ! ( Signature :: from_compact( & compact[ 0 ..4 ] ) . is_err( ) ) ;
942
+ assert ! ( Signature :: from_der( & compact[ ..] ) . is_err( ) ) ;
943
+ assert ! ( Signature :: from_der( & der[ 0 ..4 ] ) . is_err( ) ) ;
944
+ }
945
+ }
946
+
903
947
#[ test]
904
948
fn signature_display ( ) {
905
949
let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45" ;
0 commit comments