Skip to content

Commit 7f194c0

Browse files
committed
Merge #837: Remove bitcoin-hashes feature
f9ce31f remove 'hashes' dependency (Andrew Poelstra) 89d52ae remove use of "hashes" from examples and doccomments (Andrew Poelstra) d4c6c0e remove use of 'hashes' from public API (Andrew Poelstra) 6d706e3 ecdh: remove use of `hashes` in example code and tests (Andrew Poelstra) 54828ac secret: stop using "hashes" dependency for secret debug output (Andrew Poelstra) Pull request description: This feature was used in examples and docs, and to obfuscate the Debug output of secrets. The latter can be done by other means, and the docs/examples can be modified or reduced. Fixes #836 ACKs for top commit: tcharding: ACK f9ce31f Tree-SHA512: 1ab313eeb600953792b9b4e0680c86ab2b2f146769e3d86190518e47ed8dd1a187ed717aadf2f25935c869e1eff0ce178573d11428f307f16527c7940d520c6f
2 parents fc912cb + f9ce31f commit 7f194c0

File tree

9 files changed

+83
-168
lines changed

9 files changed

+83
-168
lines changed

Cargo-minimal.lock

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ version = "1.4.1"
88
source = "registry+https://github.com/rust-lang/crates.io-index"
99
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
1010

11-
[[package]]
12-
name = "arrayvec"
13-
version = "0.7.6"
14-
source = "registry+https://github.com/rust-lang/crates.io-index"
15-
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
16-
1711
[[package]]
1812
name = "bincode"
1913
version = "1.3.3"
@@ -23,22 +17,6 @@ dependencies = [
2317
"serde",
2418
]
2519

26-
[[package]]
27-
name = "bitcoin-io"
28-
version = "0.1.2"
29-
source = "registry+https://github.com/rust-lang/crates.io-index"
30-
checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56"
31-
32-
[[package]]
33-
name = "bitcoin_hashes"
34-
version = "0.14.0"
35-
source = "registry+https://github.com/rust-lang/crates.io-index"
36-
checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
37-
dependencies = [
38-
"bitcoin-io",
39-
"hex-conservative",
40-
]
41-
4220
[[package]]
4321
name = "bitflags"
4422
version = "2.9.0"
@@ -105,15 +83,6 @@ version = "1.2.0"
10583
source = "registry+https://github.com/rust-lang/crates.io-index"
10684
checksum = "ee6c0438de3ca4d8cac2eec62b228e2f8865cfe9ebefea720406774223fa2d2e"
10785

