diff --git a/examples/sign_verify.rs b/examples/sign_verify.rs index 20dfde3..1ed13fa 100644 --- a/examples/sign_verify.rs +++ b/examples/sign_verify.rs @@ -2,9 +2,14 @@ extern crate bitcoin_hashes; extern crate secp256k1; use bitcoin_hashes::{sha256, Hash}; -use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, ecdsa, Signing, Verification}; +use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; -fn verify(secp: &Secp256k1, msg: &[u8], sig: [u8; 64], pubkey: [u8; 33]) -> Result { +fn verify( + secp: &Secp256k1, + msg: &[u8], + sig: [u8; 64], + pubkey: [u8; 33], +) -> Result { let msg = sha256::Hash::hash(msg); let msg = Message::from_slice(&msg)?; let sig = ecdsa::Signature::from_compact(&sig)?; @@ -13,7 +18,11 @@ fn verify(secp: &Secp256k1, msg: &[u8], sig: [u8; 64], pubke Ok(secp.verify_ecdsa(&msg, &sig, &pubkey).is_ok()) } -fn sign(secp: &Secp256k1, msg: &[u8], seckey: [u8; 32]) -> Result { +fn sign( + secp: &Secp256k1, + msg: &[u8], + seckey: [u8; 32], +) -> Result { let msg = sha256::Hash::hash(msg); let msg = Message::from_slice(&msg)?; let seckey = SecretKey::from_slice(&seckey)?; @@ -23,8 +32,14 @@ fn sign(secp: &Secp256k1, msg: &[u8], seckey: [u8; 32]) -> Result fn main() { let secp = Secp256k1::new(); - let seckey = [59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28]; - let pubkey = [2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54]; + let seckey = [ + 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, + 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, + ]; + let pubkey = [ + 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, + 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, + ]; let msg = b"This is some message"; let signature = sign(&secp, msg, seckey).unwrap(); diff --git a/examples/sign_verify_recovery.rs b/examples/sign_verify_recovery.rs index 627bbdc..9312ec2 100644 --- a/examples/sign_verify_recovery.rs +++ b/examples/sign_verify_recovery.rs @@ -1,11 +1,15 @@ - extern crate bitcoin_hashes; extern crate secp256k1; use bitcoin_hashes::{sha256, Hash}; -use secp256k1::{Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification, ecdsa}; +use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; -fn recover(secp: &Secp256k1,msg: &[u8],sig: [u8; 64],recovery_id: u8) -> Result { +fn recover( + secp: &Secp256k1, + msg: &[u8], + sig: [u8; 64], + recovery_id: u8, +) -> Result { let msg = sha256::Hash::hash(msg); let msg = Message::from_slice(&msg)?; let id = ecdsa::RecoveryId::from_i32(recovery_id as i32)?; @@ -14,7 +18,11 @@ fn recover(secp: &Secp256k1,msg: &[u8],sig: [u8; 64],recover secp.recover_ecdsa(&msg, &sig) } -fn sign_recovery(secp: &Secp256k1, msg: &[u8], seckey: [u8; 32]) -> Result { +fn sign_recovery( + secp: &Secp256k1, + msg: &[u8], + seckey: [u8; 32], +) -> Result { let msg = sha256::Hash::hash(msg); let msg = Message::from_slice(&msg)?; let seckey = SecretKey::from_slice(&seckey)?; @@ -25,22 +33,19 @@ fn main() { let secp = Secp256k1::new(); let seckey = [ - 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, - 94, 203, 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, + 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, + 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, ]; let pubkey = PublicKey::from_slice(&[ - 2, - 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, - 245, 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, - ]).unwrap(); + 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, + 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, + ]) + .unwrap(); let msg = b"This is some message"; let signature = sign_recovery(&secp, msg, seckey).unwrap(); let (recovery_id, serialize_sig) = signature.serialize_compact(); - assert_eq!( - recover(&secp, msg, serialize_sig, recovery_id.to_i32() as u8), - Ok(pubkey) - ); + assert_eq!(recover(&secp, msg, serialize_sig, recovery_id.to_i32() as u8), Ok(pubkey)); } diff --git a/src/context.rs b/src/context.rs index 6e6851d..889dea9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,13 +1,12 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; -use crate::{Error, Secp256k1}; -use crate::ffi::{self, CPtr, types::AlignedType}; -use crate::ffi::types::{c_uint, c_void}; - #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub use self::alloc_only::*; +use crate::ffi::types::{c_uint, c_void, AlignedType}; +use crate::ffi::{self, CPtr}; +use crate::{Error, Secp256k1}; #[cfg(all(feature = "global-context", feature = "std"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "global-context", feature = "std"))))] @@ -41,13 +40,17 @@ pub mod global { impl Deref for GlobalContext { type Target = Secp256k1; - #[allow(unused_mut)] // Unused when `rand-std` is not enabled. + #[allow(unused_mut)] // Unused when `rand-std` is not enabled. fn deref(&self) -> &Self::Target { static ONCE: Once = Once::new(); static mut CONTEXT: Option> = None; ONCE.call_once(|| unsafe { let mut ctx = Secp256k1::new(); - #[cfg(all(not(target_arch = "wasm32"), feature = "rand-std", not(feature = "global-context-less-secure")))] + #[cfg(all( + not(target_arch = "wasm32"), + feature = "rand-std", + not(feature = "global-context-less-secure") + ))] { ctx.randomize(&mut rand::thread_rng()); } @@ -58,10 +61,9 @@ pub mod global { } } - /// A trait for all kinds of contexts that lets you define the exact flags and a function to /// deallocate memory. It isn't possible to implement this for types outside this crate. -pub unsafe trait Context : private::Sealed { +pub unsafe trait Context: private::Sealed { /// Flags for the ffi. const FLAGS: c_uint; /// A constant description of the context. @@ -106,13 +108,13 @@ mod private { #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc"))))] mod alloc_only { - use crate::alloc::alloc; - use core::marker::PhantomData; use super::private; - use crate::ffi::{self, types::{c_uint, c_void}}; - use crate::{Secp256k1, Signing, Verification, Context, AlignedType}; + use crate::alloc::alloc; + use crate::ffi::types::{c_uint, c_void}; + use crate::ffi::{self}; + use crate::{AlignedType, Context, Secp256k1, Signing, Verification}; impl private::Sealed for SignOnly {} impl private::Sealed for All {} @@ -195,16 +197,22 @@ mod alloc_only { let size = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) }; let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); - let ptr = unsafe {alloc::alloc(layout)}; + let ptr = unsafe { alloc::alloc(layout) }; #[allow(unused_mut)] // ctx is not mutated under some feature combinations. let mut ctx = Secp256k1 { - ctx: unsafe { ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) }, + ctx: unsafe { + ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) + }, phantom: PhantomData, size, }; - #[cfg(all(not(target_arch = "wasm32"), feature = "rand-std", not(feature = "global-context-less-secure")))] + #[cfg(all( + not(target_arch = "wasm32"), + feature = "rand-std", + not(feature = "global-context-less-secure") + ))] { ctx.randomize(&mut rand::thread_rng()); } @@ -220,9 +228,7 @@ mod alloc_only { /// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`. /// If `rand-std` feature is not enabled please consider randomizing the context (see docs /// for `Secp256k1::gen_new()`). - pub fn new() -> Secp256k1 { - Secp256k1::gen_new() - } + pub fn new() -> Secp256k1 { Secp256k1::gen_new() } } impl Secp256k1 { @@ -231,9 +237,7 @@ mod alloc_only { /// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`. /// If `rand-std` feature is not enabled please consider randomizing the context (see docs /// for `Secp256k1::gen_new()`). - pub fn signing_only() -> Secp256k1 { - Secp256k1::gen_new() - } + pub fn signing_only() -> Secp256k1 { Secp256k1::gen_new() } } impl Secp256k1 { @@ -242,24 +246,22 @@ mod alloc_only { /// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`. /// If `rand-std` feature is not enabled please consider randomizing the context (see docs /// for `Secp256k1::gen_new()`). - pub fn verification_only() -> Secp256k1 { - Secp256k1::gen_new() - } + pub fn verification_only() -> Secp256k1 { Secp256k1::gen_new() } } impl Default for Secp256k1 { - fn default() -> Self { - Self::new() - } + fn default() -> Self { Self::new() } } impl Clone for Secp256k1 { fn clone(&self) -> Secp256k1 { - let size = unsafe {ffi::secp256k1_context_preallocated_clone_size(self.ctx as _)}; + let size = unsafe { ffi::secp256k1_context_preallocated_clone_size(self.ctx as _) }; let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); - let ptr = unsafe {alloc::alloc(layout)}; + let ptr = unsafe { alloc::alloc(layout) }; Secp256k1 { - ctx: unsafe { ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void) }, + ctx: unsafe { + ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void) + }, phantom: PhantomData, size, } @@ -313,7 +315,8 @@ impl<'buf, C: Context + 'buf> Secp256k1 { ctx: unsafe { ffi::secp256k1_context_preallocated_create( buf.as_mut_c_ptr() as *mut c_void, - C::FLAGS) + C::FLAGS, + ) }, phantom: PhantomData, size: 0, // We don't care about the size because it's the caller responsibility to deallocate. @@ -323,13 +326,13 @@ impl<'buf, C: Context + 'buf> Secp256k1 { impl<'buf> Secp256k1> { /// Creates a new Secp256k1 context with all capabilities - pub fn preallocated_new(buf: &'buf mut [AlignedType]) -> Result>, Error> { + pub fn preallocated_new( + buf: &'buf mut [AlignedType], + ) -> Result>, Error> { Secp256k1::preallocated_gen_new(buf) } /// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for a context. - pub fn preallocate_size() -> usize { - Self::preallocate_size_gen() - } + pub fn preallocate_size() -> usize { Self::preallocate_size_gen() } /// Create a context from a raw context. /// @@ -342,7 +345,9 @@ impl<'buf> Secp256k1> { /// * The user must handle the freeing of the context(using the correct functions) by himself. /// * Violating these may lead to Undefined Behavior. /// - pub unsafe fn from_raw_all(raw_ctx: *mut ffi::Context) -> ManuallyDrop>> { + pub unsafe fn from_raw_all( + raw_ctx: *mut ffi::Context, + ) -> ManuallyDrop>> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, @@ -353,15 +358,15 @@ impl<'buf> Secp256k1> { impl<'buf> Secp256k1> { /// Creates a new Secp256k1 context that can only be used for signing. - pub fn preallocated_signing_only(buf: &'buf mut [AlignedType]) -> Result>, Error> { + pub fn preallocated_signing_only( + buf: &'buf mut [AlignedType], + ) -> Result>, Error> { Secp256k1::preallocated_gen_new(buf) } /// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context. #[inline] - pub fn preallocate_signing_size() -> usize { - Self::preallocate_size_gen() - } + pub fn preallocate_signing_size() -> usize { Self::preallocate_size_gen() } /// Create a context from a raw context. /// @@ -374,7 +379,9 @@ impl<'buf> Secp256k1> { /// * The user must handle the freeing of the context(using the correct functions) by himself. /// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior. /// - pub unsafe fn from_raw_signing_only(raw_ctx: *mut ffi::Context) -> ManuallyDrop>> { + pub unsafe fn from_raw_signing_only( + raw_ctx: *mut ffi::Context, + ) -> ManuallyDrop>> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, @@ -385,15 +392,15 @@ impl<'buf> Secp256k1> { impl<'buf> Secp256k1> { /// Creates a new Secp256k1 context that can only be used for verification - pub fn preallocated_verification_only(buf: &'buf mut [AlignedType]) -> Result>, Error> { + pub fn preallocated_verification_only( + buf: &'buf mut [AlignedType], + ) -> Result>, Error> { Secp256k1::preallocated_gen_new(buf) } /// Uses the ffi `secp256k1_context_preallocated_size` to check the memory size needed for the context. #[inline] - pub fn preallocate_verification_size() -> usize { - Self::preallocate_size_gen() - } + pub fn preallocate_verification_size() -> usize { Self::preallocate_size_gen() } /// Create a context from a raw context. /// @@ -406,7 +413,9 @@ impl<'buf> Secp256k1> { /// * The user must handle the freeing of the context(using the correct functions) by himself. /// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior. /// - pub unsafe fn from_raw_verification_only(raw_ctx: *mut ffi::Context) -> ManuallyDrop>> { + pub unsafe fn from_raw_verification_only( + raw_ctx: *mut ffi::Context, + ) -> ManuallyDrop>> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, diff --git a/src/ecdh.rs b/src/ecdh.rs index a999b82..c93a5e6 100644 --- a/src/ecdh.rs +++ b/src/ecdh.rs @@ -15,11 +15,14 @@ //! Support for shared secret computations. //! -use core::{borrow::Borrow, ptr, str}; +use core::borrow::Borrow; +use core::{ptr, str}; use secp256k1_sys::types::{c_int, c_uchar, c_void}; -use crate::{constants, Error, ffi::{self, CPtr}, key::{PublicKey, SecretKey}}; +use crate::ffi::{self, CPtr}; +use crate::key::{PublicKey, SecretKey}; +use crate::{constants, Error}; // The logic for displaying shared secrets relies on this (see `secret.rs`). const SHARED_SECRET_SIZE: usize = constants::SECRET_KEY_SIZE; @@ -51,7 +54,7 @@ impl SharedSecret { pub fn new(point: &PublicKey, scalar: &SecretKey) -> SharedSecret { let mut buf = [0u8; SHARED_SECRET_SIZE]; let res = unsafe { - ffi::secp256k1_ecdh( + ffi::secp256k1_ecdh( ffi::secp256k1_context_no_precomp, buf.as_mut_ptr(), point.as_c_ptr(), @@ -66,15 +69,11 @@ impl SharedSecret { /// Returns the shared secret as a byte value. #[inline] - pub fn secret_bytes(&self) -> [u8; SHARED_SECRET_SIZE] { - self.0 - } + pub fn secret_bytes(&self) -> [u8; SHARED_SECRET_SIZE] { self.0 } /// Creates a shared secret from `bytes` array. #[inline] - pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { - SharedSecret(bytes) - } + pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { SharedSecret(bytes) } /// Creates a shared secret from `bytes` slice. #[inline] @@ -85,7 +84,7 @@ impl SharedSecret { ret[..].copy_from_slice(bytes); Ok(SharedSecret(ret)) } - _ => Err(Error::InvalidSharedSecret) + _ => Err(Error::InvalidSharedSecret), } } } @@ -96,21 +95,17 @@ impl str::FromStr for SharedSecret { let mut res = [0u8; SHARED_SECRET_SIZE]; match crate::from_hex(s, &mut res) { Ok(SHARED_SECRET_SIZE) => Ok(SharedSecret::from_bytes(res)), - _ => Err(Error::InvalidSharedSecret) + _ => Err(Error::InvalidSharedSecret), } } } impl Borrow<[u8]> for SharedSecret { - fn borrow(&self) -> &[u8] { - &self.0 - } + fn borrow(&self) -> &[u8] { &self.0 } } impl AsRef<[u8]> for SharedSecret { - fn as_ref(&self) -> &[u8] { - &self.0 - } + fn as_ref(&self) -> &[u8] { &self.0 } } /// Creates a shared point from public key and secret key. @@ -162,7 +157,12 @@ pub fn shared_secret_point(point: &PublicKey, scalar: &SecretKey) -> [u8; 64] { xy } -unsafe extern "C" fn c_callback(output: *mut c_uchar, x: *const c_uchar, y: *const c_uchar, _data: *mut c_void) -> c_int { +unsafe extern "C" fn c_callback( + output: *mut c_uchar, + x: *const c_uchar, + y: *const c_uchar, + _data: *mut c_void, +) -> c_int { ptr::copy_nonoverlapping(x, output, 32); ptr::copy_nonoverlapping(y, output.offset(32), 32); 1 @@ -187,12 +187,12 @@ impl<'de> ::serde::Deserialize<'de> for SharedSecret { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "a hex string representing 32 byte SharedSecret" + "a hex string representing 32 byte SharedSecret", )) } else { d.deserialize_bytes(super::serde_util::BytesVisitor::new( "raw 32 bytes SharedSecret", - SharedSecret::from_slice + SharedSecret::from_slice, )) } } @@ -205,11 +205,11 @@ mod tests { #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; - use crate::Secp256k1; use super::SharedSecret; + use crate::Secp256k1; #[test] - #[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))] + #[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))] fn ecdh() { let s = Secp256k1::signing_only(); let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); @@ -227,7 +227,9 @@ mod tests { let x = [5u8; 32]; let y = [7u8; 32]; let mut output = [0u8; 64]; - let res = unsafe { super::c_callback(output.as_mut_ptr(), x.as_ptr(), y.as_ptr(), core::ptr::null_mut()) }; + let res = unsafe { + super::c_callback(output.as_mut_ptr(), x.as_ptr(), y.as_ptr(), core::ptr::null_mut()) + }; assert_eq!(res, 1); let mut new_x = [0u8; 32]; let mut new_y = [0u8; 32]; @@ -239,9 +241,10 @@ mod tests { #[test] #[cfg(not(fuzzing))] - #[cfg(all(feature="std", feature = "rand-std", feature = "bitcoin-hashes-std"))] + #[cfg(all(feature = "std", feature = "rand-std", feature = "bitcoin-hashes-std"))] fn bitcoin_hashes_and_sys_generate_same_secret() { use bitcoin_hashes::{sha256, Hash, HashEngine}; + use crate::ecdh::shared_secret_point; let s = Secp256k1::signing_only(); @@ -265,7 +268,7 @@ mod tests { #[test] #[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))] fn serde() { - use serde_test::{Configure, Token, assert_tokens}; + use serde_test::{assert_tokens, Configure, Token}; #[rustfmt::skip] static BYTES: [u8; 32] = [ 1, 1, 1, 1, 1, 1, 1, 1, @@ -289,23 +292,20 @@ mod tests { #[cfg(bench)] mod benches { - use test::{Bencher, black_box}; - use rand::thread_rng; - - use crate::Secp256k1; + use test::{black_box, Bencher}; use super::SharedSecret; + use crate::Secp256k1; #[bench] pub fn bench_ecdh(bh: &mut Bencher) { let s = Secp256k1::signing_only(); let (sk, pk) = s.generate_keypair(&mut thread_rng()); - bh.iter( || { + bh.iter(|| { let res = SharedSecret::new(&pk, &sk); black_box(res); }); } } - diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index d8b3535..6e3256f 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -4,7 +4,7 @@ mod recovery; pub mod serialized_signature; -use core::{fmt, str, ptr}; +use core::{fmt, ptr, str}; #[cfg(feature = "recovery")] #[cfg_attr(docsrs, doc(cfg(feature = "recovery")))] @@ -22,9 +22,7 @@ use crate::{ pub struct Signature(pub(crate) ffi::Signature); impl fmt::Debug for Signature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) } } impl fmt::Display for Signature { @@ -49,7 +47,9 @@ impl Signature { #[inline] /// Converts a DER-encoded byte slice to a signature pub fn from_der(data: &[u8]) -> Result { - if data.is_empty() {return Err(Error::InvalidSignature);} + if data.is_empty() { + return Err(Error::InvalidSignature); + } unsafe { let mut ret = ffi::Signature::new(); @@ -70,7 +70,7 @@ impl Signature { /// Converts a 64-byte compact-encoded byte slice to a signature pub fn from_compact(data: &[u8]) -> Result { if data.len() != 64 { - return Err(Error::InvalidSignature) + return Err(Error::InvalidSignature); } unsafe { @@ -93,7 +93,9 @@ impl Signature { /// 2016. It should never be used in new applications. This library does not /// support serializing to this "format" pub fn from_der_lax(data: &[u8]) -> Result { - if data.is_empty() {return Err(Error::InvalidSignature);} + if data.is_empty() { + return Err(Error::InvalidSignature); + } unsafe { let mut ret = ffi::Signature::new(); @@ -143,16 +145,15 @@ impl Signature { /// Obtains a raw pointer suitable for use with FFI functions #[inline] #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")] - pub fn as_ptr(&self) -> *const ffi::Signature { - self.as_c_ptr() - } + pub fn as_ptr(&self) -> *const ffi::Signature { self.as_c_ptr() } /// Obtains a raw mutable pointer suitable for use with FFI functions #[inline] - #[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")] - pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature { - self.as_mut_c_ptr() - } + #[deprecated( + since = "0.25.0", + note = "Use Self::as_mut_c_ptr if you need to access the FFI layer" + )] + pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature { self.as_mut_c_ptr() } #[inline] /// Serializes the signature in DER format @@ -198,21 +199,15 @@ impl Signature { impl CPtr for Signature { type Target = ffi::Signature; - fn as_c_ptr(&self) -> *const Self::Target { - &self.0 - } + fn as_c_ptr(&self) -> *const Self::Target { &self.0 } - fn as_mut_c_ptr(&mut self) -> *mut Self::Target { - &mut self.0 - } + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 } } /// Creates a new signature from a FFI signature impl From for Signature { #[inline] - fn from(sig: ffi::Signature) -> Signature { - Signature(sig) - } + fn from(sig: ffi::Signature) -> Signature { Signature(sig) } } #[cfg(feature = "serde")] @@ -233,12 +228,12 @@ impl<'de> serde::Deserialize<'de> for Signature { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(crate::serde_util::FromStrVisitor::new( - "a hex string representing a DER encoded Signature" + "a hex string representing a DER encoded Signature", )) } else { d.deserialize_bytes(crate::serde_util::BytesVisitor::new( "raw byte stream, that represents a DER encoded Signature", - Signature::from_der + Signature::from_der, )) } } @@ -259,9 +254,17 @@ impl Secp256k1 { }; // We can assume the return value because it's not possible to construct // an invalid signature from a valid `Message` and `SecretKey` - assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_c_ptr(), - sk.as_c_ptr(), ffi::secp256k1_nonce_function_rfc6979, - noncedata_ptr), 1); + assert_eq!( + ffi::secp256k1_ecdsa_sign( + self.ctx, + &mut ret, + msg.as_c_ptr(), + sk.as_c_ptr(), + ffi::secp256k1_nonce_function_rfc6979, + noncedata_ptr + ), + 1 + ); Signature::from(ret) } } @@ -287,33 +290,43 @@ impl Secp256k1 { } fn sign_grind_with_check( - &self, msg: &Message, + &self, + msg: &Message, sk: &SecretKey, - check: impl Fn(&ffi::Signature) -> bool) -> Signature { - let mut entropy_p : *const ffi::types::c_void = ptr::null(); - let mut counter : u32 = 0; - let mut extra_entropy = [0u8; 32]; - loop { - unsafe { - let mut ret = ffi::Signature::new(); - // We can assume the return value because it's not possible to construct - // an invalid signature from a valid `Message` and `SecretKey` - assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_c_ptr(), - sk.as_c_ptr(), ffi::secp256k1_nonce_function_rfc6979, - entropy_p), 1); - if check(&ret) { - return Signature::from(ret); - } - - counter += 1; - extra_entropy[..4].copy_from_slice(&counter.to_le_bytes()); - entropy_p = extra_entropy.as_c_ptr().cast::(); - - // When fuzzing, these checks will usually spinloop forever, so just short-circuit them. - #[cfg(fuzzing)] + check: impl Fn(&ffi::Signature) -> bool, + ) -> Signature { + let mut entropy_p: *const ffi::types::c_void = ptr::null(); + let mut counter: u32 = 0; + let mut extra_entropy = [0u8; 32]; + loop { + unsafe { + let mut ret = ffi::Signature::new(); + // We can assume the return value because it's not possible to construct + // an invalid signature from a valid `Message` and `SecretKey` + assert_eq!( + ffi::secp256k1_ecdsa_sign( + self.ctx, + &mut ret, + msg.as_c_ptr(), + sk.as_c_ptr(), + ffi::secp256k1_nonce_function_rfc6979, + entropy_p + ), + 1 + ); + if check(&ret) { return Signature::from(ret); } + + counter += 1; + extra_entropy[..4].copy_from_slice(&counter.to_le_bytes()); + entropy_p = extra_entropy.as_c_ptr().cast::(); + + // When fuzzing, these checks will usually spinloop forever, so just short-circuit them. + #[cfg(fuzzing)] + return Signature::from(ret); } + } } /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce @@ -322,8 +335,13 @@ impl Secp256k1 { /// of signing operation performed by this function is exponential in the /// number of bytes grinded. /// Requires a signing capable context. - pub fn sign_ecdsa_grind_r(&self, msg: &Message, sk: &SecretKey, bytes_to_grind: usize) -> Signature { - let len_check = |s : &ffi::Signature| der_length_check(s, 71 - bytes_to_grind); + pub fn sign_ecdsa_grind_r( + &self, + msg: &Message, + sk: &SecretKey, + bytes_to_grind: usize, + ) -> Signature { + let len_check = |s: &ffi::Signature| der_length_check(s, 71 - bytes_to_grind); self.sign_grind_with_check(msg, sk, len_check) } @@ -362,9 +380,16 @@ impl Secp256k1 { /// # } /// ``` #[inline] - pub fn verify_ecdsa(&self, msg: &Message, sig: &Signature, pk: &PublicKey) -> Result<(), Error> { + pub fn verify_ecdsa( + &self, + msg: &Message, + sig: &Signature, + pk: &PublicKey, + ) -> Result<(), Error> { unsafe { - if ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_c_ptr(), msg.as_c_ptr(), pk.as_c_ptr()) == 0 { + if ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_c_ptr(), msg.as_c_ptr(), pk.as_c_ptr()) + == 0 + { Err(Error::IncorrectSignature) } else { Ok(()) diff --git a/src/ecdsa/recovery.rs b/src/ecdsa/recovery.rs index 23ede65..165d694 100644 --- a/src/ecdsa/recovery.rs +++ b/src/ecdsa/recovery.rs @@ -18,10 +18,12 @@ //! use core::ptr; -use crate::{key, Secp256k1, Message, Error, Verification, Signing, ecdsa::Signature}; -use super::ffi as super_ffi; + use self::super_ffi::CPtr; +use super::ffi as super_ffi; +use crate::ecdsa::Signature; use crate::ffi::recovery as ffi; +use crate::{key, Error, Message, Secp256k1, Signing, Verification}; /// A tag used for recovering the public key from a compact signature. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -32,20 +34,18 @@ pub struct RecoveryId(i32); pub struct RecoverableSignature(ffi::RecoverableSignature); impl RecoveryId { -#[inline] -/// Allows library users to create valid recovery IDs from i32. -pub fn from_i32(id: i32) -> Result { - match id { - 0..=3 => Ok(RecoveryId(id)), - _ => Err(Error::InvalidRecoveryId) + #[inline] + /// Allows library users to create valid recovery IDs from i32. + pub fn from_i32(id: i32) -> Result { + match id { + 0..=3 => Ok(RecoveryId(id)), + _ => Err(Error::InvalidRecoveryId), + } } -} -#[inline] -/// Allows library users to convert recovery IDs to i32. -pub fn to_i32(self) -> i32 { - self.0 -} + #[inline] + /// Allows library users to convert recovery IDs to i32. + pub fn to_i32(self) -> i32 { self.0 } } impl RecoverableSignature { @@ -53,7 +53,9 @@ impl RecoverableSignature { /// Converts a compact-encoded byte slice to a signature. This /// representation is nonstandard and defined by the libsecp256k1 library. pub fn from_compact(data: &[u8], recid: RecoveryId) -> Result { - if data.is_empty() {return Err(Error::InvalidSignature);} + if data.is_empty() { + return Err(Error::InvalidSignature); + } let mut ret = ffi::RecoverableSignature::new(); @@ -77,16 +79,15 @@ impl RecoverableSignature { /// Obtains a raw pointer suitable for use with FFI functions. #[inline] #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")] - pub fn as_ptr(&self) -> *const ffi::RecoverableSignature { - self.as_c_ptr() - } + pub fn as_ptr(&self) -> *const ffi::RecoverableSignature { self.as_c_ptr() } /// Obtains a raw mutable pointer suitable for use with FFI functions. #[inline] - #[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")] - pub fn as_mut_ptr(&mut self) -> *mut ffi::RecoverableSignature { - self.as_mut_c_ptr() - } + #[deprecated( + since = "0.25.0", + note = "Use Self::as_mut_c_ptr if you need to access the FFI layer" + )] + pub fn as_mut_ptr(&mut self) -> *mut ffi::RecoverableSignature { self.as_mut_c_ptr() } #[inline] /// Serializes the recoverable signature in compact format. @@ -131,24 +132,17 @@ impl RecoverableSignature { } } - impl CPtr for RecoverableSignature { type Target = ffi::RecoverableSignature; - fn as_c_ptr(&self) -> *const Self::Target { - &self.0 - } + fn as_c_ptr(&self) -> *const Self::Target { &self.0 } - fn as_mut_c_ptr(&mut self) -> *mut Self::Target { - &mut self.0 - } + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 } } /// Creates a new recoverable signature from a FFI one. impl From for RecoverableSignature { #[inline] - fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature { - RecoverableSignature(sig) - } + fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature { RecoverableSignature(sig) } } impl Secp256k1 { @@ -180,7 +174,11 @@ impl Secp256k1 { /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce /// Requires a signing-capable context. - pub fn sign_ecdsa_recoverable(&self, msg: &Message, sk: &key::SecretKey) -> RecoverableSignature { + pub fn sign_ecdsa_recoverable( + &self, + msg: &Message, + sk: &key::SecretKey, + ) -> RecoverableSignature { self.sign_ecdsa_recoverable_with_noncedata_pointer(msg, sk, ptr::null()) } @@ -203,13 +201,15 @@ impl Secp256k1 { impl Secp256k1 { /// Determines the public key for which `sig` is a valid signature for /// `msg`. Requires a verify-capable context. - pub fn recover_ecdsa(&self, msg: &Message, sig: &RecoverableSignature) - -> Result { - + pub fn recover_ecdsa( + &self, + msg: &Message, + sig: &RecoverableSignature, + ) -> Result { unsafe { let mut pk = super_ffi::PublicKey::new(); - if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk, - sig.as_c_ptr(), msg.as_c_ptr()) != 1 { + if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk, sig.as_c_ptr(), msg.as_c_ptr()) != 1 + { return Err(Error::InvalidSignature); } Ok(key::PublicKey::from(pk)) @@ -217,21 +217,19 @@ impl Secp256k1 { } } - #[cfg(test)] #[allow(unused_imports)] mod tests { - use rand::{RngCore, thread_rng}; - - use crate::{Error, SecretKey, Secp256k1, Message}; - use crate::constants::ONE; - use super::{RecoveryId, RecoverableSignature}; - + use rand::{thread_rng, RngCore}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; + use super::{RecoverableSignature, RecoveryId}; + use crate::constants::ONE; + use crate::{Error, Message, Secp256k1, SecretKey}; + #[test] - #[cfg(all(feature="std", feature = "rand-std"))] + #[cfg(all(feature = "std", feature = "rand-std"))] fn capabilities() { let sign = Secp256k1::signing_only(); let vrfy = Secp256k1::verification_only(); @@ -252,8 +250,7 @@ mod tests { assert!(vrfy.recover_ecdsa(&msg, &sigr).is_ok()); assert!(full.recover_ecdsa(&msg, &sigr).is_ok()); - assert_eq!(vrfy.recover_ecdsa(&msg, &sigr), - full.recover_ecdsa(&msg, &sigr)); + assert_eq!(vrfy.recover_ecdsa(&msg, &sigr), full.recover_ecdsa(&msg, &sigr)); assert_eq!(full.recover_ecdsa(&msg, &sigr), Ok(pk)); } @@ -315,7 +312,7 @@ mod tests { } #[test] - #[cfg(all(feature="std", feature = "rand-std"))] + #[cfg(all(feature = "std", feature = "rand-std"))] fn sign_and_verify_fail() { let mut s = Secp256k1::new(); s.randomize(&mut thread_rng()); @@ -339,7 +336,7 @@ mod tests { } #[test] - #[cfg(all(feature="std", feature = "rand-std"))] + #[cfg(all(feature = "std", feature = "rand-std"))] fn sign_with_recovery() { let mut s = Secp256k1::new(); s.randomize(&mut thread_rng()); @@ -356,7 +353,7 @@ mod tests { } #[test] - #[cfg(all(feature="std", feature = "rand-std"))] + #[cfg(all(feature = "std", feature = "rand-std"))] fn sign_with_recovery_and_noncedata() { let mut s = Secp256k1::new(); s.randomize(&mut thread_rng()); @@ -375,7 +372,7 @@ mod tests { } #[test] - #[cfg(all(feature="std", feature = "rand-std"))] + #[cfg(all(feature = "std", feature = "rand-std"))] fn bad_recovery() { let mut s = Secp256k1::new(); s.randomize(&mut thread_rng()); @@ -419,10 +416,7 @@ mod tests { 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f, 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06, 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89]; - let sig = RecoverableSignature::from_compact( - bytes_in, - recid_in, - ).unwrap(); + let sig = RecoverableSignature::from_compact(bytes_in, recid_in).unwrap(); let (recid_out, bytes_out) = sig.serialize_compact(); assert_eq!(recid_in, recid_out); assert_eq!(&bytes_in[..], &bytes_out[..]); @@ -446,7 +440,8 @@ mod tests { #[cfg(bench)] mod benches { use rand::{thread_rng, RngCore}; - use test::{Bencher, black_box}; + use test::{black_box, Bencher}; + use super::{Message, Secp256k1}; #[bench] diff --git a/src/ecdsa/serialized_signature.rs b/src/ecdsa/serialized_signature.rs index 79ef92d..ab1f9e4 100644 --- a/src/ecdsa/serialized_signature.rs +++ b/src/ecdsa/serialized_signature.rs @@ -5,11 +5,12 @@ //! 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}; + pub use into_iter::IntoIter; -use core::{fmt, ops}; -use crate::Error; use super::Signature; +use crate::Error; pub(crate) const MAX_LEN: usize = 72; @@ -21,9 +22,7 @@ pub struct SerializedSignature { } impl fmt::Debug for SerializedSignature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) } } impl fmt::Display for SerializedSignature { @@ -37,25 +36,19 @@ impl fmt::Display for SerializedSignature { impl PartialEq for SerializedSignature { #[inline] - fn eq(&self, other: &SerializedSignature) -> bool { - **self == **other - } + fn eq(&self, other: &SerializedSignature) -> bool { **self == **other } } impl AsRef<[u8]> for SerializedSignature { #[inline] - fn as_ref(&self) -> &[u8] { - self - } + fn as_ref(&self) -> &[u8] { self } } impl ops::Deref for SerializedSignature { type Target = [u8]; #[inline] - fn deref(&self) -> &[u8] { - &self.data[..self.len] - } + fn deref(&self) -> &[u8] { &self.data[..self.len] } } impl Eq for SerializedSignature {} @@ -65,9 +58,7 @@ impl IntoIterator for SerializedSignature { type Item = u8; #[inline] - fn into_iter(self) -> Self::IntoIter { - IntoIter::new(self) - } + fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) } } impl<'a> IntoIterator for &'a SerializedSignature { @@ -75,9 +66,7 @@ impl<'a> IntoIterator for &'a SerializedSignature { type Item = &'a u8; #[inline] - fn into_iter(self) -> Self::IntoIter { - self.iter() - } + fn into_iter(self) -> Self::IntoIter { self.iter() } } impl SerializedSignature { @@ -89,43 +78,30 @@ impl SerializedSignature { #[inline] pub(crate) fn from_raw_parts(data: [u8; MAX_LEN], len: usize) -> Self { assert!(len <= MAX_LEN, "attempt to set length to {} but the maximum is {}", len, MAX_LEN); - SerializedSignature { - data, - len, - } + SerializedSignature { data, len } } /// Get the capacity of the underlying data buffer. #[inline] - pub fn capacity(&self) -> usize { - self.data.len() - } + pub fn capacity(&self) -> usize { self.data.len() } /// Get the len of the used data. #[inline] - pub fn len(&self) -> usize { - self.len - } + pub fn len(&self) -> usize { self.len } /// Set the length of the object. #[inline] - pub(crate) fn set_len_unchecked(&mut self, len: usize) { - self.len = len; - } + pub(crate) fn set_len_unchecked(&mut self, len: usize) { self.len = len; } /// Convert the serialized signature into the Signature struct. /// (This DER deserializes it) #[inline] - pub fn to_signature(&self) -> Result { - Signature::from_der(self) - } + pub fn to_signature(&self) -> Result { Signature::from_der(self) } /// Create a SerializedSignature from a Signature. /// (this DER serializes it) #[inline] - pub fn from_signature(sig: &Signature) -> SerializedSignature { - sig.serialize_der() - } + pub fn from_signature(sig: &Signature) -> SerializedSignature { sig.serialize_der() } /// Check if the space is zero. #[inline] @@ -162,9 +138,7 @@ mod into_iter { /// /// This method is analogous to [`core::slice::Iter::as_slice`]. #[inline] - pub fn as_slice(&self) -> &[u8] { - &self.signature[self.pos..] - } + pub fn as_slice(&self) -> &[u8] { &self.signature[self.pos..] } } impl Iterator for IntoIter { diff --git a/src/key.rs b/src/key.rs index 1c30ff3..a0e2db9 100644 --- a/src/key.rs +++ b/src/key.rs @@ -16,26 +16,23 @@ //! Public and secret keys. //! -use core::{fmt, ptr, str}; -use core::ops::BitXor; use core::convert::TryFrom; - -use crate::{constants, from_hex, Secp256k1, Signing, Verification}; -use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey}; -use crate::ffi::{self, CPtr, impl_array_newtype}; -use crate::ffi::types::c_uint; - -#[cfg(feature = "bitcoin-hashes")] -use crate::{hashes, ThirtyTwoByteHash}; +use core::ops::BitXor; +use core::{fmt, ptr, str}; #[cfg(feature = "serde")] use serde::ser::SerializeTuple; -#[cfg(feature = "global-context")] -use crate::{Message, ecdsa, SECP256K1}; -#[cfg(all(feature = "global-context", feature = "rand-std"))] +use crate::ffi::types::c_uint; +use crate::ffi::{self, impl_array_newtype, CPtr}; +#[cfg(all(feature = "global-context", feature = "rand-std"))] use crate::schnorr; -use crate::Scalar; +use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey}; +use crate::{constants, from_hex, Scalar, Secp256k1, Signing, Verification}; +#[cfg(feature = "global-context")] +use crate::{ecdsa, Message, SECP256K1}; +#[cfg(feature = "bitcoin-hashes")] +use crate::{hashes, ThirtyTwoByteHash}; /// Secret 256-bit key used as `x` in an ECDSA signature. /// @@ -69,7 +66,7 @@ impl str::FromStr for SecretKey { let mut res = [0u8; constants::SECRET_KEY_SIZE]; match from_hex(s, &mut res) { Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_slice(&res), - _ => Err(Error::InvalidSecretKey) + _ => Err(Error::InvalidSecretKey), } } } @@ -116,9 +113,7 @@ impl fmt::LowerHex for PublicKey { } impl fmt::Display for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl str::FromStr for PublicKey { @@ -126,15 +121,10 @@ impl str::FromStr for PublicKey { fn from_str(s: &str) -> Result { let mut res = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; match from_hex(s, &mut res) { - Ok(constants::PUBLIC_KEY_SIZE) => { - PublicKey::from_slice( - &res[0..constants::PUBLIC_KEY_SIZE] - ) - } - Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) => { - PublicKey::from_slice(&res) - } - _ => Err(Error::InvalidPublicKey) + Ok(constants::PUBLIC_KEY_SIZE) => + PublicKey::from_slice(&res[0..constants::PUBLIC_KEY_SIZE]), + Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) => PublicKey::from_slice(&res), + _ => Err(Error::InvalidPublicKey), } } } @@ -183,7 +173,7 @@ impl SecretKey { /// let sk = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order"); /// ``` #[inline] - pub fn from_slice(data: &[u8])-> Result { + pub fn from_slice(data: &[u8]) -> Result { match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) { Ok(data) => { unsafe { @@ -197,7 +187,7 @@ impl SecretKey { } Ok(SecretKey(data)) } - Err(_) => Err(InvalidSecretKey) + Err(_) => Err(InvalidSecretKey), } } @@ -221,7 +211,7 @@ impl SecretKey { let ret = ffi::secp256k1_keypair_sec( ffi::secp256k1_context_no_precomp, sk.as_mut_c_ptr(), - keypair.as_c_ptr() + keypair.as_c_ptr(), ); debug_assert_eq!(ret, 1); } @@ -255,9 +245,7 @@ impl SecretKey { /// Returns the secret key as a byte value. #[inline] - pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] { - self.0 - } + pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] { self.0 } /// Negates the secret key. #[inline] @@ -266,7 +254,7 @@ impl SecretKey { unsafe { let res = ffi::secp256k1_ec_seckey_negate( ffi::secp256k1_context_no_precomp, - self.as_mut_c_ptr() + self.as_mut_c_ptr(), ); debug_assert_eq!(res, 1); } @@ -319,9 +307,7 @@ impl SecretKey { #[inline] #[cfg(feature = "global-context")] #[cfg_attr(docsrs, doc(cfg(feature = "global-context")))] - pub fn sign_ecdsa(&self, msg: Message) -> ecdsa::Signature { - SECP256K1.sign_ecdsa(&msg, self) - } + pub fn sign_ecdsa(&self, msg: Message) -> ecdsa::Signature { SECP256K1.sign_ecdsa(&msg, self) } /// Returns the [`KeyPair`] for this [`SecretKey`]. /// @@ -380,12 +366,12 @@ impl<'de> serde::Deserialize<'de> for SecretKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "a hex string representing 32 byte SecretKey" + "a hex string representing 32 byte SecretKey", )) } else { let visitor = super::serde_util::Tuple32Visitor::new( "raw 32 bytes SecretKey", - SecretKey::from_slice + SecretKey::from_slice, ); d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor) } @@ -396,16 +382,15 @@ impl PublicKey { /// Obtains a raw const pointer suitable for use with FFI functions. #[inline] #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")] - pub fn as_ptr(&self) -> *const ffi::PublicKey { - self.as_c_ptr() - } + pub fn as_ptr(&self) -> *const ffi::PublicKey { self.as_c_ptr() } /// Obtains a raw mutable pointer suitable for use with FFI functions. #[inline] - #[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")] - pub fn as_mut_ptr(&mut self) -> *mut ffi::PublicKey { - self.as_mut_c_ptr() - } + #[deprecated( + since = "0.25.0", + note = "Use Self::as_mut_c_ptr if you need to access the FFI layer" + )] + pub fn as_mut_ptr(&mut self) -> *mut ffi::PublicKey { self.as_mut_c_ptr() } /// Creates a new public key from a [`SecretKey`]. /// @@ -421,7 +406,7 @@ impl PublicKey { /// # } /// ``` #[inline] - pub fn from_secret_key(secp: &Secp256k1,sk: &SecretKey) -> PublicKey { + pub fn from_secret_key(secp: &Secp256k1, sk: &SecretKey) -> PublicKey { unsafe { let mut pk = ffi::PublicKey::new(); // We can assume the return value because it's not possible to construct @@ -443,7 +428,9 @@ impl PublicKey { /// Creates a public key directly from a slice. #[inline] pub fn from_slice(data: &[u8]) -> Result { - if data.is_empty() {return Err(Error::InvalidPublicKey);} + if data.is_empty() { + return Err(Error::InvalidPublicKey); + } unsafe { let mut pk = ffi::PublicKey::new(); @@ -481,7 +468,7 @@ impl PublicKey { let ret = ffi::secp256k1_keypair_pub( ffi::secp256k1_context_no_precomp, &mut pk, - keypair.as_c_ptr() + keypair.as_c_ptr(), ); debug_assert_eq!(ret, 1); PublicKey(pk) @@ -555,7 +542,7 @@ impl PublicKey { pub fn add_exp_tweak( mut self, secp: &Secp256k1, - tweak: &Scalar + tweak: &Scalar, ) -> Result { unsafe { if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, &mut self.0, tweak.as_c_ptr()) == 1 { @@ -633,8 +620,8 @@ impl PublicKey { /// # } /// ``` pub fn combine_keys(keys: &[&PublicKey]) -> Result { - use core::mem::transmute; use core::i32::MAX; + use core::mem::transmute; if keys.is_empty() || keys.len() > MAX as usize { return Err(InvalidPublicKeySum); @@ -642,13 +629,13 @@ impl PublicKey { unsafe { let mut ret = ffi::PublicKey::new(); - let ptrs : &[*const ffi::PublicKey] = + let ptrs: &[*const ffi::PublicKey] = transmute::<&[&PublicKey], &[*const ffi::PublicKey]>(keys); if ffi::secp256k1_ec_pubkey_combine( ffi::secp256k1_context_no_precomp, &mut ret, ptrs.as_c_ptr(), - keys.len() as i32 + keys.len() as i32, ) == 1 { Ok(PublicKey(ret)) @@ -671,7 +658,8 @@ impl PublicKey { self.as_c_ptr(), ); debug_assert_eq!(ret, 1); - let parity = Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1"); + let parity = + Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1"); (XOnlyPublicKey(xonly_pk), parity) } @@ -684,25 +672,18 @@ impl CPtr for PublicKey { type Target = ffi::PublicKey; /// Obtains a const pointer suitable for use with FFI functions. - fn as_c_ptr(&self) -> *const Self::Target { - &self.0 - } + fn as_c_ptr(&self) -> *const Self::Target { &self.0 } /// Obtains a mutable pointer suitable for use with FFI functions. - fn as_mut_c_ptr(&mut self) -> *mut Self::Target { - &mut self.0 - } + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 } } - /// Creates a new public key from a FFI public key. /// /// Note, normal users should never need to interact directly with FFI types. impl From for PublicKey { #[inline] - fn from(pk: ffi::PublicKey) -> PublicKey { - PublicKey(pk) - } + fn from(pk: ffi::PublicKey) -> PublicKey { PublicKey(pk) } } #[cfg(feature = "serde")] @@ -728,12 +709,12 @@ impl<'de> serde::Deserialize<'de> for PublicKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "an ASCII hex string representing a public key" + "an ASCII hex string representing a public key", )) } else { let visitor = super::serde_util::Tuple33Visitor::new( "33 bytes compressed public key", - PublicKey::from_slice + PublicKey::from_slice, ); d.deserialize_tuple(constants::PUBLIC_KEY_SIZE, visitor) } @@ -751,7 +732,11 @@ impl PartialOrd for PublicKey { impl Ord for PublicKey { fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering { let ret = unsafe { - ffi::secp256k1_ec_pubkey_cmp(ffi::secp256k1_context_no_precomp, self.as_c_ptr(), other.as_c_ptr()) + ffi::secp256k1_ec_pubkey_cmp( + ffi::secp256k1_context_no_precomp, + self.as_c_ptr(), + other.as_c_ptr(), + ) }; ret.cmp(&0i32) } @@ -759,9 +744,7 @@ impl Ord for PublicKey { #[cfg(not(fuzzing))] impl PartialEq for PublicKey { - fn eq(&self, other: &Self) -> bool { - self.cmp(other) == core::cmp::Ordering::Equal - } + fn eq(&self, other: &Self) -> bool { self.cmp(other) == core::cmp::Ordering::Equal } } #[cfg(not(fuzzing))] @@ -807,23 +790,19 @@ impl KeyPair { /// Obtains a raw const pointer suitable for use with FFI functions. #[inline] #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")] - pub fn as_ptr(&self) -> *const ffi::KeyPair { - self.as_c_ptr() - } + pub fn as_ptr(&self) -> *const ffi::KeyPair { self.as_c_ptr() } /// Obtains a raw mutable pointer suitable for use with FFI functions. #[inline] - #[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")] - pub fn as_mut_ptr(&mut self) -> *mut ffi::KeyPair { - self.as_mut_c_ptr() - } + #[deprecated( + since = "0.25.0", + note = "Use Self::as_mut_c_ptr if you need to access the FFI layer" + )] + pub fn as_mut_ptr(&mut self) -> *mut ffi::KeyPair { self.as_mut_c_ptr() } /// Creates a [`KeyPair`] directly from a Secp256k1 secret key. #[inline] - pub fn from_secret_key( - secp: &Secp256k1, - sk: &SecretKey, - ) -> KeyPair { + pub fn from_secret_key(secp: &Secp256k1, sk: &SecretKey) -> KeyPair { unsafe { let mut kp = ffi::KeyPair::new(); if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, sk.as_c_ptr()) == 1 { @@ -868,9 +847,8 @@ impl KeyPair { pub fn from_seckey_str(secp: &Secp256k1, s: &str) -> Result { let mut res = [0u8; constants::SECRET_KEY_SIZE]; match from_hex(s, &mut res) { - Ok(constants::SECRET_KEY_SIZE) => { - KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE]) - } + Ok(constants::SECRET_KEY_SIZE) => + KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE]), _ => Err(Error::InvalidPublicKey), } } @@ -962,11 +940,8 @@ impl KeyPair { tweak: &Scalar, ) -> Result { unsafe { - let err = ffi::secp256k1_keypair_xonly_tweak_add( - secp.ctx, - &mut self.0, - tweak.as_c_ptr(), - ); + let err = + ffi::secp256k1_keypair_xonly_tweak_add(secp.ctx, &mut self.0, tweak.as_c_ptr()); if err != 1 { return Err(Error::InvalidTweak); } @@ -979,17 +954,13 @@ impl KeyPair { /// /// This is equivalent to using [`SecretKey::from_keypair`]. #[inline] - pub fn secret_key(&self) -> SecretKey { - SecretKey::from_keypair(self) - } + pub fn secret_key(&self) -> SecretKey { SecretKey::from_keypair(self) } /// Returns the [`PublicKey`] for this [`KeyPair`]. /// /// This is equivalent to using [`PublicKey::from_keypair`]. #[inline] - pub fn public_key(&self) -> PublicKey { - PublicKey::from_keypair(self) - } + pub fn public_key(&self) -> PublicKey { PublicKey::from_keypair(self) } /// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for this [`KeyPair`]. /// @@ -1010,30 +981,22 @@ impl KeyPair { impl From for SecretKey { #[inline] - fn from(pair: KeyPair) -> Self { - SecretKey::from_keypair(&pair) - } + fn from(pair: KeyPair) -> Self { SecretKey::from_keypair(&pair) } } impl<'a> From<&'a KeyPair> for SecretKey { #[inline] - fn from(pair: &'a KeyPair) -> Self { - SecretKey::from_keypair(pair) - } + fn from(pair: &'a KeyPair) -> Self { SecretKey::from_keypair(pair) } } impl From for PublicKey { #[inline] - fn from(pair: KeyPair) -> Self { - PublicKey::from_keypair(&pair) - } + fn from(pair: KeyPair) -> Self { PublicKey::from_keypair(&pair) } } impl<'a> From<&'a KeyPair> for PublicKey { #[inline] - fn from(pair: &'a KeyPair) -> Self { - PublicKey::from_keypair(pair) - } + fn from(pair: &'a KeyPair) -> Self { PublicKey::from_keypair(pair) } } impl str::FromStr for KeyPair { @@ -1060,8 +1023,10 @@ impl serde::Serialize for KeyPair { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2]; - s.serialize_str(crate::to_hex(&self.secret_bytes(), &mut buf) - .expect("fixed-size hex serialization")) + s.serialize_str( + crate::to_hex(&self.secret_bytes(), &mut buf) + .expect("fixed-size hex serialization"), + ) } else { let mut tuple = s.serialize_tuple(constants::SECRET_KEY_SIZE)?; for byte in self.secret_bytes().iter() { @@ -1078,25 +1043,22 @@ impl<'de> serde::Deserialize<'de> for KeyPair { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "a hex string representing 32 byte KeyPair" + "a hex string representing 32 byte KeyPair", )) } else { - let visitor = super::serde_util::Tuple32Visitor::new( - "raw 32 bytes KeyPair", - |data| { - #[cfg(feature = "global-context")] - let ctx = SECP256K1; + let visitor = super::serde_util::Tuple32Visitor::new("raw 32 bytes KeyPair", |data| { + #[cfg(feature = "global-context")] + let ctx = SECP256K1; - #[cfg(all(not(feature = "global-context"), feature = "alloc"))] - let ctx = Secp256k1::signing_only(); + #[cfg(all(not(feature = "global-context"), feature = "alloc"))] + let ctx = Secp256k1::signing_only(); - #[cfg(not(any(feature = "global-context", feature = "alloc")))] - let ctx: Secp256k1 = panic!("The previous implementation was panicking too, please enable the global-context feature of rust-secp256k1"); + #[cfg(not(any(feature = "global-context", feature = "alloc")))] + let ctx: Secp256k1 = panic!("The previous implementation was panicking too, please enable the global-context feature of rust-secp256k1"); - #[allow(clippy::needless_borrow)] - KeyPair::from_seckey_slice(&ctx, data) - } - ); + #[allow(clippy::needless_borrow)] + KeyPair::from_seckey_slice(&ctx, data) + }); d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor) } } @@ -1104,13 +1066,9 @@ impl<'de> serde::Deserialize<'de> for KeyPair { impl CPtr for KeyPair { type Target = ffi::KeyPair; - fn as_c_ptr(&self) -> *const Self::Target { - &self.0 - } + fn as_c_ptr(&self) -> *const Self::Target { &self.0 } - fn as_mut_c_ptr(&mut self) -> *mut Self::Target { - &mut self.0 - } + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 } } /// An x-only public key, used for verification of Schnorr signatures and serialized according to BIP-340. @@ -1150,9 +1108,7 @@ impl fmt::LowerHex for XOnlyPublicKey { } impl fmt::Display for XOnlyPublicKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl str::FromStr for XOnlyPublicKey { @@ -1160,9 +1116,8 @@ impl str::FromStr for XOnlyPublicKey { fn from_str(s: &str) -> Result { let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE]; match from_hex(s, &mut res) { - Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => { - XOnlyPublicKey::from_slice(&res[0..constants::SCHNORR_PUBLIC_KEY_SIZE]) - } + Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => + XOnlyPublicKey::from_slice(&res[0..constants::SCHNORR_PUBLIC_KEY_SIZE]), _ => Err(Error::InvalidPublicKey), } } @@ -1172,16 +1127,15 @@ impl XOnlyPublicKey { /// Obtains a raw const pointer suitable for use with FFI functions. #[inline] #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")] - pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey { - self.as_c_ptr() - } + pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey { self.as_c_ptr() } /// Obtains a raw mutable pointer suitable for use with FFI functions. #[inline] - #[deprecated(since = "0.25.0", note = "Use Self::as_mut_c_ptr if you need to access the FFI layer")] - pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey { - self.as_mut_c_ptr() - } + #[deprecated( + since = "0.25.0", + note = "Use Self::as_mut_c_ptr if you need to access the FFI layer" + )] + pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey { self.as_mut_c_ptr() } /// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for `keypair`. #[inline] @@ -1196,7 +1150,8 @@ impl XOnlyPublicKey { keypair.as_c_ptr(), ); debug_assert_eq!(ret, 1); - let parity = Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1"); + let parity = + Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1"); (XOnlyPublicKey(xonly_pk), parity) } @@ -1378,16 +1333,12 @@ impl Parity { /// Converts parity into an integer (byte) value. /// /// This returns `0` for even parity and `1` for odd parity. - pub fn to_u8(self) -> u8 { - self as u8 - } + pub fn to_u8(self) -> u8 { self as u8 } /// Converts parity into an integer value. /// /// This returns `0` for even parity and `1` for odd parity. - pub fn to_i32(self) -> i32 { - self as i32 - } + pub fn to_i32(self) -> i32 { self as i32 } /// Constructs a [`Parity`] from a byte. /// @@ -1414,32 +1365,24 @@ impl Parity { impl TryFrom for Parity { type Error = InvalidParityValue; - fn try_from(parity: i32) -> Result { - Self::from_i32(parity) - } + fn try_from(parity: i32) -> Result { Self::from_i32(parity) } } /// `Even` for `0`, `Odd` for `1`, error for anything else impl TryFrom for Parity { type Error = InvalidParityValue; - fn try_from(parity: u8) -> Result { - Self::from_u8(parity) - } + fn try_from(parity: u8) -> Result { Self::from_u8(parity) } } /// The conversion returns `0` for even parity and `1` for odd. impl From for i32 { - fn from(parity: Parity) -> i32 { - parity.to_i32() - } + fn from(parity: Parity) -> i32 { parity.to_i32() } } /// The conversion returns `0` for even parity and `1` for odd. impl From for u8 { - fn from(parity: Parity) -> u8 { - parity.to_u8() - } + fn from(parity: Parity) -> u8 { parity.to_u8() } } /// Returns even parity if the operands are equal, odd otherwise. @@ -1449,9 +1392,9 @@ impl BitXor for Parity { fn bitxor(self, rhs: Parity) -> Self::Output { // This works because Parity has only two values (i.e. only 1 bit of information). if self == rhs { - Parity::Even // 1^1==0 and 0^0==0 + Parity::Even // 1^1==0 and 0^0==0 } else { - Parity::Odd // 1^0==1 and 0^1==1 + Parity::Odd // 1^0==1 and 0^1==1 } } } @@ -1475,9 +1418,7 @@ impl fmt::Display for InvalidParityValue { impl std::error::Error for InvalidParityValue {} impl From for Error { - fn from(error: InvalidParityValue) -> Self { - Error::InvalidParityValue(error) - } + fn from(error: InvalidParityValue) -> Self { Error::InvalidParityValue(error) } } /// The parity is serialized as `u8` - `0` for even, `1` for odd. @@ -1496,8 +1437,7 @@ impl<'de> serde::Deserialize<'de> for Parity { fn deserialize>(d: D) -> Result { struct Visitor; - impl<'de> serde::de::Visitor<'de> for Visitor - { + impl<'de> serde::de::Visitor<'de> for Visitor { type Value = Parity; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1505,7 +1445,8 @@ impl<'de> serde::Deserialize<'de> for Parity { } fn visit_u8(self, v: u8) -> Result - where E: serde::de::Error + where + E: serde::de::Error, { use serde::de::Unexpected; @@ -1520,21 +1461,15 @@ impl<'de> serde::Deserialize<'de> for Parity { impl CPtr for XOnlyPublicKey { type Target = ffi::XOnlyPublicKey; - fn as_c_ptr(&self) -> *const Self::Target { - &self.0 - } + fn as_c_ptr(&self) -> *const Self::Target { &self.0 } - fn as_mut_c_ptr(&mut self) -> *mut Self::Target { - &mut self.0 - } + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 } } /// Creates a new Schnorr public key from a FFI x-only public key. impl From for XOnlyPublicKey { #[inline] - fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey { - XOnlyPublicKey(pk) - } + fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey { XOnlyPublicKey(pk) } } impl From for XOnlyPublicKey { @@ -1577,12 +1512,12 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "a hex string representing 32 byte schnorr public key" + "a hex string representing 32 byte schnorr public key", )) } else { let visitor = super::serde_util::Tuple32Visitor::new( "raw 32 bytes schnorr public key", - XOnlyPublicKey::from_slice + XOnlyPublicKey::from_slice, ); d.deserialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE, visitor) } @@ -1603,57 +1538,51 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey { #[cfg(all(feature = "global-context", feature = "serde"))] pub mod serde_keypair { use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use crate::key::{KeyPair, SecretKey}; #[allow(missing_docs)] pub fn serialize(key: &KeyPair, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { SecretKey::from_keypair(key).serialize(serializer) } #[allow(missing_docs)] pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let secret_key = SecretKey::deserialize(deserializer)?; - Ok(KeyPair::from_secret_key( - crate::SECP256K1, - &secret_key, - )) + Ok(KeyPair::from_secret_key(crate::SECP256K1, &secret_key)) } } #[cfg(test)] #[allow(unused_imports)] mod test { - use bitcoin_hashes::hex::ToHex; - use super::*; - use core::str::FromStr; + use bitcoin_hashes::hex::ToHex; #[cfg(any(feature = "alloc", feature = "std"))] - use rand::{Error, RngCore, thread_rng, rngs::mock::StepRng}; + use rand::{rngs::mock::StepRng, thread_rng, Error, RngCore}; use serde_test::{Configure, Token}; - #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; - use super::{XOnlyPublicKey, PublicKey, Secp256k1, SecretKey, KeyPair, Parity}; - use crate::{constants, from_hex, to_hex}; + use super::{KeyPair, Parity, PublicKey, Secp256k1, SecretKey, XOnlyPublicKey, *}; use crate::Error::{InvalidPublicKey, InvalidSecretKey}; - use crate::Scalar; + use crate::{constants, from_hex, to_hex, Scalar}; #[cfg(not(fuzzing))] macro_rules! hex { - ($hex:expr) => ({ + ($hex:expr) => {{ let mut result = vec![0; $hex.len() / 2]; from_hex($hex, &mut result).expect("valid hex string"); result - }); + }}; } #[test] @@ -1670,10 +1599,18 @@ mod test { assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey)); assert_eq!(PublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey)); - let uncompressed = PublicKey::from_slice(&[4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188]); + let uncompressed = PublicKey::from_slice(&[ + 4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, + 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, + 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, + 155, 51, 247, 123, 113, 60, 228, 188, + ]); assert!(uncompressed.is_ok()); - let compressed = PublicKey::from_slice(&[3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78]); + let compressed = PublicKey::from_slice(&[ + 3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, + 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78, + ]); assert!(compressed.is_ok()); } @@ -1777,10 +1714,7 @@ mod test { PublicKey::from_slice(&[0x55; constants::PUBLIC_KEY_SIZE]), Err(InvalidPublicKey) ); - assert_eq!( - PublicKey::from_slice(&[]), - Err(InvalidPublicKey) - ); + assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey)); } #[test] @@ -1803,25 +1737,22 @@ mod test { SecretKey::from_slice(&[0x00; constants::SECRET_KEY_SIZE]), Err(InvalidSecretKey) ); - assert_eq!( - SecretKey::from_slice(&[]), - Err(InvalidSecretKey) - ); + assert_eq!(SecretKey::from_slice(&[]), Err(InvalidSecretKey)); } #[test] #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] fn test_debug_output() { - let s = Secp256k1::new(); let (sk, _) = s.generate_keypair(&mut StepRng::new(1, 1)); - assert_eq!(&format!("{:?}", sk), - "SecretKey(#d3e0c51a23169bb5)"); + assert_eq!(&format!("{:?}", sk), "SecretKey(#d3e0c51a23169bb5)"); let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2]; - assert_eq!(to_hex(&sk[..], &mut buf).unwrap(), - "0100000000000000020000000000000003000000000000000400000000000000"); + assert_eq!( + to_hex(&sk[..], &mut buf).unwrap(), + "0100000000000000020000000000000003000000000000000400000000000000" + ); } #[test] @@ -1844,14 +1775,20 @@ mod test { #[cfg(not(fuzzing))] let pk = PublicKey::from_secret_key(&s, &sk); #[cfg(fuzzing)] - let pk = PublicKey::from_slice(&[0x02, 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66]).expect("pk"); + let pk = PublicKey::from_slice(&[ + 0x02, 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, + 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, + 0xfe, 0x91, 0xdd, 0xd1, 0x66, + ]) + .expect("pk"); assert_eq!( sk.display_secret().to_string(), "01010101010101010001020304050607ffff0000ffff00006363636363636363" ); assert_eq!( - SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363").unwrap(), + SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363") + .unwrap(), sk ); assert_eq!( @@ -1859,27 +1796,62 @@ mod test { "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" ); assert_eq!( - PublicKey::from_str("0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166").unwrap(), + PublicKey::from_str( + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" + ) + .unwrap(), pk ); assert_eq!( - PublicKey::from_str("04\ + PublicKey::from_str( + "04\ 18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\ 84B84DB303A340CD7D6823EE88174747D12A67D2F8F2F9BA40846EE5EE7A44F6" - ).unwrap(), + ) + .unwrap(), pk ); - assert!(SecretKey::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").is_err()); - assert!(SecretKey::from_str("01010101010101010001020304050607ffff0000ffff0000636363636363636363").is_err()); - assert!(SecretKey::from_str("01010101010101010001020304050607ffff0000ffff0000636363636363636").is_err()); - assert!(SecretKey::from_str("01010101010101010001020304050607ffff0000ffff000063636363636363").is_err()); - assert!(SecretKey::from_str("01010101010101010001020304050607ffff0000ffff000063636363636363xx").is_err()); - assert!(PublicKey::from_str("0300000000000000000000000000000000000000000000000000000000000000000").is_err()); - assert!(PublicKey::from_str("0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601").is_err()); - assert!(PublicKey::from_str("0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16").is_err()); - assert!(PublicKey::from_str("0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1").is_err()); - assert!(PublicKey::from_str("xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1").is_err()); + assert!(SecretKey::from_str( + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ) + .is_err()); + assert!(SecretKey::from_str( + "01010101010101010001020304050607ffff0000ffff0000636363636363636363" + ) + .is_err()); + assert!(SecretKey::from_str( + "01010101010101010001020304050607ffff0000ffff0000636363636363636" + ) + .is_err()); + assert!(SecretKey::from_str( + "01010101010101010001020304050607ffff0000ffff000063636363636363" + ) + .is_err()); + assert!(SecretKey::from_str( + "01010101010101010001020304050607ffff0000ffff000063636363636363xx" + ) + .is_err()); + assert!(PublicKey::from_str( + "0300000000000000000000000000000000000000000000000000000000000000000" + ) + .is_err()); + assert!(PublicKey::from_str( + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601" + ) + .is_err()); + assert!(PublicKey::from_str( + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16" + ) + .is_err()); + assert!(PublicKey::from_str( + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1" + ) + .is_err()); + assert!(PublicKey::from_str( + "xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1" + ) + .is_err()); let long_str = "a".repeat(1024 * 1024); assert!(SecretKey::from_str(&long_str).is_err()); @@ -1892,13 +1864,24 @@ mod test { #[cfg(not(fuzzing))] #[cfg(any(feature = "alloc", feature = "std"))] fn test_pubkey_serialize() { - let s = Secp256k1::new(); - let (_, pk1) = s.generate_keypair(&mut StepRng::new(1,1)); - assert_eq!(&pk1.serialize_uncompressed()[..], - &[4, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126, 9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229, 185, 28, 165, 110, 27, 3, 162, 126, 238, 167, 157, 242, 221, 76, 251, 237, 34, 231, 72, 39, 245, 3, 191, 64, 111, 170, 117, 103, 82, 28, 102, 163][..]); - assert_eq!(&pk1.serialize()[..], - &[3, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126, 9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229][..]); + let (_, pk1) = s.generate_keypair(&mut StepRng::new(1, 1)); + assert_eq!( + &pk1.serialize_uncompressed()[..], + &[ + 4, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126, + 9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229, 185, 28, 165, + 110, 27, 3, 162, 126, 238, 167, 157, 242, 221, 76, 251, 237, 34, 231, 72, 39, 245, + 3, 191, 64, 111, 170, 117, 103, 82, 28, 102, 163 + ][..] + ); + assert_eq!( + &pk1.serialize()[..], + &[ + 3, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126, + 9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229 + ][..] + ); } #[test] @@ -1964,7 +1947,7 @@ mod test { assert!(sk.mul_tweak(&tweak).is_err()) } - #[test] + #[test] #[cfg(any(feature = "alloc", feature = "std"))] fn test_negation() { let s = Secp256k1::new(); @@ -1990,8 +1973,8 @@ mod test { #[cfg(any(feature = "alloc", feature = "std"))] fn pubkey_hash() { use std::collections::hash_map::DefaultHasher; - use std::hash::{Hash, Hasher}; use std::collections::HashSet; + use std::hash::{Hash, Hasher}; fn hash(t: &T) -> u64 { let mut s = DefaultHasher::new(); @@ -2001,28 +1984,31 @@ mod test { let s = Secp256k1::new(); let mut set = HashSet::new(); - const COUNT : usize = 1024; + const COUNT: usize = 1024; for _ in 0..COUNT { let (_, pk) = s.generate_keypair(&mut thread_rng()); let hash = hash(&pk); assert!(!set.contains(&hash)); set.insert(hash); - }; + } assert_eq!(set.len(), COUNT); } #[test] #[cfg(not(fuzzing))] fn pubkey_combine() { - let compressed1 = PublicKey::from_slice( - &hex!("0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"), - ).unwrap(); - let compressed2 = PublicKey::from_slice( - &hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"), - ).unwrap(); - let exp_sum = PublicKey::from_slice( - &hex!("0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"), - ).unwrap(); + let compressed1 = PublicKey::from_slice(&hex!( + "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba" + )) + .unwrap(); + let compressed2 = PublicKey::from_slice(&hex!( + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + )) + .unwrap(); + let exp_sum = PublicKey::from_slice(&hex!( + "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07" + )) + .unwrap(); let sum1 = compressed1.combine(&compressed2); assert!(sum1.is_ok()); @@ -2035,18 +2021,22 @@ mod test { #[test] #[cfg(not(fuzzing))] fn pubkey_combine_keys() { - let compressed1 = PublicKey::from_slice( - &hex!("0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"), - ).unwrap(); - let compressed2 = PublicKey::from_slice( - &hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"), - ).unwrap(); - let compressed3 = PublicKey::from_slice( - &hex!("03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0") - ).unwrap(); - let exp_sum = PublicKey::from_slice( - &hex!("0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad"), - ).unwrap(); + let compressed1 = PublicKey::from_slice(&hex!( + "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba" + )) + .unwrap(); + let compressed2 = PublicKey::from_slice(&hex!( + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + )) + .unwrap(); + let compressed3 = PublicKey::from_slice(&hex!( + "03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0" + )) + .unwrap(); + let exp_sum = PublicKey::from_slice(&hex!( + "0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad" + )) + .unwrap(); let sum1 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]); assert!(sum1.is_ok()); @@ -2085,13 +2075,15 @@ mod test { #[test] #[allow(clippy::nonminimal_bool)] fn pubkey_equal() { - let pk1 = PublicKey::from_slice( - &hex!("0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"), - ).unwrap(); + let pk1 = PublicKey::from_slice(&hex!( + "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba" + )) + .unwrap(); let pk2 = pk1; - let pk3 = PublicKey::from_slice( - &hex!("02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"), - ).unwrap(); + let pk3 = PublicKey::from_slice(&hex!( + "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443" + )) + .unwrap(); assert_eq!(pk1, pk2); assert!(pk1 <= pk2); @@ -2108,7 +2100,7 @@ mod test { #[test] #[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))] fn test_serde() { - use serde_test::{Configure, Token, assert_tokens}; + use serde_test::{assert_tokens, Configure, Token}; #[rustfmt::skip] static SK_BYTES: [u8; 32] = [ 1, 1, 1, 1, 1, 1, 1, 1, @@ -2183,7 +2175,8 @@ mod test { let (xonly, _) = XOnlyPublicKey::from_keypair(&kp); let tweaked_kp = kp.add_xonly_tweak(&s, &tweak).expect("keypair tweak add failed"); - let (tweaked_xonly, parity) = xonly.add_tweak(&s, &tweak).expect("xonly pubkey tweak failed"); + let (tweaked_xonly, parity) = + xonly.add_tweak(&s, &tweak).expect("xonly pubkey tweak failed"); let (want_tweaked_xonly, tweaked_kp_parity) = XOnlyPublicKey::from_keypair(&tweaked_kp); @@ -2216,7 +2209,8 @@ mod test { #[cfg(all(feature = "global-context", feature = "serde"))] fn test_serde_keypair() { use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use serde_test::{Configure, Token, assert_tokens}; + use serde_test::{assert_tokens, Configure, Token}; + use super::serde_keypair; use crate::key::KeyPair; @@ -2227,13 +2221,18 @@ mod test { impl<'de> Deserialize<'de> for KeyPairWrapper { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> { + where + D: Deserializer<'de>, + { serde_keypair::deserialize(deserializer).map(KeyPairWrapper) } } impl Serialize for KeyPairWrapper { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { serde_keypair::serialize(&self.0, serializer) } } @@ -2284,7 +2283,7 @@ mod test { ]; let mut pk_bytes = [0u8; 33]; - pk_bytes[0] = 0x02; // Use positive Y co-ordinate. + pk_bytes[0] = 0x02; // Use positive Y co-ordinate. pk_bytes[1..].clone_from_slice(&PK_BYTES); let sk = SecretKey::from_slice(&SK_BYTES).expect("failed to parse sk bytes"); @@ -2415,7 +2414,7 @@ mod test { #[cfg(not(fuzzing))] #[cfg(all(feature = "global-context", feature = "serde"))] fn test_serde_x_only_pubkey() { - use serde_test::{Configure, Token, assert_tokens}; + use serde_test::{assert_tokens, Configure, Token}; #[rustfmt::skip] static SK_BYTES: [u8; 32] = [ @@ -2458,7 +2457,7 @@ mod test { } #[test] - #[cfg(all(any(feature= "alloc", feature = "global-context"), feature = "serde"))] + #[cfg(all(any(feature = "alloc", feature = "global-context"), feature = "serde"))] fn test_keypair_deserialize_serde() { let ctx = crate::Secp256k1::new(); let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242"; @@ -2485,10 +2484,12 @@ mod test { #[cfg(bench)] mod benches { - use test::Bencher; use std::collections::BTreeSet; - use crate::PublicKey; + + use test::Bencher; + use crate::constants::GENERATOR_X; + use crate::PublicKey; #[bench] fn bench_pk_ordering(b: &mut Bencher) { diff --git a/src/lib.rs b/src/lib.rs index aff0cdf..5d6f3d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,11 +153,8 @@ // Coding conventions #![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)] #![warn(missing_docs, missing_copy_implementations, missing_debug_implementations)] - #![allow(clippy::missing_safety_doc)] - #![cfg_attr(all(not(test), not(feature = "std")), no_std)] - // Experimental features we need. #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(bench, feature(test))] @@ -184,29 +181,30 @@ pub mod schnorr; #[cfg(feature = "serde")] mod serde_util; -#[cfg(any(test, feature = "rand"))] -#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] -pub use rand; -#[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -pub use serde; +use core::marker::PhantomData; +use core::{fmt, mem, str}; + #[cfg(feature = "bitcoin-hashes")] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))] pub use bitcoin_hashes as hashes; -pub use secp256k1_sys as ffi; -pub use crate::key::{PublicKey, SecretKey}; -pub use crate::context::*; -pub use crate::key::*; -pub use crate::scalar::Scalar; - #[cfg(feature = "global-context")] #[cfg_attr(docsrs, doc(cfg(feature = "global-context")))] pub use context::global::SECP256K1; +#[cfg(any(test, feature = "rand"))] +#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] +pub use rand; +pub use secp256k1_sys as ffi; +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +pub use serde; -use core::{fmt, str, mem, marker::PhantomData}; -use crate::ffi::{CPtr, impl_array_newtype, types::AlignedType}; +pub use crate::context::*; +use crate::ffi::types::AlignedType; +use crate::ffi::{impl_array_newtype, CPtr}; #[cfg(feature = "bitcoin-hashes")] use crate::hashes::Hash; +pub use crate::key::{PublicKey, SecretKey, *}; +pub use crate::scalar::Scalar; /// Trait describing something that promises to be a 32-byte random number; in particular, /// it has negligible probability of being zero or overflowing the group order. Such objects @@ -219,25 +217,19 @@ pub trait ThirtyTwoByteHash { #[cfg(feature = "bitcoin-hashes")] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))] impl ThirtyTwoByteHash for hashes::sha256::Hash { - fn into_32(self) -> [u8; 32] { - self.into_inner() - } + fn into_32(self) -> [u8; 32] { self.into_inner() } } #[cfg(feature = "bitcoin-hashes")] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))] impl ThirtyTwoByteHash for hashes::sha256d::Hash { - fn into_32(self) -> [u8; 32] { - self.into_inner() - } + fn into_32(self) -> [u8; 32] { self.into_inner() } } #[cfg(feature = "bitcoin-hashes")] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))] impl ThirtyTwoByteHash for hashes::sha256t::Hash { - fn into_32(self) -> [u8; 32] { - self.into_inner() - } + fn into_32(self) -> [u8; 32] { self.into_inner() } } /// A (hashed) message input to an ECDSA signature. @@ -260,7 +252,7 @@ impl Message { ret[..].copy_from_slice(data); Ok(Message(ret)) } - _ => Err(Error::InvalidMessage) + _ => Err(Error::InvalidMessage), } } @@ -291,9 +283,7 @@ impl Message { impl From for Message { /// Converts a 32-byte hash directly to a message without error paths. - fn from(t: T) -> Message { - Message(t.into_32()) - } + fn from(t: T) -> Message { Message(t.into_32()) } } impl fmt::LowerHex for Message { @@ -306,9 +296,7 @@ impl fmt::LowerHex for Message { } impl fmt::Display for Message { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } /// An ECDSA error @@ -353,7 +341,9 @@ impl fmt::Display for Error { InvalidRecoveryId => f.write_str("bad recovery id"), InvalidTweak => f.write_str("bad tweak"), NotEnoughMemory => f.write_str("not enough memory allocated"), - InvalidPublicKeySum => f.write_str("the sum of public keys was invalid or the input vector lengths was less than 1"), + InvalidPublicKeySum => f.write_str( + "the sum of public keys was invalid or the input vector lengths was less than 1", + ), InvalidParityValue(e) => write_err!(f, "couldn't create parity"; e), } } @@ -379,7 +369,6 @@ impl std::error::Error for Error { } } - /// The secp256k1 engine, used to execute all signature operations. pub struct Secp256k1 { ctx: *mut ffi::Context, @@ -396,7 +385,7 @@ impl PartialEq for Secp256k1 { fn eq(&self, _other: &Secp256k1) -> bool { true } } -impl Eq for Secp256k1 { } +impl Eq for Secp256k1 {} impl Drop for Secp256k1 { fn drop(&mut self) { @@ -414,14 +403,11 @@ impl fmt::Debug for Secp256k1 { } impl Secp256k1 { - /// Getter for the raw pointer to the underlying secp256k1 context. This /// shouldn't be needed with normal usage of the library. It enables /// extending the Secp256k1 with more cryptographic algorithms outside of /// this crate. - pub fn ctx(&self) -> &*mut ffi::Context { - &self.ctx - } + pub fn ctx(&self) -> &*mut ffi::Context { &self.ctx } /// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all). pub fn preallocate_size_gen() -> usize { @@ -468,8 +454,10 @@ impl Secp256k1 { #[inline] #[cfg(any(test, feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] - pub fn generate_keypair(&self, rng: &mut R) - -> (key::SecretKey, key::PublicKey) { + pub fn generate_keypair( + &self, + rng: &mut R, + ) -> (key::SecretKey, key::PublicKey) { let sk = key::SecretKey::new(rng); let pk = key::PublicKey::from_secret_key(self, &sk); (sk, pk) @@ -525,38 +513,38 @@ fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> { let mut i = 0; for &b in src { target[i] = HEX_TABLE[usize::from(b >> 4)]; - target[i+1] = HEX_TABLE[usize::from(b & 0b00001111)]; - i +=2 ; + target[i + 1] = HEX_TABLE[usize::from(b & 0b00001111)]; + i += 2; } let result = &target[..hex_len]; debug_assert!(str::from_utf8(result).is_ok()); return unsafe { Ok(str::from_utf8_unchecked(result)) }; } - #[cfg(test)] mod tests { use std::marker::PhantomData; use std::str::FromStr; - use rand::{RngCore, thread_rng}; - + use rand::{thread_rng, RngCore}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; - use crate::{constants, ecdsa, from_hex, to_hex, Message, PublicKey, Secp256k1, SecretKey, Error}; use crate::context::*; - use crate::ffi::{self, types::AlignedType}; + use crate::ffi::types::AlignedType; + use crate::ffi::{self}; + use crate::{ + constants, ecdsa, from_hex, to_hex, Error, Message, PublicKey, Secp256k1, SecretKey, + }; macro_rules! hex { - ($hex:expr) => ({ + ($hex:expr) => {{ let mut result = vec![0; $hex.len() / 2]; from_hex($hex, &mut result).expect("valid hex string"); result - }); + }}; } - #[test] #[cfg(feature = "std")] fn test_manual_create_destroy() { @@ -565,9 +553,12 @@ mod tests { let ctx_vrfy = unsafe { ffi::secp256k1_context_create(VerifyOnlyPreallocated::FLAGS) }; let size = 0; - let full: Secp256k1 = Secp256k1{ctx: ctx_full, phantom: PhantomData, size}; - let sign: Secp256k1 = Secp256k1{ctx: ctx_sign, phantom: PhantomData, size}; - let vrfy: Secp256k1 = Secp256k1{ctx: ctx_vrfy, phantom: PhantomData, size}; + let full: Secp256k1 = + Secp256k1 { ctx: ctx_full, phantom: PhantomData, size }; + let sign: Secp256k1 = + Secp256k1 { ctx: ctx_sign, phantom: PhantomData, size }; + let vrfy: Secp256k1 = + Secp256k1 { ctx: ctx_vrfy, phantom: PhantomData, size }; let (sk, pk) = full.generate_keypair(&mut thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap(); @@ -579,7 +570,9 @@ mod tests { assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok()); assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok()); - drop(full);drop(sign);drop(vrfy); + drop(full); + drop(sign); + drop(vrfy); unsafe { ffi::secp256k1_context_destroy(ctx_vrfy) }; unsafe { ffi::secp256k1_context_destroy(ctx_sign) }; @@ -595,9 +588,9 @@ mod tests { let ctx_sign = Secp256k1::signing_only(); let ctx_vrfy = Secp256k1::verification_only(); - let mut full = unsafe {Secp256k1::from_raw_all(ctx_full.ctx)}; - let mut sign = unsafe {Secp256k1::from_raw_signing_only(ctx_sign.ctx)}; - let mut vrfy = unsafe {Secp256k1::from_raw_verification_only(ctx_vrfy.ctx)}; + let mut full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) }; + let mut sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) }; + let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) }; let (sk, pk) = full.generate_keypair(&mut thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap(); @@ -613,7 +606,6 @@ mod tests { ManuallyDrop::drop(&mut full); ManuallyDrop::drop(&mut sign); ManuallyDrop::drop(&mut vrfy); - } drop(ctx_full); drop(ctx_sign); @@ -640,8 +632,8 @@ mod tests { let sign = Secp256k1::preallocated_signing_only(&mut buf_sign).unwrap(); let vrfy = Secp256k1::preallocated_verification_only(&mut buf_vfy).unwrap(); -// drop(buf_vfy); // The buffer can't get dropped before the context. -// println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker. + // drop(buf_vfy); // The buffer can't get dropped before the context. + // println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker. let (sk, pk) = full.generate_keypair(&mut thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap(); @@ -709,7 +701,7 @@ mod tests { assert!(ecdsa::Signature::from_compact(&compact[0..4]).is_err()); assert!(ecdsa::Signature::from_der(&compact[..]).is_err()); assert!(ecdsa::Signature::from_der(&der[0..4]).is_err()); - } + } } #[test] @@ -729,15 +721,18 @@ mod tests { assert!(ecdsa::Signature::from_str( "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab4" - ).is_err()); + ) + .is_err()); assert!(ecdsa::Signature::from_str( "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab" - ).is_err()); + ) + .is_err()); assert!(ecdsa::Signature::from_str( "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eabxx" - ).is_err()); + ) + .is_err()); assert!(ecdsa::Signature::from_str( "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\ @@ -745,7 +740,8 @@ mod tests { 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\ 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45" - ).is_err()); + ) + .is_err()); // 71 byte signature let hex_str = "30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce774b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776"; @@ -796,14 +792,14 @@ mod tests { if compact[0] < 0x80 { assert_eq!(sig, low_r_sig); } else { - #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs + #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs assert_ne!(sig, low_r_sig); } - #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs + #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0)); - #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs + #[cfg(not(fuzzing))] // mocked sig generation doesn't produce low-R sigs assert!(ecdsa::der_length_check(&grind_r_sig.0, 70)); - } + } } #[test] @@ -862,15 +858,23 @@ mod tests { #[test] fn test_bad_slice() { - assert_eq!(ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]), - Err(Error::InvalidSignature)); - assert_eq!(ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]), - Err(Error::InvalidSignature)); + assert_eq!( + ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]), + Err(Error::InvalidSignature) + ); + assert_eq!( + ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]), + Err(Error::InvalidSignature) + ); - assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]), - Err(Error::InvalidMessage)); - assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]), - Err(Error::InvalidMessage)); + assert_eq!( + Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]), + Err(Error::InvalidMessage) + ); + assert_eq!( + Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]), + Err(Error::InvalidMessage) + ); assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok()); assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok()); } @@ -881,7 +885,7 @@ mod tests { const AMOUNT: usize = 1024; for i in 0..AMOUNT { // 255 isn't a valid utf8 character. - let mut hex_buf = [255u8; AMOUNT*2]; + let mut hex_buf = [255u8; AMOUNT * 2]; let mut src_buf = [0u8; AMOUNT]; let mut result_buf = [0u8; AMOUNT]; let src = &mut src_buf[0..i]; @@ -892,9 +896,8 @@ mod tests { assert_eq!(src, &result_buf[..i]); } - - assert!(to_hex(&[1;2], &mut [0u8; 3]).is_err()); - assert!(to_hex(&[1;2], &mut [0u8; 4]).is_ok()); + assert!(to_hex(&[1; 2], &mut [0u8; 3]).is_err()); + assert!(to_hex(&[1; 2], &mut [0u8; 4]).is_ok()); assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err()); assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok()); assert!(from_hex("a", &mut [0u8; 4]).is_err()); @@ -902,14 +905,16 @@ mod tests { } #[test] - #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format + #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format #[cfg(any(feature = "alloc", feature = "std"))] fn test_noncedata() { let secp = Secp256k1::new(); let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac"); let msg = Message::from_slice(&msg).unwrap(); let noncedata = [42u8; 32]; - let sk = SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead").unwrap(); + let sk = + SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead") + .unwrap(); let expected_sig = hex!("24861b3edd4e7da43319c635091405feced6efa4ec99c3c3c35f6c3ba0ed8816116772e84994084db85a6c20589f6a85af569d42275c2a5dd900da5776b99d5d"); let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap(); @@ -919,7 +924,7 @@ mod tests { } #[test] - #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs + #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(any(feature = "alloc", feature = "std"))] fn test_low_s() { // nb this is a transaction on testnet @@ -942,13 +947,15 @@ mod tests { } #[test] - #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format + #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format #[cfg(any(feature = "alloc", feature = "std"))] fn test_low_r() { let secp = Secp256k1::new(); let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac"); let msg = Message::from_slice(&msg).unwrap(); - let sk = SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead").unwrap(); + let sk = + SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead") + .unwrap(); let expected_sig = hex!("047dd4d049db02b430d24c41c7925b2725bcd5a85393513bdec04b4dc363632b1054d0180094122b380f4cfa391e6296244da773173e78fc745c1b9c79f7b713"); let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap(); @@ -958,13 +965,15 @@ mod tests { } #[test] - #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format + #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format #[cfg(any(feature = "alloc", feature = "std"))] fn test_grind_r() { let secp = Secp256k1::new(); let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167"); let msg = Message::from_slice(&msg).unwrap(); - let sk = SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b").unwrap(); + let sk = + SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b") + .unwrap(); let expected_sig = ecdsa::Signature::from_str("304302202ffc447100d518c8ba643d11f3e6a83a8640488e7d2537b1954b942408be6ea3021f26e1248dd1e52160c3a38af9769d91a1a806cab5f9d508c103464d3c02d6e1").unwrap(); let sig = secp.sign_ecdsa_grind_r(&msg, &sk, 2); @@ -973,11 +982,11 @@ mod tests { } #[cfg(feature = "serde")] - #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs + #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(any(feature = "alloc", feature = "std"))] #[test] fn test_serde() { - use serde_test::{Configure, Token, assert_tokens}; + use serde_test::{assert_tokens, Configure, Token}; let s = Secp256k1::new(); @@ -985,11 +994,10 @@ mod tests { let sk = SecretKey::from_slice(&[2; 32]).unwrap(); let sig = s.sign_ecdsa(&msg, &sk); static SIG_BYTES: [u8; 71] = [ - 48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, - 179, 76, 119, 72, 102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, - 8, 230, 206, 119, 75, 2, 32, 40, 118, 231, 16, 47, 32, 79, 107, 254, - 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125, 75, 1, 0, 98, 225, - 147, 247, 99, 25, 15, 103, 118 + 48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, 179, 76, 119, 72, + 102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, 8, 230, 206, 119, 75, 2, 32, 40, + 118, 231, 16, 47, 32, 79, 107, 254, 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125, + 75, 1, 0, 98, 225, 147, 247, 99, 25, 15, 103, 118, ]; static SIG_STR: &str = "\ 30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce77\ @@ -1003,7 +1011,6 @@ mod tests { assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]); assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]); assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]); - } #[cfg(feature = "global-context")] @@ -1033,37 +1040,29 @@ mod tests { let hash = hashes::sha256::Hash::hash(test_bytes); let msg = Message::from(hash); assert_eq!(msg.0, hash.into_inner()); - assert_eq!( - msg, - Message::from_hashed_data::(test_bytes) - ); + assert_eq!(msg, Message::from_hashed_data::(test_bytes)); let hash = hashes::sha256d::Hash::hash(test_bytes); let msg = Message::from(hash); assert_eq!(msg.0, hash.into_inner()); - assert_eq!( - msg, - Message::from_hashed_data::(test_bytes) - ); + assert_eq!(msg, Message::from_hashed_data::(test_bytes)); } } #[cfg(bench)] mod benches { - use test::{Bencher, black_box}; - - use rand::{RngCore, thread_rng}; use rand::rngs::mock::StepRng; + use rand::{thread_rng, RngCore}; + use test::{black_box, Bencher}; use super::{Message, Secp256k1}; #[bench] #[cfg(any(feature = "alloc", feature = "std"))] pub fn generate(bh: &mut Bencher) { - let s = Secp256k1::new(); let mut r = StepRng::new(1, 1); - bh.iter( || { + bh.iter(|| { let (sk, pk) = s.generate_keypair(&mut r); black_box(sk); black_box(pk); diff --git a/src/macros.rs b/src/macros.rs index 152baa9..d2da41b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -24,7 +24,7 @@ macro_rules! impl_pretty_debug { f.write_str(")") } } - } + }; } /// Formats error. If `std` feature is OFF appends error source (delimited by `: `). We do this diff --git a/src/scalar.rs b/src/scalar.rs index d081394..10e57fe 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -25,7 +25,7 @@ pub struct Scalar([u8; 32]); const MAX_RAW: [u8; 32] = [ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40 + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40, ]; impl Scalar { @@ -39,9 +39,7 @@ impl Scalar { /// Generates a random scalar #[cfg(any(test, feature = "rand-std"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))] - pub fn random() -> Self { - Self::random_custom(rand::thread_rng()) - } + pub fn random() -> Self { Self::random_custom(rand::thread_rng()) } /// Generates a random scalar using supplied RNG #[cfg(any(test, feature = "rand"))] @@ -88,9 +86,7 @@ impl Scalar { } /// Serializes to big endian bytes - pub fn to_be_bytes(self) -> [u8; 32] { - self.0 - } + pub fn to_be_bytes(self) -> [u8; 32] { self.0 } /// Serializes to little endian bytes pub fn to_le_bytes(self) -> [u8; 32] { @@ -101,9 +97,7 @@ impl Scalar { // returns a reference to internal bytes // non-public to not leak the internal representation - pub(crate) fn as_be_bytes(&self) -> &[u8; 32] { - &self.0 - } + pub(crate) fn as_be_bytes(&self) -> &[u8; 32] { &self.0 } pub(crate) fn as_c_ptr(&self) -> *const u8 { use secp256k1_sys::CPtr; @@ -113,20 +107,16 @@ impl Scalar { } impl From for Scalar { - fn from(value: crate::SecretKey) -> Self { - Scalar(value.secret_bytes()) - } + fn from(value: crate::SecretKey) -> Self { Scalar(value.secret_bytes()) } } - /// Error returned when the value of scalar is invalid - larger than the curve order. // Intentionally doesn't implement `Copy` to improve forward compatibility. // Same reason for `non_exhaustive`. #[allow(missing_copy_implementations)] #[derive(Debug, Clone, Eq, PartialEq, Hash)] #[non_exhaustive] -pub struct OutOfRangeError { -} +pub struct OutOfRangeError {} impl fmt::Display for OutOfRangeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/schnorr.rs b/src/schnorr.rs index 39cded6..0d001e7 100644 --- a/src/schnorr.rs +++ b/src/schnorr.rs @@ -7,12 +7,11 @@ use core::{fmt, ptr, str}; #[cfg(any(test, feature = "rand"))] use rand::{CryptoRng, Rng}; -use crate::{constants, Error, from_hex, Message, Secp256k1, Signing, Verification}; +use crate::ffi::{self, impl_array_newtype, CPtr}; use crate::key::{KeyPair, XOnlyPublicKey}; -use crate::ffi::{self, CPtr, impl_array_newtype}; - -#[cfg(all(feature = "global-context", feature = "rand-std"))] +#[cfg(all(feature = "global-context", feature = "rand-std"))] use crate::SECP256K1; +use crate::{constants, from_hex, Error, Message, Secp256k1, Signing, Verification}; /// Represents a Schnorr signature. pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]); @@ -35,12 +34,12 @@ impl<'de> serde::Deserialize<'de> for Signature { fn deserialize>(d: D) -> Result { if d.is_human_readable() { d.deserialize_str(super::serde_util::FromStrVisitor::new( - "a hex string representing 64 byte schnorr signature" + "a hex string representing 64 byte schnorr signature", )) } else { d.deserialize_bytes(super::serde_util::BytesVisitor::new( "raw 64 bytes schnorr signature", - Signature::from_slice + Signature::from_slice, )) } } @@ -56,9 +55,7 @@ impl fmt::LowerHex for Signature { } impl fmt::Display for Signature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl str::FromStr for Signature { @@ -66,9 +63,8 @@ impl str::FromStr for Signature { fn from_str(s: &str) -> Result { let mut res = [0u8; constants::SCHNORR_SIGNATURE_SIZE]; match from_hex(s, &mut res) { - Ok(constants::SCHNORR_SIGNATURE_SIZE) => { - Signature::from_slice(&res[0..constants::SCHNORR_SIGNATURE_SIZE]) - } + Ok(constants::SCHNORR_SIGNATURE_SIZE) => + Signature::from_slice(&res[0..constants::SCHNORR_SIGNATURE_SIZE]), _ => Err(Error::InvalidSignature), } } @@ -130,11 +126,7 @@ impl Secp256k1 { } /// Create a schnorr signature without using any auxiliary random data. - pub fn sign_schnorr_no_aux_rand( - &self, - msg: &Message, - keypair: &KeyPair, - ) -> Signature { + pub fn sign_schnorr_no_aux_rand(&self, msg: &Message, keypair: &KeyPair) -> Signature { self.sign_schnorr_helper(msg, keypair, ptr::null()) } @@ -145,11 +137,7 @@ impl Secp256k1 { keypair: &KeyPair, aux_rand: &[u8; 32], ) -> Signature { - self.sign_schnorr_helper( - msg, - keypair, - aux_rand.as_c_ptr() as *const ffi::types::c_uchar, - ) + self.sign_schnorr_helper(msg, keypair, aux_rand.as_c_ptr() as *const ffi::types::c_uchar) } /// Create a schnorr signature using the given random number generator to @@ -199,15 +187,15 @@ impl Secp256k1 { mod tests { use core::str::FromStr; - use rand::{RngCore, rngs::ThreadRng, thread_rng}; + use rand::rngs::ThreadRng; + use rand::{thread_rng, RngCore}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; - use crate::{constants, from_hex, Message, Secp256k1, SecretKey}; - use crate::schnorr::{KeyPair, XOnlyPublicKey, Signature}; - use crate::Error::InvalidPublicKey; - use super::*; + use crate::schnorr::{KeyPair, Signature, XOnlyPublicKey}; + use crate::Error::InvalidPublicKey; + use crate::{constants, from_hex, Message, Secp256k1, SecretKey}; #[cfg(all(not(fuzzing), any(feature = "alloc", feature = "std")))] macro_rules! hex_32 { @@ -231,25 +219,17 @@ mod tests { #[test] #[cfg(all(feature = "std", feature = "rand-std"))] fn schnor_sign_with_rng_verify() { - sign_helper(|secp, msg, seckey, mut rng| { - secp.sign_schnorr_with_rng(msg, seckey, &mut rng) - }) + sign_helper(|secp, msg, seckey, mut rng| secp.sign_schnorr_with_rng(msg, seckey, &mut rng)) } #[test] #[cfg(all(feature = "std", feature = "rand-std"))] - fn schnorr_sign_verify() { - sign_helper(|secp, msg, seckey, _| { - secp.sign_schnorr(msg, seckey) - }) - } + fn schnorr_sign_verify() { sign_helper(|secp, msg, seckey, _| secp.sign_schnorr(msg, seckey)) } #[test] #[cfg(all(feature = "std", feature = "rand-std"))] fn schnorr_sign_no_aux_rand_verify() { - sign_helper(|secp, msg, seckey, _| { - secp.sign_schnorr_no_aux_rand(msg, seckey) - }) + sign_helper(|secp, msg, seckey, _| secp.sign_schnorr_no_aux_rand(msg, seckey)) } #[cfg(all(feature = "std", feature = "rand-std"))] @@ -276,7 +256,7 @@ mod tests { #[test] #[cfg(any(feature = "alloc", feature = "std"))] - #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs + #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs fn schnorr_sign() { let secp = Secp256k1::new(); @@ -291,14 +271,13 @@ mod tests { hex_32!("02CCE08E913F22A36C5648D6405A2C7C50106E7AA2F1649E381C7F09D16B80AB"); let expected_sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap(); - let sig = secp - .sign_schnorr_with_aux_rand(&msg, &sk, &aux_rand); + let sig = secp.sign_schnorr_with_aux_rand(&msg, &sk, &aux_rand); assert_eq!(expected_sig, sig); } #[test] - #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs + #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(any(feature = "alloc", feature = "std"))] fn schnorr_verify() { let secp = Secp256k1::new(); @@ -306,9 +285,10 @@ mod tests { let hex_msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614"); let msg = Message::from_slice(&hex_msg).unwrap(); let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap(); - let pubkey = - XOnlyPublicKey::from_str("B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390") - .unwrap(); + let pubkey = XOnlyPublicKey::from_str( + "B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390", + ) + .unwrap(); assert!(secp.verify_schnorr(&sig, &msg, &pubkey).is_ok()); } @@ -398,15 +378,22 @@ mod tests { pk }; #[cfg(fuzzing)] - let pk = XOnlyPublicKey::from_slice(&[0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66]).expect("pk"); + let pk = XOnlyPublicKey::from_slice(&[ + 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, + 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe, + 0x91, 0xdd, 0xd1, 0x66, + ]) + .expect("pk"); assert_eq!( pk.to_string(), "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" ); assert_eq!( - XOnlyPublicKey::from_str("18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166") - .unwrap(), + XOnlyPublicKey::from_str( + "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" + ) + .unwrap(), pk ); @@ -454,7 +441,7 @@ mod tests { ); } - #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs + #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[test] #[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))] fn test_serde() { @@ -465,8 +452,7 @@ mod tests { let msg = Message::from_slice(&[1; 32]).unwrap(); let keypair = KeyPair::from_seckey_slice(&s, &[2; 32]).unwrap(); let aux = [3u8; 32]; - let sig = s - .sign_schnorr_with_aux_rand(&msg, &keypair, &aux); + let sig = s.sign_schnorr_with_aux_rand(&msg, &keypair, &aux); static SIG_BYTES: [u8; constants::SCHNORR_SIGNATURE_SIZE] = [ 0x14, 0xd0, 0xbf, 0x1a, 0x89, 0x53, 0x50, 0x6f, 0xb4, 0x60, 0xf5, 0x8b, 0xe1, 0x41, 0xaf, 0x76, 0x7f, 0xd1, 0x12, 0x53, 0x5f, 0xb3, 0x92, 0x2e, 0xf2, 0x17, 0x30, 0x8e, @@ -479,8 +465,8 @@ mod tests { "; static PK_BYTES: [u8; 32] = [ - 24, 132, 87, 129, 246, 49, 196, 143, 28, 151, 9, 226, 48, 146, 6, 125, 6, 131, 127, - 48, 170, 12, 208, 84, 74, 200, 135, 254, 145, 221, 209, 102 + 24, 132, 87, 129, 246, 49, 196, 143, 28, 151, 9, 226, 48, 146, 6, 125, 6, 131, 127, 48, + 170, 12, 208, 84, 74, 200, 135, 254, 145, 221, 209, 102, ]; static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"; let pk = XOnlyPublicKey::from_slice(&PK_BYTES).unwrap(); diff --git a/src/secret.rs b/src/secret.rs index 4ccd33d..07cfe31 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -15,7 +15,11 @@ //! Helpers for displaying secret values use core::fmt; -use crate::{to_hex, constants::SECRET_KEY_SIZE, key::{SecretKey, KeyPair}, ecdh::SharedSecret}; + +use crate::constants::SECRET_KEY_SIZE; +use crate::ecdh::SharedSecret; +use crate::key::{KeyPair, SecretKey}; +use crate::to_hex; macro_rules! impl_display_secret { // Default hasher exists only in standard library and not alloc ($thing:ident) => { @@ -27,7 +31,7 @@ macro_rules! impl_display_secret { const DEBUG_HASH_TAG: &[u8] = &[ 0x66, 0xa6, 0x77, 0x1b, 0x9b, 0x6d, 0xae, 0xa1, 0xb2, 0xee, 0x4e, 0x07, 0x49, 0x4a, 0xac, 0x87, 0xa9, 0xb8, 0x5b, 0x4b, 0x35, 0x02, 0xaa, 0x6d, 0x0f, 0x79, - 0xcb, 0x63, 0xe6, 0xf8, 0x66, 0x22 + 0xcb, 0x63, 0xe6, 0xf8, 0x66, 0x22, ]; // =SHA256(b"rust-secp256k1DEBUG"); let mut hasher = std::collections::hash_map::DefaultHasher::new(); @@ -37,9 +41,7 @@ macro_rules! impl_display_secret { hasher.write(&self.secret_bytes()); let hash = hasher.finish(); - f.debug_tuple(stringify!($thing)) - .field(&format_args!("#{:016x}", hash)) - .finish() + f.debug_tuple(stringify!($thing)).field(&format_args!("#{:016x}", hash)).finish() } } @@ -57,9 +59,7 @@ macro_rules! impl_display_secret { engine.input(&self.secret_bytes()); let hash = sha256::Hash::from_engine(engine); - f.debug_tuple(stringify!($thing)) - .field(&format_args!("#{:016x}", hash)) - .finish() + f.debug_tuple(stringify!($thing)).field(&format_args!("#{:016x}", hash)).finish() } } @@ -69,7 +69,7 @@ macro_rules! impl_display_secret { write!(f, "") } } - } + }; } /// Helper struct for safely printing secrets (like [`SecretKey`] value). @@ -84,7 +84,7 @@ macro_rules! impl_display_secret { /// [`Debug`]: fmt::Debug #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DisplaySecret { - secret: [u8; SECRET_KEY_SIZE] + secret: [u8; SECRET_KEY_SIZE], } impl fmt::Debug for DisplaySecret { @@ -92,9 +92,7 @@ impl fmt::Debug for DisplaySecret { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut slice = [0u8; SECRET_KEY_SIZE * 2]; let hex = to_hex(&self.secret, &mut slice).expect("fixed-size hex serializer failed"); - f.debug_tuple("DisplaySecret") - .field(&hex) - .finish() + f.debug_tuple("DisplaySecret").field(&hex).finish() } } @@ -136,9 +134,7 @@ impl SecretKey { /// # } /// ``` #[inline] - pub fn display_secret(&self) -> DisplaySecret { - DisplaySecret { secret: self.secret_bytes() } - } + pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } } } impl KeyPair { @@ -172,9 +168,7 @@ impl KeyPair { /// # } /// ``` #[inline] - pub fn display_secret(&self) -> DisplaySecret { - DisplaySecret { secret: self.secret_bytes() } - } + pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } } } impl SharedSecret { @@ -210,7 +204,5 @@ impl SharedSecret { /// # } /// ``` #[inline] - pub fn display_secret(&self) -> DisplaySecret { - DisplaySecret { secret: self.secret_bytes() } - } + pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } } } diff --git a/src/serde_util.rs b/src/serde_util.rs index a439080..e2751dd 100644 --- a/src/serde_util.rs +++ b/src/serde_util.rs @@ -1,6 +1,7 @@ use core::fmt; use core::marker::PhantomData; use core::str::{self, FromStr}; + use serde::de; /// A serde visitor that works for `T`s implementing `FromStr`. @@ -11,10 +12,7 @@ pub struct FromStrVisitor { impl FromStrVisitor { pub fn new(expectation: &'static str) -> Self { - FromStrVisitor { - expectation, - _pd: PhantomData, - } + FromStrVisitor { expectation, _pd: PhantomData } } } @@ -45,10 +43,7 @@ where Err: fmt::Display, { pub fn new(expectation: &'static str, parse_fn: F) -> Self { - BytesVisitor { - expectation, - parse_fn, - } + BytesVisitor { expectation, parse_fn } } } @@ -81,10 +76,7 @@ macro_rules! impl_tuple_visitor { E: fmt::Display, { pub fn new(expectation: &'static str, parse_fn: F) -> Self { - $thing { - expectation, - parse_fn, - } + $thing { expectation, parse_fn } } } @@ -115,7 +107,7 @@ macro_rules! impl_tuple_visitor { (self.parse_fn)(&bytes).map_err(de::Error::custom) } } - } + }; } impl_tuple_visitor!(Tuple32Visitor, 32); diff --git a/tests/serde.rs b/tests/serde.rs index ef7992d..c3c5d2b 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -5,9 +5,9 @@ extern crate bincode; extern crate cbor; extern crate secp256k1; -use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey}; #[cfg(feature = "global-context")] -use secp256k1::{Secp256k1, KeyPair}; +use secp256k1::{KeyPair, Secp256k1}; +use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey}; // Arbitrary key data. @@ -70,7 +70,8 @@ fn bincode_key_pair() { #[test] fn bincode_x_only_public_key() { - let pk = XOnlyPublicKey::from_slice(&XONLY_PK_BYTES).expect("failed to create xonly pk from slice"); + let pk = + XOnlyPublicKey::from_slice(&XONLY_PK_BYTES).expect("failed to create xonly pk from slice"); let ser = bincode::serialize(&pk).unwrap(); assert_eq!(ser, XONLY_PK_BYTES);