From 7fee8c160c64a54970ca8300c75067646b6f1d6f Mon Sep 17 00:00:00 2001 From: Tobin Harding Date: Wed, 26 Jan 2022 15:15:38 +1100 Subject: [PATCH 1/4] Use Deref from core We should use `Deref` from `core` since it is available there. --- src/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.rs b/src/context.rs index 03caff55b..113c02883 100644 --- a/src/context.rs +++ b/src/context.rs @@ -16,7 +16,7 @@ pub mod global { #[cfg(feature = "global-context")] use rand; - use std::ops::Deref; + use core::ops::Deref; use std::sync::Once; use {Secp256k1, All}; From 80813b0a301cc4e83155dc2d3aa40410b7e664df Mon Sep 17 00:00:00 2001 From: Tobin Harding Date: Wed, 26 Jan 2022 10:00:35 +1100 Subject: [PATCH 2/4] Use fully qualified path for mem When building with --no-default-features the compiler emits: warning: unused import: `mem` The call site is feature gated so we either need to feature gate the import or use a fully qualified path. Since 'core' is quite short elect to use the fully qualified path. --- secp256k1-sys/src/types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/secp256k1-sys/src/types.rs b/secp256k1-sys/src/types.rs index 630e42ecf..e257d437b 100644 --- a/secp256k1-sys/src/types.rs +++ b/secp256k1-sys/src/types.rs @@ -1,5 +1,5 @@ #![allow(non_camel_case_types)] -use core::{fmt, mem}; +use core::fmt; pub type c_int = i32; pub type c_uchar = u8; @@ -46,7 +46,7 @@ impl AlignedType { } #[cfg(all(feature = "std", not(rust_secp_no_symbol_renaming)))] -pub(crate) const ALIGN_TO: usize = mem::align_of::(); +pub(crate) const ALIGN_TO: usize = ::core::mem::align_of::(); #[cfg(test)] mod tests { From 2aae5ef6688a9c7c981cb587d2930168a1531da6 Mon Sep 17 00:00:00 2001 From: Tobin Harding Date: Wed, 26 Jan 2022 10:04:49 +1100 Subject: [PATCH 3/4] Implement Debug when no std feature Currently we cannot build cleanly with `--no-default-features`. The `Debug` implementation for secrets is feature gated on `std` because it uses a hasher from `std`. If `bitcoin_hashes` is enabled we can use it for hashing. If neither `std` nor `bitcoin_hashes` is enabled fall back to outputting: --- src/secret.rs | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/secret.rs b/src/secret.rs index 28bd80d36..b7d72658a 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -19,9 +19,29 @@ use ::{SecretKey, KeyPair, to_hex}; use constants::SECRET_KEY_SIZE; macro_rules! impl_display_secret { - // Default hasher exists only in standard library and not alloc ($thing:ident) => { - #[cfg(feature = "std")] + #[cfg(feature = "bitocoin_hashes")] + #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] + impl ::core::fmt::Debug for $thing { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + use bitcoin_hashes::sha256; + + let tag = "rust-secp256k1DEBUG"; + + let mut engine = sha256::Hash::engine(); + let tag_hash = sha256::Hash::hash(tag.as_bytes()); + engine.input(&tag_hash[..]); + engine.input(&tag_hash[..]); + engine.input(&self.serialize_secret()); + let hash = sha256::Hash::from_engine(e).into_inner(); + + f.debug_tuple(stringify!($thing)) + .field(&format_args!("#{:016x}", hash)) + .finish() + } + } + + #[cfg(all(not(feature = "bitocoin_hashes"), feature = "std"))] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl ::core::fmt::Debug for $thing { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { @@ -44,6 +64,15 @@ macro_rules! impl_display_secret { .finish() } } + + // Fallback to make sure we can build cleanly with any combination of features. + #[cfg(all(not(feature = "bitocoin_hashes"), not(feature = "std")))] + #[cfg(not(feature = "std"))] + impl ::core::fmt::Debug for $thing { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "") + } + } } } @@ -92,6 +121,7 @@ impl SecretKey { /// # Example /// /// ``` + /// # #[cfg(feature = "std")] { /// use secp256k1::ONE_KEY; /// let key = ONE_KEY; /// // Normal display hides value @@ -108,6 +138,7 @@ impl SecretKey { /// "DisplaySecret(\"0000000000000000000000000000000000000000000000000000000000000001\")", /// format!("{:?}", key.display_secret()) /// ); + /// # } /// ``` #[inline] pub fn display_secret(&self) -> DisplaySecret { @@ -125,6 +156,7 @@ impl KeyPair { /// # Example /// /// ``` + /// # #[cfg(feature = "std")] { /// use secp256k1::ONE_KEY; /// use secp256k1::KeyPair; /// use secp256k1::Secp256k1; @@ -147,6 +179,8 @@ impl KeyPair { /// "DisplaySecret(\"0000000000000000000000000000000000000000000000000000000000000001\")", /// format!("{:?}", key.display_secret()) /// ); + /// # } + /// ``` #[inline] pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.serialize_secret() } From bc7e38b18067a58c741af37fcac0d0dbd3af0275 Mon Sep 17 00:00:00 2001 From: Tobin Harding Date: Wed, 26 Jan 2022 10:30:24 +1100 Subject: [PATCH 4/4] Enable build with global-context-less-secure Currently this command fails: cargo build --no-default-features --features=global-context-less-secure All features should be able to be built individually, this is currently not the case with `global-context-less-secure`. Enable `std` if `global-context-less-secure` is enabled (because `Once` only comes from `std`, not available in `core`). Add `global-context-less-secure` to the features test array in `contrib/test.sh`. With this applied the build command above runs successfully. --- Cargo.toml | 2 +- contrib/test.sh | 2 +- src/context.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2db107815..e50c84392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ rand-std = ["rand/std"] recovery = ["secp256k1-sys/recovery"] lowmemory = ["secp256k1-sys/lowmemory"] global-context = ["std", "rand-std", "global-context-less-secure"] -global-context-less-secure = [] +global-context-less-secure = ["std"] [dependencies] secp256k1-sys = { version = "0.4.2", default-features = false, path = "./secp256k1-sys" } diff --git a/contrib/test.sh b/contrib/test.sh index dc936ab75..2eaa666e7 100755 --- a/contrib/test.sh +++ b/contrib/test.sh @@ -1,6 +1,6 @@ #!/bin/sh -ex -FEATURES="bitcoin_hashes global-context lowmemory rand rand-std recovery serde" +FEATURES="bitcoin_hashes global-context-less-secure global-context lowmemory rand rand-std recovery serde" # Use toolchain if explicitly specified if [ -n "$TOOLCHAIN" ] diff --git a/src/context.rs b/src/context.rs index 113c02883..755ba8a48 100644 --- a/src/context.rs +++ b/src/context.rs @@ -35,6 +35,7 @@ pub mod global { impl Deref for GlobalContext { type Target = Secp256k1; + #[allow(unused_mut)] // Unused when "global-context" is not enabled. fn deref(&self) -> &Self::Target { static ONCE: Once = Once::new(); static mut CONTEXT: Option> = None;