108-
[[package]]
109-
name = "hex-conservative"
110-
version = "0.2.1"
111-
source = "registry+https://github.com/rust-lang/crates.io-index"
112-
checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd"
113-
dependencies = [
114-
"arrayvec",
115-
]
116-
11786
[[package]]
11887
name = "hex_lit"
11988
version = "0.1.1"
@@ -232,7 +201,6 @@ version = "0.31.1"
232201
dependencies = [
233202
"arbitrary",
234203
"bincode",
235-
"bitcoin_hashes",
236204
"getrandom",
237205
"hex_lit",
238206
"rand",

Cargo-recent.lock

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ version = "1.4.1"
88
source = "registry+https://github.com/rust-lang/crates.io-index"
99
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
1010

11-
[[package]]
12-
name = "arrayvec"
13-
version = "0.7.6"
14-
source = "registry+https://github.com/rust-lang/crates.io-index"
15-
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
16-
1711
[[package]]
1812
name = "bincode"
1913
version = "1.3.3"
@@ -23,22 +17,6 @@ dependencies = [
2317
"serde",
2418
]
2519

26-
[[package]]
27-
name = "bitcoin-io"
28-
version = "0.1.2"
29-
source = "registry+https://github.com/rust-lang/crates.io-index"
30-
checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56"
31-
32-
[[package]]
33-
name = "bitcoin_hashes"
34-
version = "0.14.0"
35-
source = "registry+https://github.com/rust-lang/crates.io-index"
36-
checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
37-
dependencies = [
38-
"bitcoin-io",
39-
"hex-conservative",
40-
]
41-
4220
[[package]]
4321
name = "bitflags"
4422
version = "2.9.0"
@@ -99,15 +77,6 @@ version = "1.8.2"
9977
source = "registry+https://github.com/rust-lang/crates.io-index"
10078
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
10179

102-
[[package]]
103-
name = "hex-conservative"
104-
version = "0.2.1"
105-
source = "registry+https://github.com/rust-lang/crates.io-index"
106-
checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd"
107-
dependencies = [
108-
"arrayvec",
109-
]
110-
11180
[[package]]
11281
name = "hex_lit"
11382
version = "0.1.1"
@@ -223,7 +192,6 @@ version = "0.31.1"
223192
dependencies = [
224193
"arbitrary",
225194
"bincode",
226-
"bitcoin_hashes",
227195
"getrandom",
228196
"hex_lit",
229197
"rand",

Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ rustdoc-args = ["--cfg", "docsrs"]
1919

2020
[features]
2121
default = ["std"]
22-
std = ["alloc", "secp256k1-sys/std", "rand?/std", "rand?/std_rng", "rand?/thread_rng", "hashes?/std"]
22+
std = ["alloc", "secp256k1-sys/std", "rand?/std", "rand?/std_rng", "rand?/thread_rng"]
2323
# allow use of Secp256k1::new and related API that requires an allocator
2424
alloc = ["secp256k1-sys/alloc"]
2525
recovery = ["secp256k1-sys/recovery"]
@@ -38,7 +38,6 @@ arbitrary = ["dep:arbitrary"]
3838
secp256k1-sys = { version = "0.11.0", default-features = false, path = "./secp256k1-sys" }
3939

4040
arbitrary = { version = "1.4", optional = true }
41-
hashes = { package = "bitcoin_hashes", version = "0.14", default-features = false, optional = true }
4241
rand = { version = "0.9", default-features = false, optional = true }
4342
serde = { version = "1.0.103", default-features = false, optional = true }
4443

@@ -58,11 +57,11 @@ unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(secp256k1_fu
5857

5958
[[example]]
6059
name = "sign_verify_recovery"
61-
required-features = ["recovery", "hashes", "std"]
60+
required-features = ["recovery", "std"]
6261

6362
[[example]]
6463
name = "sign_verify"
65-
required-features = ["hashes", "std"]
64+
required-features = ["std"]
6665

6766
[[example]]
6867
name = "generate_keys"

examples/sign_verify.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
1-
extern crate hashes;
1+
//! Signing and Verification Example
2+
//!
3+
//! In this example we directly sign the "output of a hash function"
4+
//! as represented by a 32-byte array. In practice, when signing with
5+
//! the ECDSA API, you should not sign an arbitrary hash like this,
6+
//! whether it is typed as a `[u8; 32]` or a `sha2::Sha256` or whatever.
7+
//!
8+
//! Instead, you should have a dedicated signature hash type, which has
9+
//! constructors ensuring that it represents an (ideally) domain-separated
10+
//! hash of the data you intend to sign. This type should implement
11+
//! `Into<Message>` so it can be passed to `sign_ecdsa` as a message.
12+
//!
13+
//! An example of such a type is `bitcoin::LegacySighash` from rust-bitcoin.
14+
//!
15+
216
extern crate secp256k1;
317

4-
use hashes::{sha256, Hash};
518
use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};
619

720
fn verify<C: Verification>(
821
secp: &Secp256k1<C>,
9-
msg: &[u8],
22+
msg_digest: [u8; 32],
1023
sig: [u8; 64],
1124
pubkey: [u8; 33],
1225
) -> Result<bool, Error> {
13-
let msg = sha256::Hash::hash(msg);
14-
let msg = Message::from_digest(msg.to_byte_array());
26+
let msg = Message::from_digest(msg_digest);
1527
let sig = ecdsa::Signature::from_compact(&sig)?;
1628
let pubkey = PublicKey::from_slice(&pubkey)?;
1729

@@ -20,11 +32,10 @@ fn verify<C: Verification>(
2032

2133
fn sign<C: Signing>(
2234
secp: &Secp256k1<C>,
23-
msg: &[u8],
35+
msg_digest: [u8; 32],
2436
seckey: [u8; 32],
2537
) -> Result<ecdsa::Signature, Error> {
26-
let msg = sha256::Hash::hash(msg);
27-
let msg = Message::from_digest(msg.to_byte_array());
38+
let msg = Message::from_digest(msg_digest);
2839
let seckey = SecretKey::from_byte_array(seckey)?;
2940
Ok(secp.sign_ecdsa(msg, &seckey))
3041
}
@@ -40,11 +51,11 @@ fn main() {
4051
2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141,
4152
134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54,
4253
];
43-
let msg = b"This is some message";
54+
let msg_digest = *b"this must be secure hash output.";
4455

45-
let signature = sign(&secp, msg, seckey).unwrap();
56+
let signature = sign(&secp, msg_digest, seckey).unwrap();
4657

4758
let serialize_sig = signature.serialize_compact();
4859

49-
assert!(verify(&secp, msg, serialize_sig, pubkey).unwrap());
60+
assert!(verify(&secp, msg_digest, serialize_sig, pubkey).unwrap());
5061
}

examples/sign_verify_recovery.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
extern crate hashes;
21
extern crate secp256k1;
32

4-
use hashes::{sha256, Hash};
53
use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification};
64

75
fn recover<C: Verification>(
86
secp: &Secp256k1<C>,
9-
msg: &[u8],
7+
msg_digest: [u8; 32],
108
sig: [u8; 64],
119
recovery_id: u8,
1210
) -> Result<PublicKey, Error> {
13-
let msg = sha256::Hash::hash(msg);
14-
let msg = Message::from_digest(msg.to_byte_array());
11+
let msg = Message::from_digest(msg_digest);
1512
let id = ecdsa::RecoveryId::try_from(i32::from(recovery_id))?;
1613
let sig = ecdsa::RecoverableSignature::from_compact(&sig, id)?;
1714

@@ -20,11 +17,10 @@ fn recover<C: Verification>(
2017

2118
fn sign_recovery<C: Signing>(
2219
secp: &Secp256k1<C>,
23-
msg: &[u8],
20+
msg_digest: [u8; 32],
2421
seckey: [u8; 32],
2522
) -> Result<ecdsa::RecoverableSignature, Error> {
26-
let msg = sha256::Hash::hash(msg);
27-
let msg = Message::from_digest(msg.to_byte_array());
23+
let msg = Message::from_digest(msg_digest);
2824
let seckey = SecretKey::from_byte_array(seckey)?;
2925
Ok(secp.sign_ecdsa_recoverable(msg, &seckey))
3026
}
@@ -41,11 +37,11 @@ fn main() {
4137
134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54,
4238
])
4339
.unwrap();
44-
let msg = b"This is some message";
40+
let msg_digest = *b"this must be secure hash output.";
4541

46-
let signature = sign_recovery(&secp, msg, seckey).unwrap();
42+
let signature = sign_recovery(&secp, msg_digest, seckey).unwrap();
4743

4844
let (recovery_id, serialize_sig) = signature.serialize_compact();
4945

50-
assert_eq!(recover(&secp, msg, serialize_sig, recovery_id.to_u8()), Ok(pubkey));
46+
assert_eq!(recover(&secp, msg_digest, serialize_sig, recovery_id.to_u8()), Ok(pubkey));
5147
}

src/ecdh.rs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,9 @@ impl AsRef<[u8]> for SharedSecret {
110110
/// 64 bytes representing the (x,y) co-ordinates of a point on the curve (32 bytes each).
111111
///
112112
/// # Examples
113-
/// ```
114-
/// # #[cfg(all(feature = "hashes", feature = "rand", feature = "std"))] {
115-
/// # use secp256k1::{ecdh, rand, Secp256k1, PublicKey, SecretKey};
116-
/// # use secp256k1::hashes::{Hash, sha512};
113+
/// ```ignore
114+
/// use bitcoin_hashes::{Hash, sha512};
115+
/// use secp256k1::{ecdh, rand, Secp256k1, PublicKey, SecretKey};
117116
///
118117
/// let s = Secp256k1::new();
119118
/// let (sk1, pk1) = s.generate_keypair(&mut rand::rng());
@@ -124,7 +123,6 @@ impl AsRef<[u8]> for SharedSecret {
124123
/// let point2 = ecdh::shared_secret_point(&pk1, &sk2);
125124
/// let secret2 = sha512::Hash::hash(&point2);
126125
/// assert_eq!(secret1, secret2)
127-
/// # }
128126
/// ```
129127
pub fn shared_secret_point(point: &PublicKey, scalar: &SecretKey) -> [u8; 64] {
130128
let mut xy = [0u8; 64];
@@ -224,32 +222,6 @@ mod tests {
224222
assert_eq!(y, new_y);
225223
}
226224

227-
#[test]
228-
#[cfg(not(secp256k1_fuzz))]
229-
#[cfg(all(feature = "hashes", feature = "rand", feature = "std"))]
230-
fn hashes_and_sys_generate_same_secret() {
231-
use hashes::{sha256, Hash, HashEngine};
232-
233-
use crate::ecdh::shared_secret_point;
234-
235-
let s = Secp256k1::signing_only();
236-
let (sk1, _) = s.generate_keypair(&mut rand::rng());
237-
let (_, pk2) = s.generate_keypair(&mut rand::rng());
238-
239-
let secret_sys = SharedSecret::new(&pk2, &sk1);
240-
241-
let xy = shared_secret_point(&pk2, &sk1);
242-
243-
// Mimics logic in `bitcoin-core/secp256k1/src/module/main_impl.h`
244-
let version = (xy[63] & 0x01) | 0x02;
245-
let mut engine = sha256::HashEngine::default();
246-
engine.input(&[version]);
247-
engine.input(&xy.as_ref()[..32]);
248-
let secret_bh = sha256::Hash::from_engine(engine);
249-
250-
assert_eq!(secret_bh.as_byte_array(), secret_sys.as_ref());
251-
}
252-
253225
#[test]
254226
#[cfg(all(feature = "serde", feature = "alloc"))]
255227
fn serde() {

src/key.rs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ use crate::ellswift::ElligatorSwift;
1616
use crate::ffi::types::c_uint;
1717
use crate::ffi::{self, CPtr};
1818
use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey};
19-
#[cfg(feature = "hashes")]
20-
#[allow(deprecated)]
21-
use crate::ThirtyTwoByteHash;
2219
#[cfg(feature = "global-context")]
2320
use crate::SECP256K1;
2421
use crate::{
@@ -371,15 +368,6 @@ impl SecretKey {
371368
}
372369
}
373370

374-
#[cfg(feature = "hashes")]
375-
#[allow(deprecated)]
376-
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
377-
/// Converts a 32-byte hash directly to a secret key without error paths.
378-
fn from(t: T) -> SecretKey {
379-
SecretKey::from_byte_array(t.into_32()).expect("failed to create secret key")
380-
}
381-
}
382-
383371
#[cfg(feature = "serde")]
384372
impl serde::Serialize for SecretKey {
385373
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
@@ -1889,15 +1877,12 @@ mod test {
18891877
}
18901878

18911879
#[test]
1892-
#[cfg(all(feature = "rand", feature = "alloc", not(feature = "hashes")))]
1880+
#[cfg(all(feature = "rand", feature = "alloc"))]
18931881
fn test_debug_output() {
18941882
let s = Secp256k1::new();
18951883
let (sk, _) = s.generate_keypair(&mut StepRng::new(1, 1));
18961884

1897-
assert_eq!(
1898-
&format!("{:?}", sk),
1899-
"<secret key; enable `hashes` feature of `secp256k1` to display fingerprint>"
1900-
);
1885+
assert_eq!(&format!("{:?}", sk), "SecretKey(7ad2d060fb2971d6)");
19011886

19021887
let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
19031888
assert_eq!(

0 commit comments

Comments
 (0)