Skip to content

Commit 0e0d8df

Browse files
committed
Added a new struct for the DER serialized signature
1 parent 9427070 commit 0e0d8df

File tree

1 file changed

+79
-55
lines changed

1 file changed

+79
-55
lines changed

src/lib.rs

Lines changed: 79 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ pub mod key;
156156
pub use key::SecretKey;
157157
pub use key::PublicKey;
158158
use core::marker::PhantomData;
159+
use core::ops::Deref;
159160

160161
/// A tag used for recovering the public key from a compact signature
161162
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -165,6 +166,13 @@ pub struct RecoveryId(i32);
165166
#[derive(Copy, Clone, PartialEq, Eq)]
166167
pub struct Signature(ffi::Signature);
167168

169+
/// A DER serialized Signature
170+
#[derive(Copy, Clone)]
171+
pub struct SerSignature {
172+
data: [u8; 72],
173+
len: usize,
174+
}
175+
168176
impl fmt::Debug for Signature {
169177
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170178
fmt::Display::fmt(self, f)
@@ -231,6 +239,40 @@ pub fn to_i32(self) -> i32 {
231239
}
232240
}
233241

242+
impl SerSignature {
243+
/// Get a pointer to the underlying data with the specified capacity.
244+
pub fn get_data_mut_ptr(&mut self) -> *mut u8 {
245+
self.data.as_mut_ptr()
246+
}
247+
248+
/// Get the capacity of the underlying data buffer.
249+
pub fn capacity(&self) -> usize {
250+
self.data.len()
251+
}
252+
253+
/// Get the len of the used data.
254+
pub fn len(&self) -> usize {
255+
self.len
256+
}
257+
258+
/// Set the length of the object.
259+
pub(crate) fn set_len(&mut self, len: usize) {
260+
self.len = len;
261+
}
262+
263+
/// Convert the serialized signature into the Signature struct.
264+
/// (This basically DER deserialize it)
265+
pub fn to_signature(&self) -> Result<Signature, Error> {
266+
Signature::from_der(&self)
267+
}
268+
269+
/// Create a SerSignature from a Signature.
270+
/// (this basically DER serialize it)
271+
pub fn from_signature(sig: &Signature) -> SerSignature {
272+
sig.serialize_der()
273+
}
274+
}
275+
234276
impl Signature {
235277
#[inline]
236278
/// Converts a DER-encoded byte slice to a signature
@@ -335,44 +377,24 @@ impl Signature {
335377
&mut self.0 as *mut _
336378
}
337379

338-
#[cfg(feature = "std")]
339380
#[inline]
340381
/// Serializes the signature in DER format
341-
pub fn serialize_der(&self) -> Vec<u8>{
342-
let mut ret = Vec::with_capacity(72);
343-
let mut len: usize = ret.capacity() as usize;
382+
pub fn serialize_der(&self) -> SerSignature {
383+
let mut ret = SerSignature::default();
384+
let mut len: usize = ret.capacity();
344385
unsafe {
345386
let err = ffi::secp256k1_ecdsa_signature_serialize_der(
346387
ffi::secp256k1_context_no_precomp,
347-
ret.as_mut_ptr(),
388+
ret.get_data_mut_ptr(),
348389
&mut len,
349390
self.as_ptr(),
350391
);
351392
debug_assert!(err == 1);
352-
ret.set_len(len as usize);
393+
ret.set_len(len);
353394
}
354395
ret
355396
}
356397

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-
376398
#[inline]
377399
/// Serializes the signature in compact format
378400
pub fn serialize_compact(&self) -> [u8; 64] {
@@ -474,8 +496,7 @@ impl From<ffi::RecoverableSignature> for RecoverableSignature {
474496
#[cfg(feature = "serde")]
475497
impl ::serde::Serialize for Signature {
476498
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
477-
let mut buf = [0u8; 72];
478-
s.serialize_bytes(&self.serialize_der_no_alloc(&mut buf))
499+
s.serialize_bytes(&self.serialize_der())
479500
}
480501
}
481502

@@ -611,6 +632,37 @@ impl<C> PartialEq for Secp256k1<C> {
611632
fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
612633
}
613634

635+
impl Default for SerSignature {
636+
fn default() -> SerSignature {
637+
SerSignature {
638+
data: [0u8; 72],
639+
len: 0,
640+
}
641+
}
642+
}
643+
644+
impl PartialEq for SerSignature {
645+
fn eq(&self, other: &SerSignature) -> bool {
646+
&self.data[..] == &other.data[..] &&
647+
self.len == other.len
648+
}
649+
}
650+
651+
impl AsRef<[u8]> for SerSignature {
652+
fn as_ref(&self) -> &[u8] {
653+
&self.data[..self.len]
654+
}
655+
}
656+
657+
impl Deref for SerSignature {
658+
type Target = [u8];
659+
fn deref(&self) -> &[u8] {
660+
&self.data[..self.len]
661+
}
662+
}
663+
664+
impl Eq for SerSignature {}
665+
614666
impl<C> Eq for Secp256k1<C> { }
615667

616668
impl<C> Drop for Secp256k1<C> {
@@ -932,34 +984,6 @@ mod tests {
932984
}
933985
}
934986

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-
963987
#[test]
964988
fn signature_display() {
965989
let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";

0 commit comments

Comments
 (0)