diff --git a/src/key.rs b/src/key.rs index 88415fa28..f28ef92bc 100644 --- a/src/key.rs +++ b/src/key.rs @@ -16,10 +16,12 @@ //! # Public and secret keys use core::{fmt, str}; +use core::convert::TryFrom; use crate::{constants, from_hex, schnorrsig, Secp256k1, Signing, Verification}; use crate::Error::{self, InvalidPublicKey, InvalidSecretKey}; use crate::ffi::{self, CPtr, impl_array_newtype}; +use crate::ffi::types::c_uint; /// Secret 256-bit key used as `x` in an ECDSA signature pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]); @@ -125,9 +127,8 @@ impl SecretKey { /// 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]; + match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) { + Ok(data) => { unsafe { if ffi::secp256k1_ec_seckey_verify( ffi::secp256k1_context_no_precomp, @@ -137,10 +138,9 @@ impl SecretKey { return Err(InvalidSecretKey); } } - ret[..].copy_from_slice(data); - Ok(SecretKey(ret)) + Ok(SecretKey(data)) } - _ => Err(InvalidSecretKey) + Err(_) => Err(InvalidSecretKey) } } @@ -321,39 +321,32 @@ impl PublicKey { /// it up to one bit. pub fn serialize(&self) -> [u8; constants::PUBLIC_KEY_SIZE] { let mut ret = [0; constants::PUBLIC_KEY_SIZE]; - - unsafe { - let mut ret_len = constants::PUBLIC_KEY_SIZE as usize; - let err = ffi::secp256k1_ec_pubkey_serialize( - ffi::secp256k1_context_no_precomp, - ret.as_mut_c_ptr(), - &mut ret_len, - self.as_c_ptr(), - ffi::SECP256K1_SER_COMPRESSED, - ); - debug_assert_eq!(err, 1); - debug_assert_eq!(ret_len, ret.len()); - } + self.serialize_internal(&mut ret, ffi::SECP256K1_SER_COMPRESSED); ret } + #[inline] /// Serialize the key as a byte-encoded pair of values, in uncompressed form pub fn serialize_uncompressed(&self) -> [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] { let mut ret = [0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; + self.serialize_internal(&mut ret, ffi::SECP256K1_SER_UNCOMPRESSED); + ret + } - unsafe { - let mut ret_len = constants::UNCOMPRESSED_PUBLIC_KEY_SIZE as usize; - let err = ffi::secp256k1_ec_pubkey_serialize( + #[inline(always)] + fn serialize_internal(&self, ret: &mut [u8], flag: c_uint) { + let mut ret_len = ret.len(); + let res = unsafe { + ffi::secp256k1_ec_pubkey_serialize( ffi::secp256k1_context_no_precomp, ret.as_mut_c_ptr(), &mut ret_len, self.as_c_ptr(), - ffi::SECP256K1_SER_UNCOMPRESSED, - ); - debug_assert_eq!(err, 1); - debug_assert_eq!(ret_len, ret.len()); - } - ret + flag, + ) + }; + debug_assert_eq!(res, 1); + debug_assert_eq!(ret_len, ret.len()); } #[inline] diff --git a/src/lib.rs b/src/lib.rs index 257d901c5..39e18684f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -241,7 +241,7 @@ impl SerializedSignature { /// Convert the serialized signature into the Signature struct. /// (This DER deserializes it) pub fn to_signature(&self) -> Result { - Signature::from_der(&self) + Signature::from_der(self) } /// Create a SerializedSignature from a Signature. @@ -746,7 +746,7 @@ impl Secp256k1 { /// Requires a signing capable context. pub fn sign_grind_r(&self, msg: &Message, sk: &key::SecretKey, bytes_to_grind: usize) -> Signature { let len_check = |s : &ffi::Signature| der_length_check(s, 71 - bytes_to_grind); - return self.sign_grind_with_check(msg, sk, len_check); + self.sign_grind_with_check(msg, sk, len_check) } /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce @@ -756,7 +756,7 @@ impl Secp256k1 { /// will perform two signing operations. /// Requires a signing capable context. pub fn sign_low_r(&self, msg: &Message, sk: &key::SecretKey) -> Signature { - return self.sign_grind_with_check(msg, sk, compact_sig_has_zero_first_bit) + self.sign_grind_with_check(msg, sk, compact_sig_has_zero_first_bit) } /// Generates a random keypair. Convenience function for `key::SecretKey::new` diff --git a/src/recovery.rs b/src/recovery.rs index 9a5458d7e..6c23bfc73 100644 --- a/src/recovery.rs +++ b/src/recovery.rs @@ -39,7 +39,7 @@ impl RecoveryId { /// Allows library users to create valid recovery IDs from i32. pub fn from_i32(id: i32) -> Result { match id { - 0 | 1 | 2 | 3 => Ok(RecoveryId(id)), + 0..=3 => Ok(RecoveryId(id)), _ => Err(Error::InvalidRecoveryId) } }