143
143
#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
144
144
#[ cfg( any( test, feature = "std" ) ) ] extern crate core;
145
145
146
- extern crate arrayvec;
147
-
148
- use arrayvec:: ArrayVec ;
149
146
use core:: { fmt, ptr, str} ;
150
147
151
148
#[ macro_use]
@@ -338,10 +335,11 @@ impl Signature {
338
335
& mut self . 0 as * mut _
339
336
}
340
337
338
+ #[ cfg( feature = "std" ) ]
341
339
#[ inline]
342
340
/// 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 ) ;
345
343
let mut len: usize = ret. capacity ( ) as usize ;
346
344
unsafe {
347
345
let err = ffi:: secp256k1_ecdsa_signature_serialize_der (
@@ -351,12 +349,30 @@ impl Signature {
351
349
self . as_ptr ( ) ,
352
350
) ;
353
351
debug_assert ! ( err == 1 ) ;
354
- // ret.set_len(len as usize);
355
352
ret. set_len ( len as usize ) ;
356
353
}
357
354
ret
358
355
}
359
356
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
+
360
376
#[ inline]
361
377
/// Serializes the signature in compact format
362
378
pub fn serialize_compact ( & self ) -> [ u8 ; 64 ] {
@@ -458,7 +474,8 @@ impl From<ffi::RecoverableSignature> for RecoverableSignature {
458
474
#[ cfg( feature = "serde" ) ]
459
475
impl :: serde:: Serialize for Signature {
460
476
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) )
462
479
}
463
480
}
464
481
@@ -915,6 +932,34 @@ mod tests {
915
932
}
916
933
}
917
934
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
+
918
963
#[ test]
919
964
fn signature_display ( ) {
920
965
let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45" ;
0 commit comments