diff --git a/.github/workflows/ed25519-dalek.yml b/.github/workflows/ed25519-dalek.yml
index a49d83450..406864624 100644
--- a/.github/workflows/ed25519-dalek.yml
+++ b/.github/workflows/ed25519-dalek.yml
@@ -20,7 +20,7 @@ env:
 jobs:
 
   msrv:
-    name: Current MSRV is 1.60.0
+    name: Current MSRV is 1.72.0
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v3
@@ -29,5 +29,5 @@ jobs:
     - run: cargo update -Z minimal-versions
       # Now check that `cargo build` works with respect to the oldest possible
       # deps and the stated MSRV
-    - uses: dtolnay/rust-toolchain@1.60.0
+    - uses: dtolnay/rust-toolchain@1.72.0
     - run: cargo build
diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml
index b8e44dc50..5e7fa44e5 100644
--- a/.github/workflows/workspace.yml
+++ b/.github/workflows/workspace.yml
@@ -85,7 +85,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v3
-    - uses: dtolnay/rust-toolchain@1.73.0
+    - uses: dtolnay/rust-toolchain@1.81.0
       with:
         components: clippy
     - run: cargo clippy --target x86_64-unknown-linux-gnu --all-features
diff --git a/Cargo.toml b/Cargo.toml
index a891c6705..9bc2cba16 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,3 +10,5 @@ resolver = "2"
 [profile.dev]
 opt-level = 2
 
