diff --git a/src/lib.rs b/src/lib.rs index c65d168b3..c7b078113 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 SerSignature { + 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 SerSignature { + /// Get a pointer to the underlying data with the specified capacity. + pub 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 basically DER deserialize it) + pub fn to_signature(&self) -> Result { + Signature::from_der(&self) + } + + /// Create a SerSignature from a Signature. + /// (this basically DER serialize it) + pub fn from_signature(sig: &Signature) -> SerSignature { + 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) -> SerSignature { + let mut ret = SerSignature::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,37 @@ impl PartialEq for Secp256k1 { fn eq(&self, _other: &Secp256k1) -> bool { true } } +impl Default for SerSignature { + fn default() -> SerSignature { + SerSignature { + data: [0u8; 72], + len: 0, + } + } +} + +impl PartialEq for SerSignature { + fn eq(&self, other: &SerSignature) -> bool { + &self.data[..] == &other.data[..] && + self.len == other.len + } +} + +impl AsRef<[u8]> for SerSignature { + fn as_ref(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl Deref for SerSignature { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl Eq for SerSignature {} + impl Eq for Secp256k1 { } impl Drop for Secp256k1 {