Repository: dalek-cryptography/ed25519-dalek (language: rust)

Issue:
Reduce proliferation of nondefault features
Some features are accidentally activated transitively. For example, `alloc -> rand/alloc`, which activates the `rand` feature. This is a problem if we want to provide semver guarantees for default-on features.

Relatedly, `cargo test --no-default-features` fails on `release/2.0` currently because a lot of our tests use `generate()` which requires `rand` (or, consequently, `alloc, `std`,`batch`, or `batch_deterministic`). I think a `mock.rs` module would be useful here, but we have a lot of doctests that would be affected and it'd look nasty. Maybe worth it regardless though.


Discussion / hints:
FWIW I was planning on opening a PR to move to weakly activated and namespaced features, which would require MSRV 1.60 but would clean up quite a bit of that spurious feature activation

Fix patch:
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 6019bcd..24c9ae9 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -26,7 +26,8 @@ jobs:
       - uses: dtolnay/rust-toolchain@stable
       - run: rustup target add ${{ matrix.target }}
       - run: ${{ matrix.deps }}
-      - run: cargo test --target ${{ matrix.target }} --no-default-features --features alloc
+      - run: cargo test --target ${{ matrix.target }} --no-default-features --lib
+      - run: cargo test --target ${{ matrix.target }} --no-default-features --features alloc --lib
       - run: cargo test --target ${{ matrix.target }}
       - run: cargo test --target ${{ matrix.target }} --features batch
       - run: cargo test --target ${{ matrix.target }} --features batch_deterministic
@@ -47,7 +48,7 @@ jobs:
         run: cargo build --target x86_64-unknown-linux-gnu
 
   msrv:
-    name: Current MSRV is 1.57.0
+    name: Current MSRV is 1.60.0
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v3
@@ -57,7 +58,7 @@ jobs:
     - run: cargo -Z minimal-versions check --no-default-features --features serde
       # Now check that `cargo build` works with respect to the oldest possible
       # deps and the stated MSRV
-    - uses: dtolnay/rust-toolchain@1.57.0
+    - uses: dtolnay/rust-toolchain@1.60.0
     - run: cargo build
 
   bench:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd49936..05efbbd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,5 +7,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## Unreleased
 
 ### Changes
-* Bumped MSRV from 1.41 to 1.56.1
+* Bumped MSRV from 1.41 to 1.60.0
 * Removed `ExpandedSecretKey` API ((#205)[https://github.com/dalek-cryptography/ed25519-dalek/pull/205])
diff --git a/Cargo.toml b/Cargo.toml
index 6040fb4..5099158 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@ keywords = ["cryptography", "ed25519", "curve25519", "signature", "ECC"]
 categories = ["cryptography", "no-std"]
 description = "Fast and efficient ed25519 EdDSA key generations, signing, and verification in pure Rust."
 exclude = [ ".gitignore", "TESTVECTORS", "res/*" ]
-rust-version = "1.57"
+rust-version = "1.60"
 
 [badges]
 travis-ci = { repository = "dalek-cryptography/ed25519-dalek", branch = "master"}
@@ -29,19 +29,19 @@ ed25519 = { version = "=2.0.0-pre.1", default-features = false }
 merlin = { version = "3", default-features = false, optional = true }
 rand = { version = "0.8", default-features = false, optional = true }
 rand_core = { version = "0.6", default-features = false, optional = true }
-serde_crate = { package = "serde", version = "1.0", default-features = false, optional = true }
+serde = { version = "1.0", default-features = false, optional = true }
 serde_bytes = { version = "0.11", optional = true }
 sha2 = { version = "0.10", default-features = false }
 zeroize = { version = "1", default-features = false }
 
 [dev-dependencies]
-hex = "^0.4"
+hex = "0.4"
 bincode = "1.0"
 serde_json = "1.0"
 criterion = "0.3"
 hex-literal = "0.3"
 rand = "0.8"
-serde_crate = { package = "serde", version = "1.0", features = ["derive"] }
+serde = { version = "1.0", features = ["derive"] }
 toml = { version = "0.5" }
 
 [[bench]]
@@ -51,14 +51,16 @@ required-features = ["batch"]
 
 [features]
 default = ["std", "rand"]
-std = ["alloc", "ed25519/std", "serde_crate/std", "sha2/std", "rand/std"]
-alloc = ["curve25519-dalek/alloc", "ed25519/alloc", "rand/alloc", "zeroize/alloc"]
-serde = ["serde_crate", "serde_bytes", "ed25519/serde"]
+alloc = ["curve25519-dalek/alloc", "ed25519/alloc", "rand?/alloc", "serde?/alloc", "zeroize/alloc"]
+std = ["alloc", "ed25519/std", "rand?/std", "serde?/std", "sha2/std"]
+
+asm = ["sha2/asm"]
 batch = ["alloc", "merlin", "rand/std"]
 # This feature enables deterministic batch verification.
-batch_deterministic = ["alloc", "merlin", "rand", "rand_core"]
-asm = ["sha2/asm"]
+batch_deterministic = ["alloc", "merlin", "rand"]
 # This features turns off stricter checking for scalar malleability in signatures
 legacy_compatibility = []
 pkcs8 = ["ed25519/pkcs8"]
 pem = ["alloc", "ed25519/pem", "pkcs8"]
+rand = ["dep:rand", "dep:rand_core"]
+serde = ["dep:serde", "serde_bytes", "ed25519/serde"]
diff --git a/README.md b/README.md
index 42ce823..568dbd7 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ version = "1"
 
 # Minimum Supported Rust Version
 
-This crate requires Rust 1.57.0 at a minimum. 1.x releases of this crate supported an MSRV of 1.41.
+This crate requires Rust 1.60.0 at a minimum. Older 1.x releases of this crate supported an MSRV of 1.41.
 
 In the future, MSRV changes will be accompanied by a minor version bump.
 
diff --git a/src/batch.rs b/src/batch.rs
index 39af1ca..8e19dfe 100644
--- a/src/batch.rs
+++ b/src/batch.rs
@@ -9,6 +9,9 @@
 
 //! Batch signature verification.
 
+#[cfg(all(feature = "batch", feature = "batch_deterministic"))]
+compile_error!("`batch` and `batch_deterministic` features are mutually exclusive");
+
 use alloc::vec::Vec;
 
 use core::convert::TryFrom;
diff --git a/src/lib.rs b/src/lib.rs
index e6d051e..874207c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -254,9 +254,6 @@ extern crate alloc;
 #[macro_use]
 extern crate std;
 
-#[cfg(feature = "serde")]
-extern crate serde_crate as serde;
-
 pub use ed25519;
 
 #[cfg(any(feature = "batch", feature = "batch_deterministic"))]


Test patch:
diff --git a/tests/ed25519.rs b/tests/ed25519.rs
index 87b8164..f90b187 100644
--- a/tests/ed25519.rs
+++ b/tests/ed25519.rs
@@ -15,6 +15,7 @@ use ed25519_dalek::*;
 
 use hex::FromHex;
 
+#[cfg(feature = "rand")]
 use sha2::Sha512;
 
 #[cfg(test)]
@@ -198,7 +199,7 @@ mod vectors {
     }
 }
 
-#[cfg(test)]
+#[cfg(feature = "rand")]
 mod integrations {
     use super::*;
     use rand::rngs::OsRng;
@@ -317,8 +318,8 @@ mod integrations {
 }
 
 #[cfg(all(test, feature = "serde"))]
-#[derive(Debug, serde_crate::Serialize, serde_crate::Deserialize)]
-#[serde(crate = "serde_crate")]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
+#[serde(crate = "serde")]
 struct Demo {
     signing_key: SigningKey,
 }