+[patch.crates-io]
+ed25519 = { git = "https://github.com/RustCrypto/signatures.git" }
diff --git a/curve25519-dalek/Cargo.toml b/curve25519-dalek/Cargo.toml
index f0896ba74..13eaf6acc 100644
--- a/curve25519-dalek/Cargo.toml
+++ b/curve25519-dalek/Cargo.toml
@@ -30,7 +30,7 @@ rustdoc-args = [
 features = ["serde", "rand_core", "digest", "legacy_compatibility", "group-bits"]
 
 [dev-dependencies]
-sha2 = { version = "0.10", default-features = false }
+sha2 = { version = "=0.11.0-pre.4", default-features = false }
 bincode = "1"
 criterion = { version = "0.5", features = ["html_reports"] }
 hex = "0.4.2"
@@ -50,7 +50,7 @@ cfg-if = "1"
 ff = { version = "0.13", default-features = false, optional = true }
 group = { version = "0.13", default-features = false, optional = true }
 rand_core = { version = "0.6.4", default-features = false, optional = true }
-digest = { version = "0.10", default-features = false, optional = true }
+digest = { version = "=0.11.0-pre.9", default-features = false, optional = true }
 subtle = { version = "2.6.0", default-features = false }
 serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
 zeroize = { version = "1", default-features = false, optional = true }
diff --git a/curve25519-dalek/src/backend/vector/avx2/edwards.rs b/curve25519-dalek/src/backend/vector/avx2/edwards.rs
index fd70d7d2f..4909ce15e 100644
--- a/curve25519-dalek/src/backend/vector/avx2/edwards.rs
+++ b/curve25519-dalek/src/backend/vector/avx2/edwards.rs
@@ -14,7 +14,7 @@
 //! This module currently has two point types:
 //!
 //! * `ExtendedPoint`: a point stored in vector-friendly format, with
-//! vectorized doubling and addition;
+//!   vectorized doubling and addition;
 //!
 //! * `CachedPoint`: used for readdition.
 //!
diff --git a/curve25519-dalek/src/backend/vector/packed_simd.rs b/curve25519-dalek/src/backend/vector/packed_simd.rs
index fe83b1865..61912db4f 100644
--- a/curve25519-dalek/src/backend/vector/packed_simd.rs
+++ b/curve25519-dalek/src/backend/vector/packed_simd.rs
@@ -240,7 +240,9 @@ impl u64x4 {
     pub const fn new_const(x0: u64, x1: u64, x2: u64, x3: u64) -> Self {
         // SAFETY: Transmuting between an array and a SIMD type is safe
         // https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
-        unsafe { Self(core::mem::transmute([x0, x1, x2, x3])) }
+        unsafe {
+            Self(core::mem::transmute::<[u64; 4], core::arch::x86_64::__m256i>([x0, x1, x2, x3]))
+        }
     }
 
     /// A constified variant of `splat`.
@@ -290,7 +292,13 @@ impl u32x8 {
     ) -> Self {
         // SAFETY: Transmuting between an array and a SIMD type is safe
         // https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
-        unsafe { Self(core::mem::transmute([x0, x1, x2, x3, x4, x5, x6, x7])) }
+        unsafe {
+            Self(
+                core::mem::transmute::<[u32; 8], core::arch::x86_64::__m256i>([
+                    x0, x1, x2, x3, x4, x5, x6, x7,
+                ]),
+            )
+        }
     }
 
     /// A constified variant of `splat`.
diff --git a/curve25519-dalek/src/edwards.rs b/curve25519-dalek/src/edwards.rs
index 856fac12f..2fa9f9900 100644
--- a/curve25519-dalek/src/edwards.rs
+++ b/curve25519-dalek/src/edwards.rs
@@ -52,19 +52,19 @@
 //! Scalar multiplication on Edwards points is provided by:
 //!
 //! * the `*` operator between a `Scalar` and a `EdwardsPoint`, which
-//! performs constant-time variable-base scalar multiplication;
+//!   performs constant-time variable-base scalar multiplication;
 //!
 //! * the `*` operator between a `Scalar` and a
-//! `EdwardsBasepointTable`, which performs constant-time fixed-base
-//! scalar multiplication;
+//!   `EdwardsBasepointTable`, which performs constant-time fixed-base
+//!   scalar multiplication;
 //!
 //! * an implementation of the
-//! [`MultiscalarMul`](../traits/trait.MultiscalarMul.html) trait for
-//! constant-time variable-base multiscalar multiplication;
+//!   [`MultiscalarMul`](../traits/trait.MultiscalarMul.html) trait for
+//!   constant-time variable-base multiscalar multiplication;
 //!
 //! * an implementation of the
-//! [`VartimeMultiscalarMul`](../traits/trait.VartimeMultiscalarMul.html)
-//! trait for variable-time variable-base multiscalar multiplication;
+//!   [`VartimeMultiscalarMul`](../traits/trait.VartimeMultiscalarMul.html)
+//!   trait for variable-time variable-base multiscalar multiplication;
 //!
 //! ## Implementation
 //!
@@ -104,7 +104,7 @@ use core::ops::{Mul, MulAssign};
 use cfg_if::cfg_if;
 
 #[cfg(feature = "digest")]
-use digest::{generic_array::typenum::U64, Digest};
+use digest::{array::typenum::U64, Digest};
 
 #[cfg(feature = "group")]
 use {
@@ -1234,9 +1234,9 @@ impl EdwardsPoint {
     /// # Return
     ///
     /// * `true` if `self` has zero torsion component and is in the
-    /// prime-order subgroup;
+    ///   prime-order subgroup;
     /// * `false` if `self` has a nonzero torsion component and is not
-    /// in the prime-order subgroup.
+    ///   in the prime-order subgroup.
     ///
     /// # Example
     ///
diff --git a/curve25519-dalek/src/montgomery.rs b/curve25519-dalek/src/montgomery.rs
index 2be35cdc7..50fe4ddac 100644
--- a/curve25519-dalek/src/montgomery.rs
+++ b/curve25519-dalek/src/montgomery.rs
@@ -209,10 +209,10 @@ impl MontgomeryPoint {
     /// # Return
     ///
     /// * `Some(EdwardsPoint)` if `self` is the \\(u\\)-coordinate of a
-    /// point on (the Montgomery form of) Curve25519;
+    ///   point on (the Montgomery form of) Curve25519;
     ///
     /// * `None` if `self` is the \\(u\\)-coordinate of a point on the
-    /// twist of (the Montgomery form of) Curve25519;
+    ///   twist of (the Montgomery form of) Curve25519;
     ///
     pub fn to_edwards(&self, sign: u8) -> Option<EdwardsPoint> {
         // To decompress the Montgomery u coordinate to an
diff --git a/curve25519-dalek/src/ristretto.rs b/curve25519-dalek/src/ristretto.rs
index c9d16aba3..5a79d3e41 100644
--- a/curve25519-dalek/src/ristretto.rs
+++ b/curve25519-dalek/src/ristretto.rs
@@ -93,19 +93,19 @@
 //! Scalar multiplication on Ristretto points is provided by:
 //!
 //! * the `*` operator between a `Scalar` and a `RistrettoPoint`, which
-//! performs constant-time variable-base scalar multiplication;
+//!   performs constant-time variable-base scalar multiplication;
 //!
 //! * the `*` operator between a `Scalar` and a
-//! `RistrettoBasepointTable`, which performs constant-time fixed-base
-//! scalar multiplication;
+//!   `RistrettoBasepointTable`, which performs constant-time fixed-base
+//!   scalar multiplication;
 //!
 //! * an implementation of the
-//! [`MultiscalarMul`](../traits/trait.MultiscalarMul.html) trait for
-//! constant-time variable-base multiscalar multiplication;
+//!   [`MultiscalarMul`](../traits/trait.MultiscalarMul.html) trait for
+//!   constant-time variable-base multiscalar multiplication;
 //!
 //! * an implementation of the
-//! [`VartimeMultiscalarMul`](../traits/trait.VartimeMultiscalarMul.html)
-//! trait for variable-time variable-base multiscalar multiplication;
+//!   [`VartimeMultiscalarMul`](../traits/trait.VartimeMultiscalarMul.html)
+//!   trait for variable-time variable-base multiscalar multiplication;
 //!
 //! ## Random Points and Hashing to Ristretto
 //!
@@ -113,11 +113,11 @@
 //! used to implement
 //!
 //! * `RistrettoPoint::random()`, which generates random points from an
-//! RNG - enabled by `rand_core` feature;
+//!   RNG - enabled by `rand_core` feature;
 //!
 //! * `RistrettoPoint::from_hash()` and
-//! `RistrettoPoint::hash_from_bytes()`, which perform hashing to the
-//! group.
+//!   `RistrettoPoint::hash_from_bytes()`, which perform hashing to the
+//!   group.
 //!
 //! The Elligator map itself is not currently exposed.
 //!
@@ -173,7 +173,7 @@ use core::ops::{Mul, MulAssign};
 use rand_core::CryptoRngCore;
 
 #[cfg(feature = "digest")]
-use digest::generic_array::typenum::U64;
+use digest::array::typenum::U64;
 #[cfg(feature = "digest")]
 use digest::Digest;
 
diff --git a/curve25519-dalek/src/scalar.rs b/curve25519-dalek/src/scalar.rs
index 6afd74eef..9081271d0 100644
--- a/curve25519-dalek/src/scalar.rs
+++ b/curve25519-dalek/src/scalar.rs
@@ -134,7 +134,7 @@ use rand_core::RngCore;
 use rand_core::CryptoRngCore;
 
 #[cfg(feature = "digest")]
-use digest::generic_array::typenum::U64;
+use digest::array::typenum::U64;
 #[cfg(feature = "digest")]
 use digest::Digest;
 
diff --git a/ed25519-dalek/Cargo.toml b/ed25519-dalek/Cargo.toml
index 626b8da92..8045338be 100644
--- a/ed25519-dalek/Cargo.toml
+++ b/ed25519-dalek/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "ed25519-dalek"
-version = "2.1.1"
+version = "2.2.0-pre"
 edition = "2021"
 authors = [
     "isis lovecruft <isis@patternsinthevoid.net>",
@@ -16,7 +16,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", "VALIDATIONVECTORS", "res/*" ]
-rust-version = "1.60"
+rust-version = "1.72"
 
 [package.metadata.docs.rs]
 rustdoc-args = [
@@ -27,9 +27,9 @@ features = ["batch", "digest", "hazmat", "pem", "serde"]
 
 [dependencies]
 curve25519-dalek = { version = "4", path = "../curve25519-dalek", default-features = false, features = ["digest"] }
-ed25519 = { version = ">=2.2, <2.3", default-features = false }
-signature = { version = ">=2.0, <2.3", optional = true, default-features = false }
-sha2 = { version = "0.10", default-features = false }
+ed25519 = { version = "=2.3.0-pre.0", default-features = false }
+signature = { version = "=2.3.0-pre.4", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.4", default-features = false }
 subtle = { version = "2.3.0", default-features = false }
 
 # optional features
@@ -41,8 +41,8 @@ zeroize = { version = "1.5", default-features = false, optional = true }
 [dev-dependencies]
 curve25519-dalek = { version = "4", path = "../curve25519-dalek", default-features = false, features = ["digest", "rand_core"] }
 x25519-dalek = { version = "2", path = "../x25519-dalek", default-features = false, features = ["static_secrets"] }
-blake2 = "0.10"
-sha3 = "0.10"
+blake2 = "=0.11.0-pre.4"
+sha3 = "=0.11.0-pre.4"
 hex = "0.4"
 bincode = "1.0"
 serde_json = "1.0"
@@ -63,7 +63,6 @@ default = ["fast", "std", "zeroize"]
 alloc = ["curve25519-dalek/alloc", "ed25519/alloc", "serde?/alloc", "zeroize/alloc"]
 std = ["alloc", "ed25519/std", "serde?/std", "sha2/std"]
 
-asm = ["sha2/asm"]
 batch = ["alloc", "merlin", "rand_core"]
 fast = ["curve25519-dalek/precomputed-tables"]
 digest = ["signature/digest"]
diff --git a/ed25519-dalek/src/hazmat.rs b/ed25519-dalek/src/hazmat.rs
index 784961304..f99ecc5b8 100644
--- a/ed25519-dalek/src/hazmat.rs
+++ b/ed25519-dalek/src/hazmat.rs
@@ -22,7 +22,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
 
 // These are used in the functions that are made public when the hazmat feature is set
 use crate::{Signature, VerifyingKey};
-use curve25519_dalek::digest::{generic_array::typenum::U64, Digest};
+use curve25519_dalek::digest::{array::typenum::U64, Digest};
 
 /// Contains the secret scalar and domain separator used for generating signatures.
 ///
diff --git a/ed25519-dalek/src/signing.rs b/ed25519-dalek/src/signing.rs
index 8999f50d2..aeda05004 100644
--- a/ed25519-dalek/src/signing.rs
+++ b/ed25519-dalek/src/signing.rs
@@ -24,7 +24,7 @@ use sha2::Sha512;
 use subtle::{Choice, ConstantTimeEq};
 
 use curve25519_dalek::{
-    digest::{generic_array::typenum::U64, Digest},
+    digest::{array::typenum::U64, Digest},
     edwards::{CompressedEdwardsY, EdwardsPoint},
     scalar::Scalar,
 };
@@ -713,10 +713,10 @@ impl From<&SigningKey> for pkcs8::KeypairBytes {
 }
 
 #[cfg(feature = "pkcs8")]
-impl TryFrom<pkcs8::PrivateKeyInfo<'_>> for SigningKey {
+impl TryFrom<pkcs8::PrivateKeyInfoRef<'_>> for SigningKey {
     type Error = pkcs8::Error;
 
-    fn try_from(private_key: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
+    fn try_from(private_key: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
         pkcs8::KeypairBytes::try_from(private_key)?.try_into()
     }
 }
@@ -774,7 +774,7 @@ impl<'d> Deserialize<'d> for SigningKey {
                     ));
                 }
 
-                SigningKey::try_from(bytes).map_err(serde::de::Error::custom)
+                Ok(SigningKey::from(bytes))
             }
         }
 
diff --git a/ed25519-dalek/src/verifying.rs b/ed25519-dalek/src/verifying.rs
index 246951b44..0e85ac345 100644
--- a/ed25519-dalek/src/verifying.rs
+++ b/ed25519-dalek/src/verifying.rs
@@ -13,7 +13,7 @@ use core::fmt::Debug;
 use core::hash::{Hash, Hasher};
 
 use curve25519_dalek::{
-    digest::{generic_array::typenum::U64, Digest},
+    digest::{array::typenum::U64, Digest},
     edwards::{CompressedEdwardsY, EdwardsPoint},
     montgomery::MontgomeryPoint,
     scalar::Scalar,