diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,12 @@
 # ChangeLog for crypton-x509-validation
 
+## 1.10.0
+
+* Verify ML-DSA signatures
+  [#35](https://github.com/kazu-yamamoto/crypton-certificate/pull/35)
+* Follow the breaking change in `crypton-x509` 1.10.0
+  [#35](https://github.com/kazu-yamamoto/crypton-certificate/pull/35)
+
 ## 1.9.1
 
 * Implementing the X509 name constrains extension.
diff --git a/Data/X509/Validation/Signature.hs b/Data/X509/Validation/Signature.hs
--- a/Data/X509/Validation/Signature.hs
+++ b/Data/X509/Validation/Signature.hs
@@ -20,6 +20,7 @@
 import qualified Crypto.PubKey.ECC.Types as ECC
 import qualified Crypto.PubKey.Ed25519 as Ed25519
 import qualified Crypto.PubKey.Ed448 as Ed448
+import qualified Crypto.PubKey.MLDSA as MLDSA
 import qualified Crypto.PubKey.RSA.PKCS15 as RSA
 import qualified Crypto.PubKey.RSA.PSS as PSS
 
@@ -142,12 +143,24 @@
   where
     doVerify (PubKeyEd25519 key) = eddsa Ed25519.verify Ed25519.signature key
     doVerify (PubKeyEd448 key) = eddsa Ed448.verify Ed448.signature key
+    doVerify (PubKeyMLDSA44 key) = mldsa key
+    doVerify (PubKeyMLDSA65 key) = mldsa key
+    doVerify (PubKeyMLDSA87 key) = mldsa key
     doVerify _ = SignatureFailed SignatureUnimplemented
 
     eddsa verify toSig key =
         case toSig signature of
             CryptoPassed sig
                 | verify key cdata sig -> SignaturePass
+                | otherwise -> SignatureFailed SignatureInvalid
+            CryptoFailed _ -> SignatureFailed SignatureInvalid
+
+    -- RFC 9881 Section 3: the empty context string.
+    mldsa :: MLDSA.MLDSA p => MLDSA.VerificationKey p -> SignatureVerification
+    mldsa key =
+        case MLDSA.signature signature of
+            CryptoPassed sig
+                | MLDSA.verify key MLDSA.emptyContext cdata sig -> SignaturePass
                 | otherwise -> SignatureFailed SignatureInvalid
             CryptoFailed _ -> SignatureFailed SignatureInvalid
 
diff --git a/Tests/Certificate.hs b/Tests/Certificate.hs
--- a/Tests/Certificate.hs
+++ b/Tests/Certificate.hs
@@ -29,8 +29,6 @@
     mkLeaf,
 ) where
 
-import Control.Applicative
-
 import Crypto.Hash.Algorithms
 import Crypto.Number.Serialize
 
@@ -40,6 +38,7 @@
 import qualified Crypto.PubKey.ECC.Types as ECC
 import qualified Crypto.PubKey.Ed25519 as Ed25519
 import qualified Crypto.PubKey.Ed448 as Ed448
+import qualified Crypto.PubKey.MLDSA as MLDSA
 import qualified Crypto.PubKey.RSA as RSA
 import qualified Crypto.PubKey.RSA.PKCS15 as RSA
 import qualified Crypto.PubKey.RSA.PSS as PSS
@@ -51,6 +50,7 @@
 import Data.ASN1.Types
 import Data.ByteArray (convert)
 import Data.Maybe (catMaybes)
+import Data.Proxy (Proxy (..))
 import Data.String (fromString)
 import Data.X509
 
@@ -103,6 +103,12 @@
         -> Alg ECDSA.PublicKey ECDSA.PrivateKey
     AlgEd25519 :: Alg Ed25519.PublicKey Ed25519.SecretKey
     AlgEd448 :: Alg Ed448.PublicKey Ed448.SecretKey
+    AlgMLDSA44
+        :: Alg (MLDSA.VerificationKey MLDSA.MLDSA44) (MLDSA.SigningKey MLDSA.MLDSA44)
+    AlgMLDSA65
+        :: Alg (MLDSA.VerificationKey MLDSA.MLDSA65) (MLDSA.SigningKey MLDSA.MLDSA65)
+    AlgMLDSA87
+        :: Alg (MLDSA.VerificationKey MLDSA.MLDSA87) (MLDSA.SigningKey MLDSA.MLDSA87)
 
 -- | Types of public and private keys used by a signature algorithm.
 type Keys pub priv = (Alg pub priv, pub, priv)
@@ -125,7 +131,16 @@
 generateKeys alg@AlgEd448 = do
     secret <- Ed448.generateSecretKey
     return (alg, Ed448.toPublic secret, secret)
+generateKeys alg@AlgMLDSA44 =
+    withAlg alg <$> MLDSA.generateKeyPair (Proxy :: Proxy MLDSA.MLDSA44)
+generateKeys alg@AlgMLDSA65 =
+    withAlg alg <$> MLDSA.generateKeyPair (Proxy :: Proxy MLDSA.MLDSA65)
+generateKeys alg@AlgMLDSA87 =
+    withAlg alg <$> MLDSA.generateKeyPair (Proxy :: Proxy MLDSA.MLDSA87)
 
+withAlg :: Alg pub priv -> (pub, priv) -> Keys pub priv
+withAlg alg (pub, priv) = (alg, pub, priv)
+
 generateRSAKeys
     :: Alg RSA.PublicKey RSA.PrivateKey
     -> Int
@@ -149,6 +164,9 @@
     bytes = (bits + 7) `div` 8
 getPubKey AlgEd25519 key = PubKeyEd25519 key
 getPubKey AlgEd448 key = PubKeyEd448 key
+getPubKey AlgMLDSA44 key = PubKeyMLDSA44 key
+getPubKey AlgMLDSA65 key = PubKeyMLDSA65 key
+getPubKey AlgMLDSA87 key = PubKeyMLDSA87 key
 
 getSignatureALG :: Alg pub priv -> SignatureALG
 getSignatureALG (AlgRSA _ hash) = SignatureALG (getHashALG hash) PubKeyALG_RSA
@@ -157,6 +175,9 @@
 getSignatureALG (AlgEC _ hash) = SignatureALG (getHashALG hash) PubKeyALG_EC
 getSignatureALG AlgEd25519 = SignatureALG_IntrinsicHash PubKeyALG_Ed25519
 getSignatureALG AlgEd448 = SignatureALG_IntrinsicHash PubKeyALG_Ed448
+getSignatureALG AlgMLDSA44 = SignatureALG_IntrinsicHash PubKeyALG_MLDSA44
+getSignatureALG AlgMLDSA65 = SignatureALG_IntrinsicHash PubKeyALG_MLDSA65
+getSignatureALG AlgMLDSA87 = SignatureALG_IntrinsicHash PubKeyALG_MLDSA87
 
 doSign :: Alg pub priv -> priv -> B.ByteString -> IO B.ByteString
 doSign (AlgRSA _ hash) key msg = do
@@ -193,6 +214,9 @@
     return $ convert $ Ed25519.sign key (Ed25519.toPublic key) msg
 doSign AlgEd448 key msg =
     return $ convert $ Ed448.sign key (Ed448.toPublic key) msg
+doSign AlgMLDSA44 key msg = convert <$> MLDSA.sign key MLDSA.emptyContext msg
+doSign AlgMLDSA65 key msg = convert <$> MLDSA.sign key MLDSA.emptyContext msg
+doSign AlgMLDSA87 key msg = convert <$> MLDSA.sign key MLDSA.emptyContext msg
 
 -- Certificate utilities --
 
diff --git a/Tests/Tests.hs b/Tests/Tests.hs
--- a/Tests/Tests.hs
+++ b/Tests/Tests.hs
@@ -1,7 +1,6 @@
 -- | Validation test suite.
 module Main (main) where
 
-import Control.Applicative
 import Control.Monad (unless)
 
 import Crypto.Hash.Algorithms
@@ -998,6 +997,9 @@
             , treeWithAlg "ECDSA" (AlgEC curveName hashSHA512)
             , treeWithAlg "Ed25519" AlgEd25519
             , treeWithAlg "Ed448" AlgEd448
+            , treeWithAlg "ML-DSA-44" AlgMLDSA44
+            , treeWithAlg "ML-DSA-65" AlgMLDSA65
+            , treeWithAlg "ML-DSA-87" AlgMLDSA87
             ]
   where
     pssParams = PSS.defaultPSSParams SHA224
diff --git a/crypton-x509-validation.cabal b/crypton-x509-validation.cabal
--- a/crypton-x509-validation.cabal
+++ b/crypton-x509-validation.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               crypton-x509-validation
-version:            1.9.1
+version:            1.10.0
 license:            BSD3
 license-file:       LICENSE
 copyright:          Vincent Hanquez <vincent@snarc.org>
@@ -33,12 +33,12 @@
         base >=3 && <5,
         bytestring,
         containers,
-        crypton >=1.1 && < 1.2,
+        crypton >=2.1.8 && <2.3,
         crypton-asn1-types >=0.4.1 && <0.5,
         crypton-asn1-encoding >=0.10.0 && <0.11,
         crypton-pem >=0.2.4 && <0.4,
-        crypton-x509 >=1.9.0 && <1.10,
-        crypton-x509-store >=1.9.0 && <1.10,
+        crypton-x509 >=1.10 && <1.11,
+        crypton-x509-store >=1.10 && <1.11,
         data-default,
         iproute >=1.2.2,
         mtl,
