143143#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
144144#[ cfg( any( test, feature = "std" ) ) ] extern crate core;
145145
146- extern crate arrayvec;
147-
148- use arrayvec:: ArrayVec ;
149146use core:: { fmt, ptr, str} ;
150147
151148#[ macro_use]
@@ -338,10 +335,11 @@ impl Signature {
338335 & mut self . 0 as * mut _
339336 }
340337
338+ #[ cfg( feature = "std" ) ]
341339 #[ inline]
342340 /// Serializes the signature in DER format
343- pub fn serialize_der ( & self ) -> ArrayVec < [ u8 ; 72 ] > {
344- let mut ret = ArrayVec :: < [ _ ; 72 ] > :: new ( ) ;
341+ pub fn serialize_der ( & self ) -> Vec < u8 > {
342+ let mut ret = Vec :: with_capacity ( 72 ) ;
345343 let mut len: usize = ret. capacity ( ) as usize ;
346344 unsafe {
347345 let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
@@ -351,12 +349,30 @@ impl Signature {
351349 self . as_ptr ( ) ,
352350 ) ;
353351 debug_assert ! ( err == 1 ) ;
354- // ret.set_len(len as usize);
355352 ret. set_len ( len as usize ) ;
356353 }
357354 ret
358355 }
359356
357+ #[ inline]
358+ /// Serializes the signature in DER format without allocating memory
359+ /// The signature can be anywhere from 8 bytes to 72 bytes
360+ /// So the function needs a buffer that is equal or larger than 72 bytes
361+ /// It will write into that buffer and return a slice containing only the signature
362+ pub fn serialize_der_no_alloc < ' a > ( & self , buf : & ' a mut [ u8 ] ) -> & ' a [ u8 ] {
363+ let mut len: usize = buf. len ( ) ;
364+ unsafe {
365+ let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
366+ ffi:: secp256k1_context_no_precomp,
367+ buf. as_mut_ptr ( ) ,
368+ & mut len,
369+ self . as_ptr ( ) ,
370+ ) ;
371+ debug_assert ! ( err == 1 ) ;
372+ }
373+ & buf[ ..len]
374+ }
375+
360376 #[ inline]
361377 /// Serializes the signature in compact format
362378 pub fn serialize_compact ( & self ) -> [ u8 ; 64 ] {
@@ -458,7 +474,8 @@ impl From<ffi::RecoverableSignature> for RecoverableSignature {
458474#[ cfg( feature = "serde" ) ]
459475impl :: serde:: Serialize for Signature {
460476 fn serialize < S : :: serde:: Serializer > ( & self , s : S ) -> Result < S :: Ok , S :: Error > {
461- s. serialize_bytes ( & self . serialize_der ( ) )
477+ let mut buf = [ 0u8 ; 72 ] ;
478+ s. serialize_bytes ( & self . serialize_der_no_alloc ( & mut buf) )
462479 }
463480}
464481
@@ -915,6 +932,34 @@ mod tests {
915932 }
916933 }
917934
935+ #[ test]
936+ fn signature_serialize_no_alloc_roundtrip ( ) {
937+ let mut s = Secp256k1 :: new ( ) ;
938+ s. randomize ( & mut thread_rng ( ) ) ;
939+
940+ let mut msg = [ 0 ; 32 ] ;
941+ for _ in 0 ..100 {
942+ thread_rng ( ) . fill_bytes ( & mut msg) ;
943+ let msg = Message :: from_slice ( & msg) . unwrap ( ) ;
944+
945+ let ( sk, _) = s. generate_keypair ( & mut thread_rng ( ) ) ;
946+ let sig1 = s. sign ( & msg, & sk) ;
947+ let mut buf = vec ! [ 0u8 ; 172 ] ;
948+ let der = sig1. serialize_der_no_alloc ( & mut buf) ;
949+ let sig2 = Signature :: from_der ( & der[ ..] ) . unwrap ( ) ;
950+ assert_eq ! ( sig1, sig2) ;
951+
952+ let compact = sig1. serialize_compact ( ) ;
953+ let sig2 = Signature :: from_compact ( & compact[ ..] ) . unwrap ( ) ;
954+ assert_eq ! ( sig1, sig2) ;
955+
956+ assert ! ( Signature :: from_compact( & der[ ..] ) . is_err( ) ) ;
957+ assert ! ( Signature :: from_compact( & compact[ 0 ..4 ] ) . is_err( ) ) ;
958+ assert ! ( Signature :: from_der( & compact[ ..] ) . is_err( ) ) ;
959+ assert ! ( Signature :: from_der( & der[ 0 ..4 ] ) . is_err( ) ) ;
960+ }
961+ }
962+
918963 #[ test]
919964 fn signature_display ( ) {
920965 let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45" ;
0 commit comments