Skip to content

Update hashes to 0.16.0 #832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

rustaceanrob
Copy link

The 0.15.0 was a massive release for hashes in terms of API clean up and also adding new HKDF support. ElligatorSwift in combination with HKDF are the primitives required for encrypted message passing on bitcoin, so exporting these in tandum would save an additional hashes dependency.

I skip to 0.16.0 because hashes allows for hex-conservative as an optional dependency, and no listed changes elsewhere.

Reducing the scope of #783 and will take a stab at rand later.

@apoelstra
Copy link
Member

Thanks! Yeah, let's do this. I am tempted to cut a release of rust-secp256k1 anyway since @stevenroose also asked for this.

Was hoping to get #806 in first but it's blocked on lack of review, so let's just do it.

@apoelstra
Copy link
Member

cargo test --no-default-features --features 'alloc hashes'

fails claiming that Sha256 does not implement Display.

I'm not sure why the Display impl on Sha256 should depend on anything. I spent a couple minutes trying to trace through the macro soup that produces these impls but gave up.

The `0.15.0` was a massive release for `hashes` in terms of API clean
up and also adding new HKDF support. ElligatorSwift in combination with
HKDF are the primitives required for encrypted message passing on
bitcoin, so exporting these in tandum would save an additional
`hashes` dependency.

I skip to `0.16.0` because `hashes` allows for `hex-conservative` as an
optional dependency, and no listed changes elsewhere.
@rustaceanrob
Copy link
Author

Well, I came up with a solution lol. Using the Debug string works. This macro is implementing Debug, so this seems acceptable.

@apoelstra
Copy link
Member

Hah, thanks! I'd prefer to keep the PR here as-is as a canary, because I suspect that actually we broke hashes for nostd users, and we should fix that and cut a point release.

@rustaceanrob
Copy link
Author

Exploring hashes, it looks like the hash_trait_impls macro (internal_macros.rs) calls the impl_hex_string_traits macro (macros.rs) conditional on the hex feature. The 0.16.0 version makes hex optional, which is perhaps explaining the failure. Displaying a secret could can be gated on a hex feature or come with std, unless you have a proposed patch for hashes.

@tcharding
Copy link
Member

tcharding commented Aug 15, 2025

I did #833 while reviewing this.

f.debug_tuple(stringify!($thing)).field(&format_args!("#{:.16}", hash)).finish()
f.debug_tuple(stringify!($thing)).field(&format_args!("{:?}", hash)).finish()
Copy link
Member

@tcharding tcharding Aug 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That 16 width was so its a fingerprint not the whole hash. But I cannot find a test for it. Can you add this and make it pass?

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    #[cfg(feature = "hashes")]
    fn debug_secret_hashes_feature_enabled() {
        let key = "0000000000000000000000000000000000000000000000000000000000000001".parse::<SecretKey>().unwrap();
        
        // Normal debug hides value (`Display` is not implemented for `SecretKey`).
        let want = "SecretKey(#2518682f7819fb2d)";
        let got = format!("{:?}", key);
        assert_eq!(got, want);
    }

    #[test]
    #[cfg(not(feature = "hashes"))]
    fn debug_secret_no_hashes() {
        let key = "0000000000000000000000000000000000000000000000000000000000000001".parse::<SecretKey>().unwrap();
        
        // With "hashes" feature we just output a message.
        let want = "<secret key; enable `hashes` feature of `secp256k1` to display fingerprint>";
        let got = format!("{:?}", key);
        assert_eq!(got, want);
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the doc test was supposed to test it but it just includes a comment about it.

@rustaceanrob
Copy link
Author

Rebasing on #833 works. I will wait for that to go in and then add the tests.

@stevenroose
Copy link
Contributor

stevenroose commented Aug 15, 2025

It seems that no APIs change, so shouldn't it be possible to support bitcoin_hashes = ">= 0.14.0 < 0.17.0". The only diff is the Hash trait import. There is still a trait like that in v0.16.0, so it would only result in an unused warning for users of new hashes.

@stevenroose
Copy link
Contributor

With the following diff it could be compatible with 0.14, 0.15 and 0.16

hashes-16.patch.txt:

diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index a7b2d98..43c2942 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -23,26 +23,17 @@ dependencies = [
  "serde",
 ]

-[[package]]
-name = "bitcoin-internals"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b854212e29b96c8f0fe04cab11d57586c8f3257de0d146c76cb3b42b3eb9118"
-
 [[package]]
 name = "bitcoin-io"
-version = "0.2.0"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26792cd2bf245069a1c5acb06aa7ad7abe1de69b507c90b490bca81e0665d0ee"
-dependencies = [
- "bitcoin-internals",
-]
+checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56"

 [[package]]
 name = "bitcoin_hashes"
-version = "0.16.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e5d09f16329cd545d7e6008b2c6b2af3a90bc678cf41ac3d2f6755943301b16"
+checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
 dependencies = [
  "bitcoin-io",
  "hex-conservative",
@@ -116,9 +107,9 @@ checksum = "ee6c0438de3ca4d8cac2eec62b228e2f8865cfe9ebefea720406774223fa2d2e"

 [[package]]
 name = "hex-conservative"
-version = "0.3.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4afe881d0527571892c4034822e59bb10c6c991cce6abe8199b6f5cf10766f55"
+checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd"
 dependencies = [
  "arrayvec",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 99093bd..81f9aed 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,7 +38,7 @@ arbitrary = ["dep:arbitrary"]
 secp256k1-sys = { version = "0.11.0", default-features = false, path = "./secp256k1-sys" }

 arbitrary = { version = "1.4", optional = true }
-hashes = { package = "bitcoin_hashes", version = "0.16", default-features = false, optional = true }
+hashes = { package = "bitcoin_hashes", version = ">= 0.14.0, < 0.17", default-features = false, optional = true }
 rand = { version = "0.9", default-features = false, optional = true }
 serde = { version = "1.0.103", default-features = false, optional = true }

diff --git a/examples/sign_verify.rs b/examples/sign_verify.rs
index db0fdd3..4b74ecb 100644
--- a/examples/sign_verify.rs
+++ b/examples/sign_verify.rs
@@ -2,6 +2,8 @@ extern crate hashes;
 extern crate secp256k1;

 use hashes::sha256;
+#[allow(unused)] // unused in hashes >=0.15.0
+use hashes::Hash;
 use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};

 fn verify<C: Verification>(
diff --git a/examples/sign_verify_recovery.rs b/examples/sign_verify_recovery.rs
index dedc24c..a30ebc1 100644
--- a/examples/sign_verify_recovery.rs
+++ b/examples/sign_verify_recovery.rs
@@ -2,6 +2,8 @@ extern crate hashes;
 extern crate secp256k1;

 use hashes::sha256;
+#[allow(unused)] // unused in hashes >=0.15.0
+use hashes::Hash;
 use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};

 fn recover<C: Verification>(
diff --git a/src/secret.rs b/src/secret.rs
index 293c74d..9b85ac3 100644
--- a/src/secret.rs
+++ b/src/secret.rs
@@ -15,6 +15,8 @@ macro_rules! impl_display_secret {
         impl ::core::fmt::Debug for $thing {
             fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                 use hashes::{sha256, HashEngine};
+                #[allow(unused)] // unused in hashes >=0.15.0
+                use hashes::Hash;

                 let tag = "rust-secp256k1DEBUG";

@apoelstra
Copy link
Member

Nice! Yeah, since we moved the ThirtyTwoByteHash trait from hashes there is no longer a problem.

I wonder if we could even move the range backward to before 0.14..

@rustaceanrob
Copy link
Author

Will close for #837

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants