Skip to content

Commit 29c0549

Browse files
committed
Merge #520: Fix feature gating
9c74855 Fix feature gating (Tobin C. Harding) Pull request description: Currently we have a few problems with our feature gating, attempt to audit all feature gating and fix it by doing: 1. Do not enable features on optional dependencies (`rand` and `bitcoin-hashes`) in dev-dependencies, doing so hides broken feature gating in unit tests. 2. Do not use unnecessary feature combinations when one feature enables another e.g. `any(feature = "std", feature = "alloc")`. 3. Enable "std" from "rand-std" and "bitcoin-std" (and fix features gating as for point 2). 4. Clean up code around `rand::thread_rng`, this is part of this patch because `thread_rng` requires the "rand-std" feature. 5. Clean up CI test script to test each feature individually now that "rand-std" and "bitcoin-hashes-std" enable "std". ACKs for top commit: apoelstra: ACK 9c74855 Kixunil: ACK 9c74855 Tree-SHA512: 3f8e464eeab1fe279249b5097082774c3de076ec9537162f367013098bde45957b12067a7434389e520bfacd3b415274f897917bf000f332d52cf960b1d4aecf
2 parents a777942 + 9c74855 commit 29c0549

File tree

11 files changed

+210
-241
lines changed

11 files changed

+210
-241
lines changed

Cargo.toml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ std = ["alloc", "secp256k1-sys/std"]
2323
# allow use of Secp256k1::new and related API that requires an allocator
2424
alloc = ["secp256k1-sys/alloc"]
2525
bitcoin-hashes = ["bitcoin_hashes"] # Feature alias because of the underscore.
26-
bitcoin-hashes-std = ["bitcoin-hashes", "bitcoin_hashes/std"]
27-
rand-std = ["rand/std", "rand/std_rng"]
26+
bitcoin-hashes-std = ["std", "bitcoin_hashes/std"]
27+
rand-std = ["std", "rand/std", "rand/std_rng"]
2828
recovery = ["secp256k1-sys/recovery"]
2929
lowmemory = ["secp256k1-sys/lowmemory"]
3030
global-context = ["std"]
@@ -46,10 +46,8 @@ bitcoin_hashes = { version = "0.11", default-features = false, optional = true }
4646
rand = { version = "0.8", default-features = false, optional = true }
4747

4848
[dev-dependencies]
49-
rand = "0.8"
5049
rand_core = "0.6"
5150
serde_test = "1.0"
52-
bitcoin_hashes = "0.11"
5351
bincode = "1.3.3"
5452

5553
# cbor does not build on WASM, we use it in a single trivial test (an example of when
@@ -64,15 +62,15 @@ getrandom = { version = "0.2", features = ["js"] }
6462

6563
[[example]]
6664
name = "sign_verify_recovery"
67-
required-features = ["std", "recovery"]
65+
required-features = ["recovery", "bitcoin-hashes-std"]
6866

6967
[[example]]
7068
name = "sign_verify"
71-
required-features = ["std"]
69+
required-features = ["bitcoin-hashes-std"]
7270

7371
[[example]]
7472
name = "generate_keys"
75-
required-features = ["std", "rand-std"]
73+
required-features = ["rand-std"]
7674

7775
[workspace]
7876
members = ["secp256k1-sys"]

contrib/test.sh

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
set -ex
44

5-
FEATURES="bitcoin-hashes global-context lowmemory rand recovery serde std alloc"
6-
# These features are typically enabled along with the 'std' feature, so we test
7-
# them together with 'std'.
8-
STD_FEATURES="rand-std bitcoin-hashes-std"
5+
FEATURES="bitcoin-hashes global-context lowmemory rand recovery serde std alloc bitcoin-hashes-std rand-std"
96

107
cargo --version
118
rustc --version
@@ -49,17 +46,16 @@ if [ "$DO_FEATURE_MATRIX" = true ]; then
4946
RUSTFLAGS='--cfg=fuzzing' RUSTDOCFLAGS='--cfg=fuzzing' cargo test --all
5047
RUSTFLAGS='--cfg=fuzzing' RUSTDOCFLAGS='--cfg=fuzzing' cargo test --all --features="$FEATURES"
5148
cargo test --all --features="rand serde"
52-
cargo test --features="$STD_FEATURES"
5349

5450
if [ "$NIGHTLY" = true ]; then
5551
cargo test --all --all-features
5652
RUSTFLAGS='--cfg=fuzzing' RUSTDOCFLAGS='--cfg=fuzzing' cargo test --all --all-features
5753
fi
5854

