diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ef99eb610..88f946744 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [stable, beta, nightly, 1.29.0] + rust: [stable, beta, nightly, 1.41.1] steps: - name: Checkout Crate uses: actions/checkout@v2 @@ -46,9 +46,6 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} override: true - - name: Pin cc if rust 1.29 - if: matrix.rust == '1.29.0' - run: cargo generate-lockfile --verbose && cargo update -p cc --precise "1.0.41" --verbose - name: Running cargo env: DO_FEATURE_MATRIX: true @@ -59,7 +56,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [stable, beta, nightly] # No 1.29 because WASM requires Rust 1.30 + rust: [stable, beta, nightly] # wasm-pack doesn't support rust 1.41.1 steps: - name: Checkout Crate uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index a76f41188..7ea750c8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ documentation = "https://docs.rs/secp256k1/" description = "Rust wrapper library for Pieter Wuille's `libsecp256k1`. Implements ECDSA and BIP 340 signatures for the SECG elliptic curve group secp256k1 and related utilities." keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ] readme = "README.md" -autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330 +edition = "2018" # Should make docs.rs show all functions, even those behind non-default features [package.metadata.docs.rs] @@ -20,10 +20,10 @@ rustdoc-args = ["--cfg", "docsrs"] [features] unstable = ["recovery", "rand-std"] default = ["std"] -std = ["secp256k1-sys/std"] +std = ["alloc", "secp256k1-sys/std"] # allow use of Secp256k1::new and related API that requires an allocator -alloc = [] -bitcoin-hashes-std = ["bitcoin_hashes/std"] + alloc = ["secp256k1-sys/alloc"] + bitcoin-hashes-std = ["bitcoin_hashes/std"] rand-std = ["rand/std"] recovery = ["secp256k1-sys/recovery"] lowmemory = ["secp256k1-sys/lowmemory"] @@ -43,17 +43,17 @@ serde = { version = "1.0", default-features = false, optional = true } # You likely only want to enable these if you explicitly do not want to use "std", otherwise enable # the respective -std feature e.g., bitcoin-hashes-std bitcoin_hashes = { version = "0.10", default-features = false, optional = true } -rand = { version = "0.6", default-features = false, optional = true } +rand = { version = "0.8", default-features = false, optional = true } [dev-dependencies] -rand = "0.6" -rand_core = "0.4" +rand = "0.8" +rand_core = "0.6" serde_test = "1.0" bitcoin_hashes = "0.10" [target.wasm32-unknown-unknown.dev-dependencies] wasm-bindgen-test = "0.3" -rand = { version = "0.6", features = ["wasm-bindgen"] } +getrandom = { version = "0.2", features = ["js"] } [[example]] diff --git a/README.md b/README.md index 4e03acbf8..a2c85b226 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,7 @@ Contributions to this library are welcome. A few guidelines: * Any breaking changes must have an accompanied entry in CHANGELOG.md * No new dependencies, please. * No crypto should be implemented in Rust, with the possible exception of hash functions. Cryptographic contributions should be directed upstream to libsecp256k1. -* This library should always compile with any combination of features on **Rust 1.29**. - -## A note on Rust 1.29 support - -The build dependency `cc` might require a more recent version of the Rust compiler. -To ensure compilation with Rust 1.29.0, pin its version in your `Cargo.lock` -with `cargo update -p cc --precise 1.0.41`. If you're using `secp256k1` in a library, -to make sure it compiles in CI, you'll need to generate a lockfile first. -Example for Travis CI: -```yml -before_script: - - if [ "$TRAVIS_RUST_VERSION" == "1.29.0" ]; then - cargo generate-lockfile --verbose && cargo update -p cc --precise "1.0.41" --verbose; - fi -``` +* This library should always compile with any combination of features on **Rust 1.41.1**. ## Fuzzing diff --git a/clippy.toml b/clippy.toml index a8d2e37f1..799264ef1 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.29" +msrv = "1.41.1" diff --git a/examples/generate_keys.rs b/examples/generate_keys.rs index ae1ec2b84..171e0c39d 100644 --- a/examples/generate_keys.rs +++ b/examples/generate_keys.rs @@ -1,11 +1,11 @@ extern crate secp256k1; -use secp256k1::rand::rngs::OsRng; +use secp256k1::rand::thread_rng; use secp256k1::{PublicKey, Secp256k1, SecretKey}; fn main() { let secp = Secp256k1::new(); - let mut rng = OsRng::new().unwrap(); + let mut rng = thread_rng(); // First option: let (seckey, pubkey) = secp.generate_keypair(&mut rng); diff --git a/secp256k1-sys/Cargo.toml b/secp256k1-sys/Cargo.toml index 43da5983f..ae93625d4 100644 --- a/secp256k1-sys/Cargo.toml +++ b/secp256k1-sys/Cargo.toml @@ -13,6 +13,7 @@ keywords = [ "secp256k1", "libsecp256k1", "ffi" ] readme = "README.md" build = "build.rs" links = "rustsecp256k1_v0_5_0" +edition = "2018" # Should make docs.rs show all functions, even those behind non-default features [package.metadata.docs.rs] @@ -29,5 +30,6 @@ libc = "0.2" default = ["std"] recovery = [] lowmemory = [] -std = [] +std = ["alloc"] +alloc = [] diff --git a/secp256k1-sys/src/lib.rs b/secp256k1-sys/src/lib.rs index ebbe4830f..6f614399e 100644 --- a/secp256k1-sys/src/lib.rs +++ b/secp256k1-sys/src/lib.rs @@ -17,10 +17,7 @@ //! not be needed for most users. // Coding conventions -#![deny(non_upper_case_globals)] -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(unused_mut)] +#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case, unused_mut)] #![cfg_attr(all(not(test), not(feature = "std")), no_std)] #![cfg_attr(docsrs, feature(doc_cfg))] @@ -28,10 +25,12 @@ #[cfg(any(test, feature = "std"))] extern crate core; +#[cfg(feature = "alloc")] +extern crate alloc; + #[cfg(fuzzing)] const THIS_UNUSED_CONSTANT_IS_YOUR_WARNING_THAT_ALL_THE_CRYPTO_IN_THIS_LIB_IS_DISABLED_FOR_FUZZING: usize = 0; -#[macro_use] mod macros; pub mod types; @@ -585,11 +584,11 @@ extern "C" { /// /// The newly created secp256k1 raw context. #[no_mangle] -#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] +#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))] pub unsafe extern "C" fn rustsecp256k1_v0_5_0_context_create(flags: c_uint) -> *mut Context { use core::mem; - use std::alloc; + use crate::alloc::alloc; assert!(ALIGN_TO >= mem::align_of::()); assert!(ALIGN_TO >= mem::align_of::<&usize>()); assert!(ALIGN_TO >= mem::size_of::()); @@ -605,8 +604,8 @@ pub unsafe extern "C" fn rustsecp256k1_v0_5_0_context_create(flags: c_uint) -> * secp256k1_context_preallocated_create(ptr, flags) } -#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] +#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))] pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context { rustsecp256k1_v0_5_0_context_create(flags) } @@ -618,10 +617,10 @@ pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context { /// The pointer shouldn't be used after passing to this function, consider it as passing it to `free()`. /// #[no_mangle] -#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] +#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))] pub unsafe extern "C" fn rustsecp256k1_v0_5_0_context_destroy(ctx: *mut Context) { - use std::alloc; + use crate::alloc::alloc; secp256k1_context_preallocated_destroy(ctx); let ptr = (ctx as *mut u8).sub(ALIGN_TO); let bytes = (ptr as *mut usize).read(); @@ -629,8 +628,8 @@ pub unsafe extern "C" fn rustsecp256k1_v0_5_0_context_destroy(ctx: *mut Context) alloc::dealloc(ptr, layout); } -#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))))] +#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))))] pub unsafe fn secp256k1_context_destroy(ctx: *mut Context) { rustsecp256k1_v0_5_0_context_destroy(ctx) } diff --git a/secp256k1-sys/src/macros.rs b/secp256k1-sys/src/macros.rs index 47f10dff7..10d715e32 100644 --- a/secp256k1-sys/src/macros.rs +++ b/secp256k1-sys/src/macros.rs @@ -69,14 +69,14 @@ macro_rules! impl_array_newtype { impl PartialOrd for $thing { #[inline] - fn partial_cmp(&self, other: &$thing) -> Option<::core::cmp::Ordering> { + fn partial_cmp(&self, other: &$thing) -> Option { self[..].partial_cmp(&other[..]) } } impl Ord for $thing { #[inline] - fn cmp(&self, other: &$thing) -> ::core::cmp::Ordering { + fn cmp(&self, other: &$thing) -> core::cmp::Ordering { self[..].cmp(&other[..]) } } @@ -89,7 +89,7 @@ macro_rules! impl_array_newtype { } } - impl ::core::ops::Index for $thing { + impl core::ops::Index for $thing { type Output = $ty; #[inline] @@ -99,41 +99,41 @@ macro_rules! impl_array_newtype { } } - impl ::core::ops::Index<::core::ops::Range> for $thing { + impl core::ops::Index> for $thing { type Output = [$ty]; #[inline] - fn index(&self, index: ::core::ops::Range) -> &[$ty] { + fn index(&self, index: core::ops::Range) -> &[$ty] { let &$thing(ref dat) = self; &dat[index] } } - impl ::core::ops::Index<::core::ops::RangeTo> for $thing { + impl core::ops::Index> for $thing { type Output = [$ty]; #[inline] - fn index(&self, index: ::core::ops::RangeTo) -> &[$ty] { + fn index(&self, index: core::ops::RangeTo) -> &[$ty] { let &$thing(ref dat) = self; &dat[index] } } - impl ::core::ops::Index<::core::ops::RangeFrom> for $thing { + impl core::ops::Index> for $thing { type Output = [$ty]; #[inline] - fn index(&self, index: ::core::ops::RangeFrom) -> &[$ty] { + fn index(&self, index: core::ops::RangeFrom) -> &[$ty] { let &$thing(ref dat) = self; &dat[index] } } - impl ::core::ops::Index<::core::ops::RangeFull> for $thing { + impl core::ops::Index for $thing { type Output = [$ty]; #[inline] - fn index(&self, _: ::core::ops::RangeFull) -> &[$ty] { + fn index(&self, _: core::ops::RangeFull) -> &[$ty] { let &$thing(ref dat) = self; &dat[..] } @@ -142,7 +142,7 @@ macro_rules! impl_array_newtype { type Target = $ty; fn as_c_ptr(&self) -> *const Self::Target { if self.is_empty() { - ::core::ptr::null() + core::ptr::null() } else { self.as_ptr() } @@ -150,7 +150,7 @@ macro_rules! impl_array_newtype { fn as_mut_c_ptr(&mut self) -> *mut Self::Target { if self.is_empty() { - ::core::ptr::null::() as *mut _ + core::ptr::null::() as *mut _ } else { self.as_mut_ptr() } @@ -162,8 +162,8 @@ macro_rules! impl_array_newtype { #[macro_export] macro_rules! impl_raw_debug { ($thing:ident) => { - impl ::core::fmt::Debug for $thing { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + impl core::fmt::Debug for $thing { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { for i in self[..].iter().cloned() { write!(f, "{:02x}", i)?; } diff --git a/secp256k1-sys/src/recovery.rs b/secp256k1-sys/src/recovery.rs index 567f19dda..99bb49c54 100644 --- a/secp256k1-sys/src/recovery.rs +++ b/secp256k1-sys/src/recovery.rs @@ -15,9 +15,9 @@ //! # FFI of the recovery module -use ::types::*; -use ::core::fmt; -use {Context, Signature, NonceFn, PublicKey, CPtr}; +use crate::{Context, Signature, NonceFn, PublicKey, CPtr, impl_array_newtype}; +use crate::types::*; +use core::fmt; /// Library-internal representation of a Secp256k1 signature + recovery ID #[repr(C)] @@ -98,13 +98,10 @@ extern "C" { #[cfg(fuzzing)] mod fuzz_dummy { - use super::*; - use std::slice; + use core::slice; - use secp256k1_ec_pubkey_create; - use secp256k1_ec_pubkey_parse; - use secp256k1_ec_pubkey_serialize; - use SECP256K1_SER_COMPRESSED; + use crate::{secp256k1_ec_pubkey_create, secp256k1_ec_pubkey_parse, secp256k1_ec_pubkey_serialize, SECP256K1_SER_COMPRESSED}; + use super::*; /// Sets sig to msg32||full pk pub unsafe fn secp256k1_ecdsa_sign_recoverable( @@ -170,6 +167,6 @@ mod fuzz_dummy { 1 } } -#[cfg(fuzzing)] -pub use self::fuzz_dummy::*; +#[cfg(fuzzing)] +pub use self::fuzz_dummy::*; \ No newline at end of file diff --git a/secp256k1-sys/src/types.rs b/secp256k1-sys/src/types.rs index e257d437b..e457ec41c 100644 --- a/secp256k1-sys/src/types.rs +++ b/secp256k1-sys/src/types.rs @@ -1,5 +1,4 @@ #![allow(non_camel_case_types)] -use core::fmt; pub type c_int = i32; pub type c_uchar = u8; @@ -10,23 +9,7 @@ pub type size_t = usize; /// The way we use it makes it fine either way but this type shouldn't be used outside of the library. pub type c_char = i8; -/// This is an exact copy of -/// It should be Equivalent to C's void type when used as a pointer. -/// -/// We can replace this with `core::ffi::c_void` once we update the rustc version to >=1.30.0. -#[repr(u8)] -pub enum c_void { - #[doc(hidden)] - __variant1, - #[doc(hidden)] - __variant2, -} - -impl fmt::Debug for c_void { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("c_void") - } -} +pub use core::ffi::c_void; /// A type that is as aligned as the biggest alignment for fundamental types in C /// since C11 that means as aligned as `max_align_t` is. @@ -45,8 +28,8 @@ impl AlignedType { pub const ZERO: AlignedType = AlignedType([0u8; 16]); } -#[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -pub(crate) const ALIGN_TO: usize = ::core::mem::align_of::(); +#[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] +pub(crate) const ALIGN_TO: usize = core::mem::align_of::(); #[cfg(test)] mod tests { @@ -54,7 +37,7 @@ mod tests { use std::any::TypeId; use std::mem; use std::os::raw; - use {types, AlignedType}; + use crate::{types, AlignedType}; #[test] fn verify_types() { diff --git a/src/context.rs b/src/context.rs index b7568778a..b5b552536 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,24 +1,23 @@ use core::marker::PhantomData; use core::mem::ManuallyDrop; -use ffi::{self, CPtr, types::AlignedType}; -use ffi::types::{c_uint, c_void}; -use Error; -use Secp256k1; -#[cfg(any(feature = "std", feature = "alloc"))] -#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +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::*; #[cfg(all(feature = "global-context", feature = "std"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "global-context", feature = "std"))))] /// Module implementing a singleton pattern for a global `Secp256k1` context. pub mod global { - #[cfg(feature = "rand-std")] - use rand; use std::ops::Deref; use std::sync::Once; - use {Secp256k1, All}; + + use crate::{All, Secp256k1}; /// Proxy struct for global `SECP256K1` context. #[derive(Debug, Copy, Clone)] @@ -104,13 +103,16 @@ mod private { impl<'buf> Sealed for SignOnlyPreallocated<'buf> {} } -#[cfg(any(feature = "std", feature = "alloc"))] -#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc"))))] mod alloc_only { - #[cfg(feature = "std")] - use std::alloc; - #[cfg(not(feature = "std"))] - use alloc::alloc; + 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}; #[cfg(feature = "rand-std")] use rand; @@ -119,8 +121,7 @@ mod alloc_only { impl private::Sealed for All {} impl private::Sealed for VerifyOnly {} - use super::*; - const ALIGN_TO: usize = ::core::mem::align_of::(); + const ALIGN_TO: usize = core::mem::align_of::(); /// Represents the set of capabilities needed for signing. #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] diff --git a/src/ecdh.rs b/src/ecdh.rs index 387716cb0..3ebf9481b 100644 --- a/src/ecdh.rs +++ b/src/ecdh.rs @@ -15,14 +15,11 @@ //! Support for shared secret computations. //! -use core::{ptr, str}; -use core::borrow::Borrow; +use core::{borrow::Borrow, ptr, str}; -use {Error, from_hex}; -use key::{SecretKey, PublicKey}; -use ffi::{self, CPtr}; use secp256k1_sys::types::{c_int, c_uchar, c_void}; -use constants; + +use crate::{constants, Error, ffi::{self, CPtr}, key::{PublicKey, SecretKey}}; // The logic for displaying shared secrets relies on this (see `secret.rs`). const SHARED_SECRET_SIZE: usize = constants::SECRET_KEY_SIZE; @@ -97,7 +94,7 @@ impl str::FromStr for SharedSecret { type Err = Error; fn from_str(s: &str) -> Result { let mut res = [0u8; SHARED_SECRET_SIZE]; - match from_hex(s, &mut res) { + match crate::from_hex(s, &mut res) { Ok(SHARED_SECRET_SIZE) => Ok(SharedSecret::from_bytes(res)), _ => Err(Error::InvalidSharedSecret) } @@ -177,7 +174,7 @@ impl ::serde::Serialize for SharedSecret { fn serialize(&self, s: S) -> Result { if s.is_human_readable() { let mut buf = [0u8; SHARED_SECRET_SIZE * 2]; - s.serialize_str(::to_hex(&self.0, &mut buf).expect("fixed-size hex serialization")) + s.serialize_str(crate::to_hex(&self.0, &mut buf).expect("fixed-size hex serialization")) } else { s.serialize_bytes(&self.as_ref()[..]) } @@ -204,13 +201,13 @@ impl<'de> ::serde::Deserialize<'de> for SharedSecret { #[cfg(test)] #[allow(unused_imports)] mod tests { - use super::*; use rand::thread_rng; - use super::super::Secp256k1; - #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; + use crate::Secp256k1; + use super::SharedSecret; + #[test] #[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))] fn ecdh() { @@ -230,7 +227,7 @@ 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(), 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]; @@ -244,7 +241,8 @@ mod tests { #[cfg(not(fuzzing))] #[cfg(all(feature="rand-std", feature = "std", feature = "bitcoin_hashes"))] fn bitcoin_hashes_and_sys_generate_same_secret() { - use hashes::{sha256, Hash, HashEngine}; + use bitcoin_hashes::{sha256, Hash, HashEngine}; + use crate::ecdh::shared_secret_point; let s = Secp256k1::signing_only(); let (sk1, _) = s.generate_keypair(&mut thread_rng()); @@ -292,11 +290,13 @@ mod tests { #[cfg(all(test, feature = "unstable"))] mod benches { - use rand::thread_rng; use test::{Bencher, black_box}; + use rand::thread_rng; + + use crate::Secp256k1; + use super::SharedSecret; - use super::super::Secp256k1; #[bench] pub fn bench_ecdh(bh: &mut Bencher) { diff --git a/src/ecdsa/mod.rs b/src/ecdsa/mod.rs index 91429b4f5..8c0f8145f 100644 --- a/src/ecdsa/mod.rs +++ b/src/ecdsa/mod.rs @@ -2,8 +2,8 @@ use core::{fmt, str, ops, ptr, mem}; -use {Signing, Verification, Message, PublicKey, Secp256k1, SecretKey, from_hex, Error, ffi}; -use ffi::CPtr; +use crate::{Signing, Verification, Message, PublicKey, Secp256k1, SecretKey, from_hex, Error, ffi}; +use crate::ffi::CPtr; #[cfg(feature = "recovery")] mod recovery; @@ -13,7 +13,7 @@ mod recovery; pub use self::recovery::{RecoveryId, RecoverableSignature}; #[cfg(feature = "global-context")] -use SECP256K1; +use crate::SECP256K1; /// An ECDSA signature #[derive(Copy, Clone, PartialEq, Eq, Hash)] @@ -120,7 +120,7 @@ impl SerializedSignature { /// Convert the serialized signature into the Signature struct. /// (This DER deserializes it) pub fn to_signature(&self) -> Result { - Signature::from_der(&self) + Signature::from_der(self) } /// Create a SerializedSignature from a Signature. @@ -304,8 +304,8 @@ impl From for Signature { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for Signature { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for Signature { + fn serialize(&self, s: S) -> Result { if s.is_human_readable() { s.collect_str(self) } else { @@ -316,14 +316,14 @@ impl ::serde::Serialize for Signature { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for Signature { - fn deserialize>(d: D) -> Result { +impl<'de> serde::Deserialize<'de> for Signature { + fn deserialize>(d: D) -> Result { if d.is_human_readable() { - d.deserialize_str(::serde_util::FromStrVisitor::new( + d.deserialize_str(crate::serde_util::FromStrVisitor::new( "a hex string representing a DER encoded Signature" )) } else { - d.deserialize_bytes(::serde_util::BytesVisitor::new( + d.deserialize_bytes(crate::serde_util::BytesVisitor::new( "raw byte stream, that represents a DER encoded Signature", Signature::from_der )) @@ -467,12 +467,11 @@ impl Secp256k1 { /// /// ```rust /// # #[cfg(all(feature = "std", feature = "rand-std"))] { - /// # use secp256k1::rand::rngs::OsRng; + /// # use secp256k1::rand::thread_rng; /// # use secp256k1::{Secp256k1, Message, Error}; /// # /// # let secp = Secp256k1::new(); - /// # let mut rng = OsRng::new().expect("OsRng"); - /// # let (secret_key, public_key) = secp.generate_keypair(&mut rng); + /// # let (secret_key, public_key) = secp.generate_keypair(&mut thread_rng()); /// # /// let message = Message::from_slice(&[0xab; 32]).expect("32 bytes"); /// let sig = secp.sign(&message, &secret_key); @@ -496,12 +495,11 @@ impl Secp256k1 { /// /// ```rust /// # #[cfg(all(feature = "std", feature = "rand-std"))] { - /// # use secp256k1::rand::rngs::OsRng; + /// # use secp256k1::rand::thread_rng; /// # use secp256k1::{Secp256k1, Message, Error}; /// # /// # let secp = Secp256k1::new(); - /// # let mut rng = OsRng::new().expect("OsRng"); - /// # let (secret_key, public_key) = secp.generate_keypair(&mut rng); + /// # let (secret_key, public_key) = secp.generate_keypair(&mut thread_rng()); /// # /// let message = Message::from_slice(&[0xab; 32]).expect("32 bytes"); /// let sig = secp.sign_ecdsa(&message, &secret_key); diff --git a/src/ecdsa/recovery.rs b/src/ecdsa/recovery.rs index 02e0c83b1..d2c471ec4 100644 --- a/src/ecdsa/recovery.rs +++ b/src/ecdsa/recovery.rs @@ -18,12 +18,10 @@ //! use core::ptr; -use key; +use crate::{key, Secp256k1, Message, Error, Verification, Signing, ecdsa::Signature}; use super::ffi as super_ffi; use self::super_ffi::CPtr; -use ffi::recovery as ffi; -use super::*; -use {Verification, Secp256k1, Signing, Message}; +use crate::ffi::recovery as ffi; /// A tag used for recovering the public key from a compact signature. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -38,7 +36,7 @@ impl RecoveryId { /// Allows library users to create valid recovery IDs from i32. pub fn from_i32(id: i32) -> Result { match id { - 0 | 1 | 2 | 3 => Ok(RecoveryId(id)), + 0..=3 => Ok(RecoveryId(id)), _ => Err(Error::InvalidRecoveryId) } } @@ -127,7 +125,7 @@ impl RecoverableSignature { #[cfg(feature = "global-context")] #[cfg_attr(docsrs, doc(cfg(feature = "global-context")))] pub fn recover(&self, msg: &Message) -> Result { - SECP256K1.recover_ecdsa(msg, self) + crate::SECP256K1.recover_ecdsa(msg, self) } } @@ -235,9 +233,10 @@ impl Secp256k1 { #[cfg(test)] #[allow(unused_imports)] mod tests { - use super::*; use rand::{RngCore, thread_rng}; - use key::SecretKey; + + use crate::{Error, SecretKey, Secp256k1, Message}; + use super::{RecoveryId, RecoverableSignature}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/src/key.rs b/src/key.rs index 1ebc3cb97..6ddbf08a1 100644 --- a/src/key.rs +++ b/src/key.rs @@ -16,22 +16,19 @@ //! Public and secret keys. //! -#[cfg(any(test, feature = "rand"))] use rand::Rng; - use core::{fmt, ptr, str}; use core::ops::BitXor; +use core::convert::TryFrom; -use super::{from_hex, Secp256k1}; -use super::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey}; -use ::{Signing}; -use Verification; -use constants; -use ffi::{self, CPtr}; +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 = "global-context")] -use {Message, ecdsa, SECP256K1}; +use crate::{Message, ecdsa, SECP256K1}; #[cfg(all(feature = "global-context", feature = "rand-std"))] -use schnorr; +use crate::schnorr; /// Secret 256-bit key used as `x` in an ECDSA signature. /// @@ -122,7 +119,7 @@ impl str::FromStr for PublicKey { } #[cfg(any(test, feature = "rand"))] -fn random_32_bytes(rng: &mut R) -> [u8; 32] { +fn random_32_bytes(rng: &mut R) -> [u8; 32] { let mut ret = [0u8; 32]; rng.fill_bytes(&mut ret); ret @@ -142,7 +139,7 @@ impl SecretKey { #[inline] #[cfg(any(test, feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] - pub fn new(rng: &mut R) -> SecretKey { + pub fn new(rng: &mut R) -> SecretKey { let mut data = random_32_bytes(rng); unsafe { while ffi::secp256k1_ec_seckey_verify( @@ -166,9 +163,8 @@ impl SecretKey { /// ``` #[inline] pub fn from_slice(data: &[u8])-> Result { - match data.len() { - constants::SECRET_KEY_SIZE => { - let mut ret = [0u8; constants::SECRET_KEY_SIZE]; + match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) { + Ok(data) => { unsafe { if ffi::secp256k1_ec_seckey_verify( ffi::secp256k1_context_no_precomp, @@ -178,10 +174,9 @@ impl SecretKey { return Err(InvalidSecretKey); } } - ret[..].copy_from_slice(data); - Ok(SecretKey(ret)) + Ok(SecretKey(data)) } - _ => Err(InvalidSecretKey) + Err(_) => Err(InvalidSecretKey) } } @@ -321,11 +316,11 @@ impl SecretKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for SecretKey { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for SecretKey { + fn serialize(&self, s: S) -> Result { if s.is_human_readable() { let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2]; - s.serialize_str(::to_hex(&self.0, &mut buf).expect("fixed-size hex serialization")) + s.serialize_str(crate::to_hex(&self.0, &mut buf).expect("fixed-size hex serialization")) } else { s.serialize_bytes(&self[..]) } @@ -334,8 +329,8 @@ impl ::serde::Serialize for SecretKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for SecretKey { - fn deserialize>(d: D) -> Result { +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" @@ -462,39 +457,32 @@ impl PublicKey { /// represented by only a single bit, as x determines it up to one bit. pub fn serialize(&self) -> [u8; constants::PUBLIC_KEY_SIZE] { let mut ret = [0u8; constants::PUBLIC_KEY_SIZE]; - - unsafe { - let mut ret_len = constants::PUBLIC_KEY_SIZE as usize; - let err = ffi::secp256k1_ec_pubkey_serialize( - ffi::secp256k1_context_no_precomp, - ret.as_mut_c_ptr(), - &mut ret_len, - self.as_c_ptr(), - ffi::SECP256K1_SER_COMPRESSED, - ); - debug_assert_eq!(err, 1); - debug_assert_eq!(ret_len, ret.len()); - } + self.serialize_internal(&mut ret, ffi::SECP256K1_SER_COMPRESSED); ret } + #[inline] /// Serializes the key as a byte-encoded pair of values, in uncompressed form. pub fn serialize_uncompressed(&self) -> [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] { let mut ret = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]; + self.serialize_internal(&mut ret, ffi::SECP256K1_SER_UNCOMPRESSED); + ret + } - unsafe { - let mut ret_len = constants::UNCOMPRESSED_PUBLIC_KEY_SIZE as usize; - let err = ffi::secp256k1_ec_pubkey_serialize( + #[inline(always)] + fn serialize_internal(&self, ret: &mut [u8], flag: c_uint) { + let mut ret_len = ret.len(); + let res = unsafe { + ffi::secp256k1_ec_pubkey_serialize( ffi::secp256k1_context_no_precomp, ret.as_mut_c_ptr(), &mut ret_len, self.as_c_ptr(), - ffi::SECP256K1_SER_UNCOMPRESSED, - ); - debug_assert_eq!(err, 1); - debug_assert_eq!(ret_len, ret.len()); - } - ret + flag, + ) + }; + debug_assert_eq!(res, 1); + debug_assert_eq!(ret_len, ret.len()); } #[inline] @@ -671,8 +659,8 @@ impl From for PublicKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for PublicKey { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for PublicKey { + fn serialize(&self, s: S) -> Result { if s.is_human_readable() { s.collect_str(self) } else { @@ -683,8 +671,8 @@ impl ::serde::Serialize for PublicKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for PublicKey { - fn deserialize>(d: D) -> Result { +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" @@ -699,13 +687,13 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey { } impl PartialOrd for PublicKey { - fn partial_cmp(&self, other: &PublicKey) -> Option<::core::cmp::Ordering> { + fn partial_cmp(&self, other: &PublicKey) -> Option { self.serialize().partial_cmp(&other.serialize()) } } impl Ord for PublicKey { - fn cmp(&self, other: &PublicKey) -> ::core::cmp::Ordering { + fn cmp(&self, other: &PublicKey) -> core::cmp::Ordering { self.serialize().cmp(&other.serialize()) } } @@ -837,7 +825,7 @@ impl KeyPair { #[inline] #[cfg(any(test, feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] - pub fn new(secp: &Secp256k1, rng: &mut R) -> KeyPair { + pub fn new(secp: &Secp256k1, rng: &mut R) -> KeyPair { let mut random_32_bytes = || { let mut ret = [0u8; 32]; rng.fill_bytes(&mut ret); @@ -992,11 +980,11 @@ impl str::FromStr for KeyPair { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for KeyPair { - fn serialize(&self, s: S) -> Result { +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(::to_hex(&self.secret_bytes(), &mut buf) + s.serialize_str(crate::to_hex(&self.secret_bytes(), &mut buf) .expect("fixed-size hex serialization")) } else { s.serialize_bytes(&self.0[..]) @@ -1006,8 +994,8 @@ impl ::serde::Serialize for KeyPair { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for KeyPair { - fn deserialize>(d: D) -> Result { +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" @@ -1360,7 +1348,7 @@ impl fmt::Display for InvalidParityValue { #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl ::std::error::Error for InvalidParityValue {} +impl std::error::Error for InvalidParityValue {} impl From for Error { fn from(error: InvalidParityValue) -> Self { @@ -1371,8 +1359,8 @@ impl From for Error { /// The parity is serialized as `u8` - `0` for even, `1` for odd. #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for Parity { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for Parity { + fn serialize(&self, s: S) -> Result { s.serialize_u8(self.to_u8()) } } @@ -1380,11 +1368,11 @@ impl ::serde::Serialize for Parity { /// The parity is deserialized as `u8` - `0` for even, `1` for odd. #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for Parity { - fn deserialize>(d: D) -> Result { +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; @@ -1393,7 +1381,7 @@ 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; @@ -1425,8 +1413,8 @@ impl From for XOnlyPublicKey { } } -impl From<::key::PublicKey> for XOnlyPublicKey { - fn from(src: ::key::PublicKey) -> XOnlyPublicKey { +impl From for XOnlyPublicKey { + fn from(src: PublicKey) -> XOnlyPublicKey { unsafe { let mut pk = ffi::XOnlyPublicKey::new(); assert_eq!( @@ -1445,8 +1433,8 @@ impl From<::key::PublicKey> for XOnlyPublicKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for XOnlyPublicKey { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for XOnlyPublicKey { + fn serialize(&self, s: S) -> Result { if s.is_human_readable() { s.collect_str(self) } else { @@ -1457,8 +1445,8 @@ impl ::serde::Serialize for XOnlyPublicKey { #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for XOnlyPublicKey { - fn deserialize>(d: D) -> Result { +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" @@ -1486,8 +1474,7 @@ 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 key::KeyPair; - use key::SecretKey; + use crate::key::{KeyPair, SecretKey}; #[allow(missing_docs)] pub fn serialize(key: &KeyPair, serializer: S) -> Result @@ -1505,7 +1492,7 @@ pub mod serde_keypair { let secret_key = SecretKey::deserialize(deserializer)?; Ok(KeyPair::from_secret_key( - &::SECP256K1, + &crate::SECP256K1, &secret_key, )) } @@ -1514,23 +1501,18 @@ pub mod serde_keypair { #[cfg(test)] #[allow(unused_imports)] mod test { - use super::*; - - #[cfg(any(feature = "alloc", feature = "std"))] - use core::iter; use core::str::FromStr; #[cfg(any(feature = "alloc", feature = "std"))] - use rand::{Error, ErrorKind, RngCore, thread_rng}; - #[cfg(any(feature = "alloc", feature = "std"))] - use rand_core::impls; - - use constants; - use Error::{InvalidPublicKey, InvalidSecretKey}; + use rand::{Error, RngCore, thread_rng, rngs::mock::StepRng}; #[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 crate::Error::{InvalidPublicKey, InvalidSecretKey}; + macro_rules! hex { ($hex:expr) => ({ let mut result = vec![0; $hex.len() / 2]; @@ -1601,7 +1583,6 @@ mod test { #[test] #[cfg(any(feature = "alloc", feature = "std"))] fn test_out_of_range() { - struct BadRng(u8); impl RngCore for BadRng { fn next_u32(&mut self) -> u32 { unimplemented!() } @@ -1694,28 +1675,9 @@ mod test { #[test] #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] fn test_debug_output() { - use to_hex; - - struct DumbRng(u32); - impl RngCore for DumbRng { - fn next_u32(&mut self) -> u32 { - self.0 = self.0.wrapping_add(1); - self.0 - } - fn next_u64(&mut self) -> u64 { - self.next_u32() as u64 - } - fn fill_bytes(&mut self, dest: &mut [u8]) { - impls::fill_bytes_via_next(self, dest); - } - - fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), Error> { - Err(Error::new(ErrorKind::Unavailable, "not implemented")) - } - } let s = Secp256k1::new(); - let (sk, _) = s.generate_keypair(&mut DumbRng(0)); + let (sk, _) = s.generate_keypair(&mut StepRng::new(1, 1)); assert_eq!(&format!("{:?}", sk), "SecretKey(#d3e0c51a23169bb5)"); @@ -1781,7 +1743,7 @@ mod test { assert!(PublicKey::from_str("0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1").is_err()); assert!(PublicKey::from_str("xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1").is_err()); - let long_str: String = iter::repeat('a').take(1024 * 1024).collect(); + let long_str: String = core::iter::repeat('a').take(1024 * 1024).collect(); assert!(SecretKey::from_str(&long_str).is_err()); assert!(PublicKey::from_str(&long_str).is_err()); } @@ -1792,26 +1754,9 @@ mod test { #[cfg(not(fuzzing))] #[cfg(any(feature = "alloc", feature = "std"))] fn test_pubkey_serialize() { - struct DumbRng(u32); - impl RngCore for DumbRng { - fn next_u32(&mut self) -> u32 { - self.0 = self.0.wrapping_add(1); - self.0 - } - fn next_u64(&mut self) -> u64 { - self.next_u32() as u64 - } - fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), Error> { - Err(Error::new(ErrorKind::Unavailable, "not implemented")) - } - - fn fill_bytes(&mut self, dest: &mut [u8]) { - impls::fill_bytes_via_next(self, dest); - } - } let s = Secp256k1::new(); - let (_, pk1) = s.generate_keypair(&mut DumbRng(0)); + 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()[..], @@ -2095,7 +2040,7 @@ mod test { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_test::{Configure, Token, assert_tokens}; use super::serde_keypair; - use key::KeyPair; + use crate::key::KeyPair; // Normally users would derive the serde traits, but we can't easily enable the serde macros // here, so they are implemented manually to be able to test the behaviour. @@ -2125,7 +2070,7 @@ mod test { 01010101010101010001020304050607ffff0000ffff00006363636363636363\ "; - let sk = KeyPairWrapper(KeyPair::from_seckey_slice(&::SECP256K1, &SK_BYTES).unwrap()); + let sk = KeyPairWrapper(KeyPair::from_seckey_slice(&crate::SECP256K1, &SK_BYTES).unwrap()); assert_tokens(&sk.compact(), &[Token::BorrowedBytes(&SK_BYTES[..])]); assert_tokens(&sk.compact(), &[Token::Bytes(&SK_BYTES)]); diff --git a/src/lib.rs b/src/lib.rs index 0fcb5c2ef..de3b7a399 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,8 +47,7 @@ //! use secp256k1::hashes::sha256; //! //! let secp = Secp256k1::new(); -//! let mut rng = OsRng::new().expect("OsRng"); -//! let (secret_key, public_key) = secp.generate_keypair(&mut rng); +//! let (secret_key, public_key) = secp.generate_keypair(&mut OsRng); //! let message = Message::from_hashed_data::("Hello World!".as_bytes()); //! //! let sig = secp.sign_ecdsa(&message, &secret_key); @@ -150,47 +149,19 @@ //! * `bitcoin_hashes` - enables interaction with the `bitcoin-hashes` crate (e.g. conversions). // Coding conventions -#![deny(non_upper_case_globals)] -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(unused_mut)] -#![warn(missing_docs)] -#![warn(missing_copy_implementations)] -#![warn(missing_debug_implementations)] - +#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)] +#![warn(missing_docs, missing_copy_implementations, missing_debug_implementations)] #![cfg_attr(all(not(test), not(feature = "std")), no_std)] #![cfg_attr(all(test, feature = "unstable"), feature(test))] #![cfg_attr(docsrs, feature(doc_cfg))] -#[macro_use] -pub extern crate secp256k1_sys; -pub use secp256k1_sys as ffi; - -#[cfg(feature = "bitcoin_hashes")] -#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] -pub extern crate bitcoin_hashes as hashes; -#[cfg(all(test, feature = "unstable"))] -extern crate test; -#[cfg(any(test, feature = "rand"))] -#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] -pub extern crate rand; -#[cfg(any(test))] -extern crate rand_core; -#[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -pub extern crate serde; -#[cfg(all(test, feature = "serde"))] -extern crate serde_test; -#[cfg(any(test, feature = "rand"))] -use rand::Rng; -#[cfg(any(test, feature = "std"))] -extern crate core; -#[cfg(all(test, target_arch = "wasm32"))] -extern crate wasm_bindgen_test; #[cfg(feature = "alloc")] extern crate alloc; - +#[cfg(any(test, feature = "std"))] +extern crate core; +#[cfg(all(test, feature = "unstable"))] +extern crate test; #[macro_use] mod macros; @@ -206,18 +177,28 @@ pub mod schnorr; #[cfg(feature = "serde")] mod serde_util; -pub use key::*; -pub use context::*; -use core::marker::PhantomData; -use core::{mem, fmt, str}; -use ffi::{CPtr, types::AlignedType}; +#[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; +#[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::*; #[cfg(feature = "global-context")] #[cfg_attr(docsrs, doc(cfg(feature = "global-context")))] pub use context::global::SECP256K1; +use core::{fmt, str, mem, marker::PhantomData}; +use crate::ffi::{CPtr, impl_array_newtype, types::AlignedType}; #[cfg(feature = "bitcoin_hashes")] -use hashes::Hash; +use crate::hashes::Hash; // Backwards compatible changes /// Schnorr Signature related methods. @@ -225,13 +206,13 @@ use hashes::Hash; pub mod schnorrsig { #[deprecated(since = "0.21.0", note = "Use crate::XOnlyPublicKey instead.")] /// backwards compatible re-export of xonly key - pub type PublicKey = super::XOnlyPublicKey; + pub type PublicKey = crate::key::XOnlyPublicKey; /// backwards compatible re-export of keypair #[deprecated(since = "0.21.0", note = "Use crate::KeyPair instead.")] - pub type KeyPair = super::KeyPair; + pub type KeyPair = crate::key::KeyPair; /// backwards compatible re-export of schnorr signatures #[deprecated(since = "0.21.0", note = "Use schnorr::Signature instead.")] - pub type Signature = super::schnorr::Signature; + pub type Signature = crate::schnorr::Signature; } #[deprecated(since = "0.21.0", note = "Use ecdsa::Signature instead.")] @@ -470,7 +451,7 @@ impl Secp256k1 { /// [libsecp256k1](https://github.com/bitcoin-core/secp256k1/commit/d2275795ff22a6f4738869f5528fbbb61738aa48). #[cfg(any(test, feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] - pub fn randomize(&mut self, rng: &mut R) { + pub fn randomize(&mut self, rng: &mut R) { let mut seed = [0u8; 32]; rng.fill_bytes(&mut seed); self.seeded_randomize(&seed); @@ -501,7 +482,7 @@ impl Secp256k1 { #[inline] #[cfg(any(test, feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand")))] - pub fn generate_keypair(&self, rng: &mut R) + 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); @@ -513,7 +494,7 @@ impl Secp256k1 { #[inline] #[cfg(all(feature = "global-context", feature = "rand"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "global-context", feature = "rand"))))] -pub fn generate_keypair(rng: &mut R) -> (key::SecretKey, key::PublicKey) { +pub fn generate_keypair(rng: &mut R) -> (key::SecretKey, key::PublicKey) { SECP256K1.generate_keypair(rng) } @@ -569,14 +550,18 @@ fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> { #[cfg(test)] mod tests { - use super::*; + use std::marker::PhantomData; + use std::str::FromStr; + use rand::{RngCore, thread_rng}; - use core::str::FromStr; - use ffi::types::AlignedType; #[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}; + macro_rules! hex { ($hex:expr) => ({ let mut result = vec![0; $hex.len() / 2]; @@ -1038,6 +1023,7 @@ mod tests { #[cfg(feature = "global-context")] #[test] fn test_global_context() { + use crate::SECP256K1; let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641"); let sk = SecretKey::from_slice(&sk_data).unwrap(); let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d"); @@ -1054,8 +1040,7 @@ mod tests { #[cfg(feature = "bitcoin_hashes")] #[test] fn test_from_hash() { - use hashes; - use hashes::Hash; + use crate::hashes::{self, Hash}; let test_bytes = "Hello world!".as_bytes(); @@ -1079,40 +1064,19 @@ mod tests { #[cfg(all(test, feature = "unstable"))] mod benches { - use rand::{thread_rng, RngCore}; use test::{Bencher, black_box}; - use super::{Secp256k1, Message}; + use rand::{RngCore, thread_rng}; + use rand::rngs::mock::StepRng; + + use super::{Message, Secp256k1}; #[bench] #[cfg(any(feature = "alloc", feature = "std"))] pub fn generate(bh: &mut Bencher) { - struct CounterRng(u64); - impl RngCore for CounterRng { - fn next_u32(&mut self) -> u32 { - self.next_u64() as u32 - } - - fn next_u64(&mut self) -> u64 { - self.0 += 1; - self.0 - } - - fn fill_bytes(&mut self, dest: &mut [u8]) { - for chunk in dest.chunks_mut(64/8) { - let rand: [u8; 64/8] = unsafe {std::mem::transmute(self.next_u64())}; - chunk.copy_from_slice(&rand[..chunk.len()]); - } - } - - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { - Ok(self.fill_bytes(dest)) - } - } - let s = Secp256k1::new(); - let mut r = CounterRng(0); + let mut r = StepRng::new(1, 1); bh.iter( || { let (sk, pk) = s.generate_keypair(&mut r); black_box(sk); diff --git a/src/macros.rs b/src/macros.rs index 9dad59da7..6cd1d66a9 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -15,8 +15,8 @@ macro_rules! impl_pretty_debug { ($thing:ident) => { - impl ::core::fmt::Debug for $thing { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + impl core::fmt::Debug for $thing { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}(", stringify!($thing))?; for i in &self[..] { write!(f, "{:02x}", i)?; diff --git a/src/schnorr.rs b/src/schnorr.rs index 9c745e4b9..506156822 100644 --- a/src/schnorr.rs +++ b/src/schnorr.rs @@ -2,19 +2,17 @@ //! Support for Schnorr signatures. //! -#[cfg(any(test, feature = "rand-std"))] -use rand::thread_rng; +use core::{fmt, ptr, str}; + #[cfg(any(test, feature = "rand"))] use rand::{CryptoRng, Rng}; -use super::{from_hex, Error}; -use core::{fmt, ptr, str}; -use ffi::{self, CPtr}; -use {constants, Secp256k1}; -use {Message, Signing, Verification, KeyPair, XOnlyPublicKey}; +use crate::{constants, Error, from_hex, Message, Secp256k1, Signing, Verification}; +use crate::key::{KeyPair, XOnlyPublicKey}; +use crate::ffi::{self, CPtr, impl_array_newtype}; #[cfg(all(feature = "global-context", feature = "rand-std"))] -use SECP256K1; +use crate::SECP256K1; /// Represents a Schnorr signature. pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]); @@ -22,9 +20,8 @@ impl_array_newtype!(Signature, u8, constants::SCHNORR_SIGNATURE_SIZE); impl_pretty_debug!(Signature); #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl ::serde::Serialize for Signature { - fn serialize(&self, s: S) -> Result { +impl serde::Serialize for Signature { + fn serialize(&self, s: S) -> Result { if s.is_human_readable() { s.collect_str(self) } else { @@ -34,9 +31,8 @@ impl ::serde::Serialize for Signature { } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de> ::serde::Deserialize<'de> for Signature { - fn deserialize>(d: D) -> Result { +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" @@ -139,8 +135,7 @@ impl Secp256k1 { #[cfg(any(test, feature = "rand-std"))] #[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))] pub fn sign_schnorr(&self, msg: &Message, keypair: &KeyPair) -> Signature { - let mut rng = thread_rng(); - self.sign_schnorr_with_rng(msg, keypair, &mut rng) + self.sign_schnorr_with_rng(msg, keypair, &mut rand::thread_rng()) } /// Create a schnorr signature without using any auxiliary random data. @@ -276,21 +271,16 @@ impl Secp256k1 { #[cfg(test)] #[allow(unused_imports)] mod tests { - use std::iter; - use std::str::FromStr; - - use rand::rngs::ThreadRng; - use rand::{Error, ErrorKind, RngCore, thread_rng}; - use rand_core::impls; - - use {constants, Error::InvalidPublicKey, from_hex, Message, Secp256k1, SecretKey}; - - #[cfg(any(feature = "std", feature = "alloc"))] - use All; + use core::str::FromStr; + use rand::{RngCore, rngs::ThreadRng, thread_rng}; #[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::*; #[cfg(all(not(fuzzing), any(feature = "alloc", feature = "std")))] @@ -338,7 +328,7 @@ mod tests { #[cfg(all(feature = "std", feature = "rand-std"))] fn sign_helper( - sign: fn(&Secp256k1, &Message, &KeyPair, &mut ThreadRng) -> Signature, + sign: fn(&Secp256k1, &Message, &KeyPair, &mut ThreadRng) -> Signature, ) { let secp = Secp256k1::new(); @@ -429,8 +419,8 @@ mod tests { let keypair = KeyPair::from_seckey_str(&secp, sk_str).unwrap(); let sk = SecretKey::from_keypair(&keypair); assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk); - let pk = ::key::PublicKey::from_keypair(&keypair); - assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk); + let pk = crate::key::PublicKey::from_keypair(&keypair); + assert_eq!(crate::key::PublicKey::from_secret_key(&secp, &sk), pk); let (xpk, _parity) = keypair.x_only_public_key(); assert_eq!(XOnlyPublicKey::from(pk), xpk); } @@ -515,7 +505,7 @@ mod tests { ) .is_err()); - let long_str: String = iter::repeat('a').take(1024 * 1024).collect(); + let long_str: String = core::iter::repeat('a').take(1024 * 1024).collect(); assert!(XOnlyPublicKey::from_str(&long_str).is_err()); } @@ -525,26 +515,9 @@ mod tests { #[cfg(not(fuzzing))] #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] fn test_pubkey_serialize() { - struct DumbRng(u32); - impl RngCore for DumbRng { - fn next_u32(&mut self) -> u32 { - self.0 = self.0.wrapping_add(1); - self.0 - } - fn next_u64(&mut self) -> u64 { - self.next_u32() as u64 - } - fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), Error> { - Err(Error::new(ErrorKind::Unavailable, "not implemented")) - } - - fn fill_bytes(&mut self, dest: &mut [u8]) { - impls::fill_bytes_via_next(self, dest); - } - } - + use rand::rngs::mock::StepRng; let secp = Secp256k1::new(); - let kp = KeyPair::new(&secp, &mut DumbRng(0)); + let kp = KeyPair::new(&secp, &mut StepRng::new(1, 1)); let (pk, _parity) = kp.x_only_public_key(); assert_eq!( &pk.serialize()[..], diff --git a/src/secret.rs b/src/secret.rs index 7ee08ac04..4f0aaf295 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -14,25 +14,23 @@ //! Helpers for displaying secret values -use ::core::fmt; -use ::{SecretKey, KeyPair, to_hex}; -use ecdh::SharedSecret; -use constants::SECRET_KEY_SIZE; - +use core::fmt; +use crate::{to_hex, constants::SECRET_KEY_SIZE, key::{SecretKey, KeyPair}, ecdh::SharedSecret}; macro_rules! impl_display_secret { // Default hasher exists only in standard library and not alloc ($thing:ident) => { #[cfg(feature = "std")] - impl ::core::fmt::Debug for $thing { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use ::core::hash::Hasher; + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + impl core::fmt::Debug for $thing { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + use core::hash::Hasher; 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 ]; // =SHA256(b"rust-secp256k1DEBUG"); - let mut hasher = ::std::collections::hash_map::DefaultHasher::new(); + let mut hasher = std::collections::hash_map::DefaultHasher::new(); hasher.write(DEBUG_HASH_TAG); hasher.write(DEBUG_HASH_TAG); @@ -48,7 +46,7 @@ macro_rules! impl_display_secret { #[cfg(all(not(feature = "std"), feature = "bitcoin_hashes"))] impl ::core::fmt::Debug for $thing { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - use hashes::{sha256, Hash, HashEngine}; + use crate::hashes::{sha256, Hash, HashEngine}; let tag = "rust-secp256k1DEBUG";