diff --git a/src/key.rs b/src/key.rs index 8d6518590..de9fe4482 100644 --- a/src/key.rs +++ b/src/key.rs @@ -28,40 +28,7 @@ use ffi::{self, CPtr}; /// Secret 256-bit key used as `x` in an ECDSA signature pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]); -impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE); -impl_pretty_debug!(SecretKey); - -impl fmt::LowerHex for SecretKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for ch in &self.0[..] { - write!(f, "{:02x}", *ch)?; - } - Ok(()) - } -} - -impl fmt::Display for SecretKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl str::FromStr for SecretKey { - type Err = Error; - fn from_str(s: &str) -> Result { - let mut res = [0; constants::SECRET_KEY_SIZE]; - match from_hex(s, &mut res) { - Ok(constants::SECRET_KEY_SIZE) => Ok(SecretKey(res)), - _ => Err(Error::InvalidSecretKey) - } - } -} - -/// The number 1 encoded as a secret key -pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1]); +impl_seckey!(); /// A Secp256k1 public key, used for verification of signatures #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] @@ -108,113 +75,6 @@ fn random_32_bytes(rng: &mut R) -> [u8; 32] { ret } -impl SecretKey { - /// Creates a new random secret key. Requires compilation with the "rand" feature. - #[inline] - #[cfg(any(test, feature = "rand"))] - pub fn new(rng: &mut R) -> SecretKey { - let mut data = random_32_bytes(rng); - unsafe { - while ffi::secp256k1_ec_seckey_verify( - ffi::secp256k1_context_no_precomp, - data.as_c_ptr(), - ) == 0 - { - data = random_32_bytes(rng); - } - } - SecretKey(data) - } - - /// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key - #[inline] - pub fn from_slice(data: &[u8])-> Result { - match data.len() { - constants::SECRET_KEY_SIZE => { - let mut ret = [0; constants::SECRET_KEY_SIZE]; - unsafe { - if ffi::secp256k1_ec_seckey_verify( - ffi::secp256k1_context_no_precomp, - data.as_c_ptr(), - ) == 0 - { - return Err(InvalidSecretKey); - } - } - ret[..].copy_from_slice(data); - Ok(SecretKey(ret)) - } - _ => Err(InvalidSecretKey) - } - } - - #[inline] - /// Negates one secret key. - pub fn negate_assign( - &mut self - ) { - unsafe { - let res = ffi::secp256k1_ec_seckey_negate( - ffi::secp256k1_context_no_precomp, - self.as_mut_c_ptr() - ); - debug_assert_eq!(res, 1); - } - } - - #[inline] - /// Adds one secret key to another, modulo the curve order. WIll - /// return an error if the resulting key would be invalid or if - /// the tweak was not a 32-byte length slice. - pub fn add_assign( - &mut self, - other: &[u8], - ) -> Result<(), Error> { - if other.len() != 32 { - return Err(Error::InvalidTweak); - } - unsafe { - if ffi::secp256k1_ec_seckey_tweak_add( - ffi::secp256k1_context_no_precomp, - self.as_mut_c_ptr(), - other.as_c_ptr(), - ) != 1 - { - Err(Error::InvalidTweak) - } else { - Ok(()) - } - } - } - - #[inline] - /// Multiplies one secret key by another, modulo the curve order. Will - /// return an error if the resulting key would be invalid or if - /// the tweak was not a 32-byte length slice. - pub fn mul_assign( - &mut self, - other: &[u8], - ) -> Result<(), Error> { - if other.len() != 32 { - return Err(Error::InvalidTweak); - } - unsafe { - if ffi::secp256k1_ec_seckey_tweak_mul( - ffi::secp256k1_context_no_precomp, - self.as_mut_c_ptr(), - other.as_c_ptr(), - ) != 1 - { - Err(Error::InvalidTweak) - } else { - Ok(()) - } - } - } -} - -serde_impl!(SecretKey, constants::SECRET_KEY_SIZE); - impl PublicKey { /// Obtains a raw const pointer suitable for use with FFI functions #[inline] @@ -404,71 +264,7 @@ impl From for PublicKey { } } -#[cfg(feature = "serde")] -impl ::serde::Serialize for PublicKey { - fn serialize(&self, s: S) -> Result { - if s.is_human_readable() { - s.collect_str(self) - } else { - s.serialize_bytes(&self.serialize()) - } - } -} - -#[cfg(feature = "serde")] -impl<'de> ::serde::Deserialize<'de> for PublicKey { - fn deserialize>(d: D) -> Result { - if d.is_human_readable() { - struct HexVisitor; - - impl<'de> ::serde::de::Visitor<'de> for HexVisitor { - type Value = PublicKey; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("an ASCII hex string") - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: ::serde::de::Error, - { - if let Ok(hex) = str::from_utf8(v) { - str::FromStr::from_str(hex).map_err(E::custom) - } else { - Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self)) - } - } - - fn visit_str(self, v: &str) -> Result - where - E: ::serde::de::Error, - { - str::FromStr::from_str(v).map_err(E::custom) - } - } - d.deserialize_str(HexVisitor) - } else { - struct BytesVisitor; - - impl<'de> ::serde::de::Visitor<'de> for BytesVisitor { - type Value = PublicKey; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a bytestring") - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: ::serde::de::Error, - { - PublicKey::from_slice(v).map_err(E::custom) - } - } - - d.deserialize_bytes(BytesVisitor) - } - } -} +serde_impl_from_slice!(PublicKey); #[cfg(test)] mod test { diff --git a/src/macros.rs b/src/macros.rs index 9cf9ba6d3..4e5540fbd 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -87,3 +87,220 @@ macro_rules! serde_impl( macro_rules! serde_impl( ($t:ident, $len:expr) => () ); + +macro_rules! impl_seckey ( + () => { + impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE); + impl_pretty_debug!(SecretKey); + + impl fmt::LowerHex for SecretKey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for ch in &self.0[..] { + write!(f, "{:02x}", *ch)?; + } + Ok(()) + } + } + + impl fmt::Display for SecretKey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } + } + + impl str::FromStr for SecretKey { + type Err = Error; + fn from_str(s: &str) -> Result { + let mut res = [0; constants::SECRET_KEY_SIZE]; + match from_hex(s, &mut res) { + Ok(constants::SECRET_KEY_SIZE) => Ok(SecretKey(res)), + _ => Err(Error::InvalidSecretKey) + } + } + } + + /// The number 1 encoded as a secret key + pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1]); + + + impl SecretKey { + /// Creates a new random secret key. Requires compilation with the "rand" feature. + #[inline] + #[cfg(any(test, feature = "rand"))] + pub fn new(rng: &mut R) -> SecretKey { + let mut data = random_32_bytes(rng); + unsafe { + while ffi::secp256k1_ec_seckey_verify( + ffi::secp256k1_context_no_precomp, + data.as_c_ptr(), + ) == 0 + { + data = random_32_bytes(rng); + } + } + SecretKey(data) + } + /// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key + #[inline] + pub fn from_slice(data: &[u8])-> Result { + match data.len() { + constants::SECRET_KEY_SIZE => { + let mut ret = [0; constants::SECRET_KEY_SIZE]; + unsafe { + if ffi::secp256k1_ec_seckey_verify( + ffi::secp256k1_context_no_precomp, + data.as_c_ptr(), + ) == 0 + { + return Err(InvalidSecretKey); + } + } + ret[..].copy_from_slice(data); + Ok(SecretKey(ret)) + } + _ => Err(InvalidSecretKey) + } + } + #[inline] + /// Negates one secret key. + pub fn negate_assign( + &mut self + ) { + unsafe { + let res = ffi::secp256k1_ec_seckey_negate( + ffi::secp256k1_context_no_precomp, + self.as_mut_c_ptr() + ); + debug_assert_eq!(res, 1); + } + } + #[inline] + /// Adds one secret key to another, modulo the curve order. WIll + /// return an error if the resulting key would be invalid or if + /// the tweak was not a 32-byte length slice. + pub fn add_assign( + &mut self, + other: &[u8], + ) -> Result<(), Error> { + if other.len() != 32 { + return Err(Error::InvalidTweak); + } + unsafe { + if ffi::secp256k1_ec_seckey_tweak_add( + ffi::secp256k1_context_no_precomp, + self.as_mut_c_ptr(), + other.as_c_ptr(), + ) != 1 + { + Err(Error::InvalidTweak) + } else { + Ok(()) + } + } + } + #[inline] + /// Multiplies one secret key by another, modulo the curve order. Will + /// return an error if the resulting key would be invalid or if + /// the tweak was not a 32-byte length slice. + pub fn mul_assign( + &mut self, + other: &[u8], + ) -> Result<(), Error> { + if other.len() != 32 { + return Err(Error::InvalidTweak); + } + unsafe { + if ffi::secp256k1_ec_seckey_tweak_mul( + ffi::secp256k1_context_no_precomp, + self.as_mut_c_ptr(), + other.as_c_ptr(), + ) != 1 + { + Err(Error::InvalidTweak) + } else { + Ok(()) + } + } + } + } + + serde_impl!(SecretKey, constants::SECRET_KEY_SIZE); + }; +); + +#[cfg(feature = "serde")] +macro_rules! serde_impl_from_slice { + ($t: ident) => { + impl ::serde::Serialize for $t { + fn serialize(&self, s: S) -> Result { + if s.is_human_readable() { + s.collect_str(self) + } else { + s.serialize_bytes(&self.serialize()) + } + } + } + + impl<'de> ::serde::Deserialize<'de> for $t { + fn deserialize>(d: D) -> Result<$t, D::Error> { + if d.is_human_readable() { + struct HexVisitor; + + impl<'de> ::serde::de::Visitor<'de> for HexVisitor { + type Value = $t; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an ASCII hex string") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: ::serde::de::Error, + { + if let Ok(hex) = str::from_utf8(v) { + str::FromStr::from_str(hex).map_err(E::custom) + } else { + Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self)) + } + } + + fn visit_str(self, v: &str) -> Result + where + E: ::serde::de::Error, + { + str::FromStr::from_str(v).map_err(E::custom) + } + } + d.deserialize_str(HexVisitor) + } else { + struct BytesVisitor; + + impl<'de> ::serde::de::Visitor<'de> for BytesVisitor { + type Value = $t; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a bytestring") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: ::serde::de::Error, + { + $t::from_slice(v).map_err(E::custom) + } + } + + d.deserialize_bytes(BytesVisitor) + } + } + } + }; +} + +#[cfg(not(feature = "serde"))] +macro_rules! serde_impl_from_slice( + ($t:ident) => () +);