5955
# Examples
60-
cargo run --example sign_verify --features=std
61-
cargo run --example sign_verify_recovery --features=std,recovery
62-
cargo run --example generate_keys --features=std,rand-std
56+
cargo run --example sign_verify --features=bitcoin-hashes-std
57+
cargo run --example sign_verify_recovery --features=recovery,bitcoin-hashes-std
58+
cargo run --example generate_keys --features=rand-std
6359
fi
6460

6561
# Build the docs if told to (this only works with the nightly toolchain)
@@ -96,7 +92,7 @@ fi
9692
# Bench if told to, only works with non-stable toolchain (nightly, beta).
9793
if [ "$DO_BENCH" = true ]
9894
then
99-
RUSTFLAGS='--cfg=bench' cargo bench --features=recovery
95+
RUSTFLAGS='--cfg=bench' cargo bench --features=recovery,rand-std
10096
fi
10197

10298
exit 0

examples/generate_keys.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
extern crate secp256k1;
22

3-
use secp256k1::rand::thread_rng;
43
use secp256k1::{PublicKey, Secp256k1, SecretKey};
54

65
fn main() {
76
let secp = Secp256k1::new();
8-
let mut rng = thread_rng();
7+
let mut rng = rand::thread_rng();
98
// First option:
109
let (seckey, pubkey) = secp.generate_keypair(&mut rng);
1110

src/context.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ pub mod global {
3131
/// ```
3232
/// # #[cfg(all(feature = "global-context", feature = "rand-std"))] {
3333
/// use secp256k1::{PublicKey, SECP256K1};
34-
/// use secp256k1::rand::thread_rng;
35-
/// let _ = SECP256K1.generate_keypair(&mut thread_rng());
34+
/// let _ = SECP256K1.generate_keypair(&mut rand::thread_rng());
3635
/// # }
3736
/// ```
3837
pub static SECP256K1: &GlobalContext = &GlobalContext { __private: () };
@@ -106,7 +105,7 @@ mod private {
106105
}
107106

108107
#[cfg(feature = "alloc")]
109-
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc"))))]
108+
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
110109
mod alloc_only {
111110
use core::marker::PhantomData;
112111

@@ -176,7 +175,7 @@ mod alloc_only {
176175
/// If `rand-std` feature is enabled, context will have been randomized using `thread_rng`.
177176
/// If `rand-std` feature is not enabled please consider randomizing the context as follows:
178177
/// ```
179-
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
178+
/// # #[cfg(feature = "rand-std")] {
180179
/// # use secp256k1::Secp256k1;
181180
/// # use secp256k1::rand::{thread_rng, RngCore};
182181
/// let mut ctx = Secp256k1::new();

src/ecdh.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@ const SHARED_SECRET_SIZE: usize = constants::SECRET_KEY_SIZE;
3232
/// # Examples
3333
///
3434
/// ```
35-
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
36-
/// # use secp256k1::Secp256k1;
35+
/// # #[cfg(feature = "rand-std")] {
36+
/// # use secp256k1::{rand, Secp256k1};
3737
/// # use secp256k1::ecdh::SharedSecret;
38-
/// # use secp256k1::rand::thread_rng;
3938
/// let s = Secp256k1::new();
40-
/// let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
41-
/// let (sk2, pk2) = s.generate_keypair(&mut thread_rng());
39+
/// let (sk1, pk1) = s.generate_keypair(&mut rand::thread_rng());
40+
/// let (sk2, pk2) = s.generate_keypair(&mut rand::thread_rng());
4241
/// let sec1 = SharedSecret::new(&pk2, &sk1);
4342
/// let sec2 = SharedSecret::new(&pk1, &sk2);
4443
/// assert_eq!(sec1, sec2);
@@ -122,14 +121,13 @@ impl AsRef<[u8]> for SharedSecret {
122121
///
123122
/// # Examples
124123
/// ```
125-
/// # #[cfg(all(feature = "bitcoin-hashes-std", feature = "rand-std", feature = "std"))] {
126-
/// # use secp256k1::{ecdh, Secp256k1, PublicKey, SecretKey};
124+
/// # #[cfg(all(feature = "bitcoin-hashes-std", feature = "rand-std"))] {
125+
/// # use secp256k1::{ecdh, rand, Secp256k1, PublicKey, SecretKey};
127126
/// # use secp256k1::hashes::{Hash, sha512};
128-
/// # use secp256k1::rand::thread_rng;
129127
///
130128
/// let s = Secp256k1::new();
131-
/// let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
132-
/// let (sk2, pk2) = s.generate_keypair(&mut thread_rng());
129+
/// let (sk1, pk1) = s.generate_keypair(&mut rand::thread_rng());
130+
/// let (sk2, pk2) = s.generate_keypair(&mut rand::thread_rng());
133131
///
134132
/// let point1 = ecdh::shared_secret_point(&pk2, &sk1);
135133
/// let secret1 = sha512::Hash::hash(&point1);
@@ -201,19 +199,18 @@ impl<'de> ::serde::Deserialize<'de> for SharedSecret {
201199
#[cfg(test)]
202200
#[allow(unused_imports)]
203201
mod tests {
204-
use rand::thread_rng;
205202
#[cfg(target_arch = "wasm32")]
206203
use wasm_bindgen_test::wasm_bindgen_test as test;
207204

208205
use super::SharedSecret;
209206
use crate::Secp256k1;
210207

211208
#[test]
212-
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
209+
#[cfg(feature = "rand-std")]
213210
fn ecdh() {
214211
let s = Secp256k1::signing_only();
215-
let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
216-
let (sk2, pk2) = s.generate_keypair(&mut thread_rng());
212+
let (sk1, pk1) = s.generate_keypair(&mut rand::thread_rng());
213+
let (sk2, pk2) = s.generate_keypair(&mut rand::thread_rng());
217214

218215
let sec1 = SharedSecret::new(&pk2, &sk1);
219216
let sec2 = SharedSecret::new(&pk1, &sk2);
@@ -241,15 +238,15 @@ mod tests {
241238

242239
#[test]
243240
#[cfg(not(fuzzing))]
244-
#[cfg(all(feature = "std", feature = "rand-std", feature = "bitcoin-hashes-std"))]
241+
#[cfg(all(feature = "bitcoin-hashes-std", feature = "rand-std"))]
245242
fn bitcoin_hashes_and_sys_generate_same_secret() {
246243
use bitcoin_hashes::{sha256, Hash, HashEngine};
247244

248245
use crate::ecdh::shared_secret_point;
249246

250247
let s = Secp256k1::signing_only();
251-
let (sk1, _) = s.generate_keypair(&mut thread_rng());
252-
let (_, pk2) = s.generate_keypair(&mut thread_rng());
248+
let (sk1, _) = s.generate_keypair(&mut rand::thread_rng());
249+
let (_, pk2) = s.generate_keypair(&mut rand::thread_rng());
253250

254251
let secret_sys = SharedSecret::new(&pk2, &sk1);
255252

@@ -266,7 +263,7 @@ mod tests {
266263
}
267264

268265
#[test]
269-
#[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))]
266+
#[cfg(all(feature = "serde", feature = "alloc"))]
270267
fn serde() {
271268
use serde_test::{assert_tokens, Configure, Token};
272269
#[rustfmt::skip]
@@ -291,8 +288,8 @@ mod tests {
291288
}
292289

293290
#[cfg(bench)]
291+
#[cfg(feature = "rand-std")] // Currently only a single bench that requires "rand-std".
294292
mod benches {
295-
use rand::thread_rng;
296293
use test::{black_box, Bencher};
297294

298295
use super::SharedSecret;
@@ -301,7 +298,7 @@ mod benches {
301298
#[bench]
302299
pub fn bench_ecdh(bh: &mut Bencher) {
303300
let s = Secp256k1::signing_only();
304-
let (sk, pk) = s.generate_keypair(&mut thread_rng());
301+
let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
305302

306303
bh.iter(|| {
307304
let res = SharedSecret::new(&pk, &sk);

src/ecdsa/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,11 @@ impl<C: Verification> Secp256k1<C> {
364364
/// verify-capable context.
365365
///
366366
/// ```rust
367-
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
368-
/// # use secp256k1::rand::thread_rng;
369-
/// # use secp256k1::{Secp256k1, Message, Error};
367+
/// # #[cfg(feature = "rand-std")] {
368+
/// # use secp256k1::{rand, Secp256k1, Message, Error};
370369
/// #
371370
/// # let secp = Secp256k1::new();
372-
/// # let (secret_key, public_key) = secp.generate_keypair(&mut thread_rng());
371+
/// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
373372
/// #
374373
/// let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
375374
/// let sig = secp.sign_ecdsa(&message, &secret_key);

0 commit comments

Comments
 (0)