From dfcf74f9d01c2d796d219af94362d8c65dda229e Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Thu, 11 Apr 2019 21:47:20 +0300 Subject: [PATCH] Added a new struct for the DER serialized signature --- src/lib.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c65d168..1a25c9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -156,6 +156,7 @@ pub mod key; pub use key::SecretKey; pub use key::PublicKey; use core::marker::PhantomData; +use core::ops::Deref; /// A tag used for recovering the public key from a compact signature #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -165,6 +166,13 @@ pub struct RecoveryId(i32); #[derive(Copy, Clone, PartialEq, Eq)] pub struct Signature(ffi::Signature); +/// A DER serialized Signature +#[derive(Copy, Clone)] +pub struct SerializedSignature { + data: [u8; 72], + len: usize, +} + impl fmt::Debug for Signature { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) @@ -231,6 +239,40 @@ pub fn to_i32(self) -> i32 { } } +impl SerializedSignature { + /// Get a pointer to the underlying data with the specified capacity. + pub(crate) fn get_data_mut_ptr(&mut self) -> *mut u8 { + self.data.as_mut_ptr() + } + + /// Get the capacity of the underlying data buffer. + pub fn capacity(&self) -> usize { + self.data.len() + } + + /// Get the len of the used data. + pub fn len(&self) -> usize { + self.len + } + + /// Set the length of the object. + pub(crate) fn set_len(&mut self, len: usize) { + self.len = len; + } + + /// Convert the serialized signature into the Signature struct. + /// (This DER deserializes it) + pub fn to_signature(&self) -> Result { + Signature::from_der(&self) + } + + /// Create a SerializedSignature from a Signature. + /// (this DER serializes it) + pub fn from_signature(sig: &Signature) -> SerializedSignature { + sig.serialize_der() + } +} + impl Signature { #[inline] /// Converts a DER-encoded byte slice to a signature @@ -337,18 +379,18 @@ impl Signature { #[inline] /// Serializes the signature in DER format - pub fn serialize_der(&self) -> Vec { - let mut ret = Vec::with_capacity(72); - let mut len: usize = ret.capacity() as usize; + pub fn serialize_der(&self) -> SerializedSignature { + let mut ret = SerializedSignature::default(); + let mut len: usize = ret.capacity(); unsafe { let err = ffi::secp256k1_ecdsa_signature_serialize_der( ffi::secp256k1_context_no_precomp, - ret.as_mut_ptr(), + ret.get_data_mut_ptr(), &mut len, self.as_ptr(), ); debug_assert!(err == 1); - ret.set_len(len as usize); + ret.set_len(len); } ret } @@ -590,6 +632,36 @@ impl PartialEq for Secp256k1 { fn eq(&self, _other: &Secp256k1) -> bool { true } } +impl Default for SerializedSignature { + fn default() -> SerializedSignature { + SerializedSignature { + data: [0u8; 72], + len: 0, + } + } +} + +impl PartialEq for SerializedSignature { + fn eq(&self, other: &SerializedSignature) -> bool { + &self.data[..self.len] == &other.data[..other.len] + } +} + +impl AsRef<[u8]> for SerializedSignature { + fn as_ref(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl Deref for SerializedSignature { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl Eq for SerializedSignature {} + impl Eq for Secp256k1 { } impl Drop for Secp256k1 {