142142#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
143143#[ cfg( any( test, feature = "std" ) ) ] extern crate core;
144144
145- extern crate arrayvec;
146-
147- use arrayvec:: ArrayVec ;
148145use core:: { fmt, ptr, str} ;
149146
150147#[ macro_use]
@@ -337,10 +334,11 @@ impl Signature {
337334 & mut self . 0 as * mut _
338335 }
339336
337+ #[ cfg( feature = "std" ) ]
340338 #[ inline]
341339 /// 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 ) ;
344342 let mut len: usize = ret. capacity ( ) as usize ;
345343 unsafe {
346344 let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
@@ -350,12 +348,30 @@ impl Signature {
350348 self . as_ptr ( ) ,
351349 ) ;
352350 debug_assert ! ( err == 1 ) ;
353- // ret.set_len(len as usize);
354351 ret. set_len ( len as usize ) ;
355352 }
356353 ret
357354 }
358355
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+
359375 #[ inline]
360376 /// Serializes the signature in compact format
361377 pub fn serialize_compact ( & self ) -> [ u8 ; 64 ] {
@@ -457,7 +473,8 @@ impl From<ffi::RecoverableSignature> for RecoverableSignature {
457473#[ cfg( feature = "serde" ) ]
458474impl :: serde:: Serialize for Signature {
459475 fn serialize < S : :: serde:: Serializer > ( & self , s : S ) -> Result < S :: Ok , S :: Error > {
460- s. serialize_bytes ( & self . serialize_der ( ) )
476+ let mut buf = [ 0u8 ; 72 ] ;
477+ s. serialize_bytes ( & self . serialize_der_no_alloc ( & mut buf) )
461478 }
462479}
463480
@@ -900,6 +917,34 @@ mod tests {
900917 }
901918 }
902919
920+ #[ test]
921+ fn signature_serialize_no_alloc_roundtrip ( ) {
922+ let mut s = Secp256k1 :: new ( ) ;
923+ s. randomize ( & mut thread_rng ( ) ) ;
924+
925+ let mut msg = [ 0 ; 32 ] ;
926+ for _ in 0 ..100 {
927+ thread_rng ( ) . fill_bytes ( & mut msg) ;
928+ let msg = Message :: from_slice ( & msg) . unwrap ( ) ;
929+
930+ let ( sk, _) = s. generate_keypair ( & mut thread_rng ( ) ) ;
931+ let sig1 = s. sign ( & msg, & sk) ;
932+ let mut buf = vec ! [ 0u8 ; 172 ] ;
933+ let der = sig1. serialize_der_no_alloc ( & mut buf) ;
934+ let sig2 = Signature :: from_der ( & der[ ..] ) . unwrap ( ) ;
935+ assert_eq ! ( sig1, sig2) ;
936+
937+ let compact = sig1. serialize_compact ( ) ;
938+ let sig2 = Signature :: from_compact ( & compact[ ..] ) . unwrap ( ) ;
939+ assert_eq ! ( sig1, sig2) ;
940+
941+ assert ! ( Signature :: from_compact( & der[ ..] ) . is_err( ) ) ;
942+ assert ! ( Signature :: from_compact( & compact[ 0 ..4 ] ) . is_err( ) ) ;
943+ assert ! ( Signature :: from_der( & compact[ ..] ) . is_err( ) ) ;
944+ assert ! ( Signature :: from_der( & der[ 0 ..4 ] ) . is_err( ) ) ;
945+ }
946+ }
947+
903948 #[ test]
904949 fn signature_display ( ) {
905950 let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45" ;
0 commit comments