From 7f2d3d24526886d40e50d926a51d21a5b81d6adb Mon Sep 17 00:00:00 2001 From: Martin Habovstiak Date: Tue, 21 Jun 2022 19:36:50 +0200 Subject: [PATCH] Move `SerializedSignature` into its own module This de-clutters the code and prepares for the next step of adding `IntoIterator`. The type is still re-exported so the change is neither breaking nor inconvenient. This also adds more datialed explanation of `SerializedSignature` and why it's needed. --- src/ecdsa/mod.rs | 105 ++-------------------------- src/ecdsa/serialized_signature.rs | 109 ++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 100 deletions(-) create mode 100644 src/ecdsa/serialized_signature.rs diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index 035e207..742457a 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -1,10 +1,12 @@ //! Structs and functionality related to the ECDSA signature algorithm. -use core::{fmt, str, ops, ptr}; +use core::{fmt, str, ptr}; use crate::{Signing, Verification, Message, PublicKey, Secp256k1, SecretKey, from_hex, Error, ffi}; use crate::ffi::CPtr; +pub mod serialized_signature; + #[cfg(feature = "recovery")] mod recovery; @@ -12,6 +14,8 @@ mod recovery; #[cfg_attr(docsrs, doc(cfg(feature = "recovery")))] pub use self::recovery::{RecoveryId, RecoverableSignature}; +pub use serialized_signature::SerializedSignature; + #[cfg(feature = "global-context")] use crate::SECP256K1; @@ -19,13 +23,6 @@ use crate::SECP256K1; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Signature(pub(crate) 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) @@ -39,21 +36,6 @@ impl fmt::Display for Signature { } } -impl fmt::Debug for SerializedSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -impl fmt::Display for SerializedSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for v in self.data.iter().take(self.len) { - write!(f, "{:02x}", v)?; - } - Ok(()) - } -} - impl str::FromStr for Signature { type Err = Error; fn from_str(s: &str) -> Result { @@ -65,83 +47,6 @@ impl str::FromStr for Signature { } } -impl Default for SerializedSignature { - fn default() -> SerializedSignature { - SerializedSignature { - data: [0u8; 72], - len: 0, - } - } -} - -impl PartialEq for SerializedSignature { - fn eq(&self, other: &SerializedSignature) -> bool { - **self == **other - } -} - -impl AsRef<[u8]> for SerializedSignature { - fn as_ref(&self) -> &[u8] { - &*self - } -} - -impl ops::Deref for SerializedSignature { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.data[..self.len] - } -} - -impl Eq for SerializedSignature {} - -impl<'a> IntoIterator for &'a SerializedSignature { - type IntoIter = core::slice::Iter<'a, u8>; - type Item = &'a u8; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -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() - } - - /// Check if the space is zero. - pub fn is_empty(&self) -> bool { self.len() == 0 } -} - impl Signature { #[inline] /// Converts a DER-encoded byte slice to a signature diff --git a/src/ecdsa/serialized_signature.rs b/src/ecdsa/serialized_signature.rs new file mode 100644 index 0000000..4fd0449 --- /dev/null +++ b/src/ecdsa/serialized_signature.rs @@ -0,0 +1,109 @@ +//! Implements [`SerializedSignature`] and related types. +//! +//! DER-serialized signatures have the issue that they can have different lengths. +//! We want to avoid using `Vec` since that would require allocations making the code slower and +//! unable to run on platforms without allocator. We implement a special type to encapsulate +//! serialized signatures and since it's a bit more complicated it has its own module. + +use core::{fmt, ops}; +use crate::Error; +use super::Signature; + +/// A DER serialized Signature +#[derive(Copy, Clone)] +pub struct SerializedSignature { + data: [u8; 72], + len: usize, +} + +impl fmt::Debug for SerializedSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Display for SerializedSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for v in self.data.iter().take(self.len) { + write!(f, "{:02x}", v)?; + } + Ok(()) + } +} + +impl Default for SerializedSignature { + fn default() -> SerializedSignature { + SerializedSignature { + data: [0u8; 72], + len: 0, + } + } +} + +impl PartialEq for SerializedSignature { + fn eq(&self, other: &SerializedSignature) -> bool { + **self == **other + } +} + +impl AsRef<[u8]> for SerializedSignature { + fn as_ref(&self) -> &[u8] { + &*self + } +} + +impl ops::Deref for SerializedSignature { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl Eq for SerializedSignature {} + +impl<'a> IntoIterator for &'a SerializedSignature { + type IntoIter = core::slice::Iter<'a, u8>; + type Item = &'a u8; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +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() + } + + /// Check if the space is zero. + pub fn is_empty(&self) -> bool { self.len() == 0 } +}