diff --git a/Crypto/PubKey/ECC/Prim.hs b/Crypto/PubKey/ECC/Prim.hs
--- a/Crypto/PubKey/ECC/Prim.hs
+++ b/Crypto/PubKey/ECC/Prim.hs
@@ -6,6 +6,7 @@
     , pointDouble
     , pointMul
     , isPointAtInfinity
+    , isPointValid
     ) where
 
 import Data.Maybe
@@ -89,6 +90,32 @@
 isPointAtInfinity :: Point -> Bool
 isPointAtInfinity PointO = True
 isPointAtInfinity _      = False
+
+-- | check if a point is on specific curve
+--
+-- This perform three checks:
+--
+-- * x is not out of range
+-- * y is not out of range
+-- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds
+isPointValid :: Curve -> Point -> Bool
+isPointValid _                           PointO      = True
+isPointValid (CurveFP (CurvePrime p cc)) (Point x y) =
+    isValid x && isValid y && (y ^ (2 :: Int)) `eqModP` (x ^ (3 :: Int) + a * x + b)
+  where a  = ecc_a cc
+        b  = ecc_b cc
+        eqModP z1 z2 = (z1 `mod` p) == (z2 `mod` p)
+        isValid e = e >= 0 && e < p
+isPointValid curve@(CurveF2m (CurveBinary fx cc)) pt@(Point x y) =
+    and [ isValid x
+        , isValid y
+        , ((((x `add` a) `mul` x `add` y) `mul` x) `add` b `add` (squareF2m fx y)) == 0
+        ]
+  where a  = ecc_a cc
+        b  = ecc_b cc
+        add = addF2m
+        mul = mulF2m fx
+        isValid e = modF2m fx e == e
 
 -- | div and mod
 divmod :: Integer -> Integer -> Integer -> Maybe Integer
diff --git a/Tests/EccArithmetic.hs b/Tests/EccArithmetic.hs
--- a/Tests/EccArithmetic.hs
+++ b/Tests/EccArithmetic.hs
@@ -1,8 +1,6 @@
 module EccArithmetic (properties_ecc_arithmetic) where
 
-import Test.Framework.Providers.QuickCheck2 (testProperty)
-import Test.QuickCheck
-import Test.QuickCheck.Test
+import Test.Tasty.QuickCheck
 
 import Crypto.Types.PubKey.ECC
 import Crypto.PubKey.ECC.Generate
diff --git a/Tests/KAT.hs b/Tests/KAT.hs
--- a/Tests/KAT.hs
+++ b/Tests/KAT.hs
@@ -1,11 +1,9 @@
 {-# LANGUAGE OverloadedStrings #-}
 module KAT where
 
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.HUnit (testCase)
-import Test.QuickCheck
-import Test.QuickCheck.Test
-import Test.HUnit
+import Test.Tasty
+import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
 import System.IO (hFlush, stdout)
 
 import Data.ByteString (ByteString)
@@ -19,6 +17,7 @@
 import KAT.OAEP
 import KAT.PSS
 import KAT.DSA
+import KAT.ECC
 import KAT.ECDSA
 
 data VectorMgf = VectorMgf { seed :: ByteString
@@ -40,5 +39,8 @@
     , pssTests
     , oaepTests
     , dsaTests
+    , eccTests
     , ecdsaTests
     ]
+
+newKats = [ eccKatTests ]
diff --git a/Tests/KAT/DSA.hs b/Tests/KAT/DSA.hs
--- a/Tests/KAT/DSA.hs
+++ b/Tests/KAT/DSA.hs
@@ -8,9 +8,8 @@
 import qualified Crypto.PubKey.DSA as DSA
 import qualified Crypto.Hash.SHA1 as SHA1
 
-import Test.HUnit
-import Test.Framework (Test, testGroup)
-import Test.Framework.Providers.HUnit (testCase)
+import Test.Tasty
+import Test.Tasty.HUnit
 
 data VectorDSA = VectorDSA
     { pgq :: DSA.Params
diff --git a/Tests/KAT/ECC.hs b/Tests/KAT/ECC.hs
new file mode 100644
--- /dev/null
+++ b/Tests/KAT/ECC.hs
@@ -0,0 +1,145 @@
+{-# LANGUAGE OverloadedStrings #-}
+module KAT.ECC (eccTests, eccKatTests) where
+
+import Control.Arrow (second)
+import Control.Applicative
+import Data.ByteString (ByteString)
+import Crypto.Number.Serialize
+
+import qualified Crypto.Types.PubKey.ECC as ECC
+import qualified Crypto.PubKey.ECC.Prim as ECC
+
+import Test.Tasty.KAT
+import Test.Tasty.KAT.FileLoader
+
+import Test.Tasty
+import Test.Tasty.HUnit
+
+
+data VectorPoint = VectorPoint
+    { curve :: ECC.Curve
+    , x     :: Integer
+    , y     :: Integer
+    , valid :: Bool
+    }
+
+vectorsPoint =
+    [ VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x     = 0x491c0c4761b0a4a147b5e4ce03a531546644f5d1e3d05e57
+        , y     = 0x6fa5addd47c5d6be3933fbff88f57a6c8ca0232c471965de
+        , valid = False -- point not on curve
+        }
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x646c22e8aa5f7833390e0399155ac198ae42470bba4fc834
+        , y    = 0x8d4afcfffd80e69a4d180178b37c44572495b7b267ee32a9
+        , valid = True
+        }
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x4c6b9ea0dec92ecfff7799470be6a2277b9169daf45d54bb
+        , y    = 0xf0eab42826704f51b26ae98036e83230becb639dd1964627
+        , valid = False -- point not on curve
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x0673c8bb717b055c3d6f55c06acfcfb7260361ed3ec0f414
+        , y    = 0xba8b172826eb0b854026968d2338a180450a27906f6eddea
+        , valid = True
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x82c949295156192df0b52480e38c810751ac570daec460a3
+        , y    = 0x200057ada615c80b8ff256ce8d47f2562b74a438f1921ac3
+        , valid = False -- point not on curve
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x284fbaa76ce0faae2ca4867d01092fa1ace5724cd12c8dd0
+        , y    = 0xe42af3dbf3206be3fcbcc3a7ccaf60c73dc29e7bb9b44fca
+        , valid = True
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x1b574acd4fb0f60dde3e3b5f3f0e94211f95112e43cba6fd2
+        , y    = 0xbcc1b8a770f01a22e84d7f14e44932ffe094d8e3b1e6ac26
+        , valid = False -- x or y out of range
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x16ba109f1f1bb44e0d05b80181c03412ea764a59601d17e9f
+        , y    = 0x0569a843dbb4e287db420d6b9fe30cd7b5d578b052315f56
+        , valid = False -- x or y out of range
+        }
+
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x1333308a7c833ede5189d25ea3525919c9bd16370d904938d
+        , y    = 0xb10fd01d67df75ff9b726c700c1b50596c9f0766ea56f80e
+        , valid = False -- x or y out of range
+        }
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x    = 0x9671ec444cff24c8a5be80b018fa505ed6109a731e88c91a
+        , y    = 0xfe79dae23008e46bf4230c895aab261a95845a77f06d0655
+        , valid = True
+        }
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x     = 0x158e8b6f0b14216bc52fe8897b4305d870ede70436a96741d
+        , y     = 0xfb3f970b19a313571a1a23be310923f85acc1cab0a157cbd
+        , valid = False -- x or y out of range
+        }
+    , VectorPoint
+        { curve = ECC.getCurveByName ECC.SEC_p192r1
+        , x     = 0xace95b650c08f73dbb4fa7b4bbdebd6b809a25b28ed135ef
+        , y     = 0xe9b8679404166d1329dd539ad52aad9a1b6681f5f26bb9aa
+        , valid = False -- point not on curve
+        }
+    ]
+
+doPointValidTest (i, vector) = testCase (show i) (valid vector @=? ECC.isPointValid (curve vector) (ECC.Point (x vector) (y vector)))
+
+eccTests = testGroup "ECC"
+    [ testGroup "valid-point" $ map doPointValidTest (zip [0..] vectorsPoint)
+    ]
+
+eccKatTests = do
+    res <- testKatLoad "KATs/ECC-PKV.txt" (map (second (map toVector)) . katLoaderSimple)
+    return $ testKatDetailed {-Grouped-} "ECC/valid-point" res (\g vect -> do
+        let c = ECC.getCurveByName <$> case g of
+                        "P-192" -> Just ECC.SEC_p192r1
+                        "P-224" -> Just ECC.SEC_p224r1
+                        "P-256" -> Just ECC.SEC_p256r1
+                        "P-384" -> Just ECC.SEC_p384r1
+                        "P-521" -> Just ECC.SEC_p521r1
+                        "B-163" -> Just ECC.SEC_t163r2
+                        "B-233" -> Just ECC.SEC_t233r1
+                        "B-283" -> Just ECC.SEC_t283r1
+                        "B-409" -> Just ECC.SEC_t409r1
+                        "B-571" -> Just ECC.SEC_t571r1
+                        ""      -> Nothing
+                        _       -> Nothing
+{-
+                        "K-163" -> Just ECC.SEC_t163k1
+                        "K-233" -> Just ECC.SEC_t233k1
+                        "K-283" -> Just ECC.SEC_t283k1
+                        "K-409" -> Just ECC.SEC_t409k1
+                        "K-571" -> Just ECC.SEC_t571k1
+-}
+        case c of
+            Nothing    -> return True
+            Just curve -> do
+                return (ECC.isPointValid curve (ECC.Point (x vect) (y vect)) == valid vect)
+        )
+
+  where toVector kvs =
+            case sequence $ map (flip lookup kvs) [ "Qx", "Qy", "Result" ] of
+                Just [qx,qy,res] -> VectorPoint undefined (valueHexInteger qx) (valueHexInteger qy) (head res /= 'F')
+                Nothing          -> error ("ERROR CRAP: " ++ show kvs) -- VectorPoint undefined 0 0 True
diff --git a/Tests/KAT/ECDSA.hs b/Tests/KAT/ECDSA.hs
--- a/Tests/KAT/ECDSA.hs
+++ b/Tests/KAT/ECDSA.hs
@@ -10,9 +10,8 @@
 import qualified Crypto.Types.PubKey.ECC as ECC
 import qualified Crypto.Hash.SHA1 as SHA1
 
-import Test.HUnit
-import Test.Framework (testGroup)
-import Test.Framework.Providers.HUnit (testCase)
+import Test.Tasty.HUnit
+import Test.Tasty
 
 data VectorECDSA = VectorECDSA
     { curve :: ECC.Curve
diff --git a/Tests/KAT/OAEP.hs b/Tests/KAT/OAEP.hs
--- a/Tests/KAT/OAEP.hs
+++ b/Tests/KAT/OAEP.hs
@@ -10,9 +10,8 @@
 import qualified Crypto.PubKey.RSA.OAEP as OAEP
 import qualified Crypto.Hash.SHA1 as SHA1
 
-import Test.HUnit
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.HUnit (testCase)
+import Test.Tasty
+import Test.Tasty.HUnit
 
 rsaKeyInt = PrivateKey
     { private_pub = PublicKey
diff --git a/Tests/KAT/PSS.hs b/Tests/KAT/PSS.hs
--- a/Tests/KAT/PSS.hs
+++ b/Tests/KAT/PSS.hs
@@ -10,9 +10,8 @@
 import qualified Crypto.PubKey.RSA.PSS as PSS
 import qualified Crypto.Hash.SHA1 as SHA1
 
-import Test.HUnit
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.HUnit (testCase)
+import Test.Tasty
+import Test.Tasty.HUnit
 
 data VectorPSS = VectorPSS { message :: ByteString
                            , salt :: ByteString
diff --git a/Tests/Tests.hs b/Tests/Tests.hs
--- a/Tests/Tests.hs
+++ b/Tests/Tests.hs
@@ -1,10 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-import Test.Framework (Test, defaultMain, testGroup)
-import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.Tasty
+import Test.Tasty.QuickCheck
 
-import Test.QuickCheck
-import Test.QuickCheck.Test
 import System.IO (hFlush, stdout)
 
 import Control.Monad
@@ -174,9 +172,12 @@
     , testGroup "ECC arithmetic" properties_ecc_arithmetic
     ]
 
-main = defaultMain
-    [ testGroup "KATs" katTests
-    , asymEncryptionTests
-    , asymSignatureTests
-    , asymOtherTests
-    ]
+main = do
+    kats <- sequence newKats
+    defaultMain $ testGroup "crypto-pubkey"
+        [ testGroup "KATs" katTests
+        , testGroup "KAT2s" kats
+        , asymEncryptionTests
+        , asymSignatureTests
+        , asymOtherTests
+        ]
diff --git a/crypto-pubkey.cabal b/crypto-pubkey.cabal
--- a/crypto-pubkey.cabal
+++ b/crypto-pubkey.cabal
@@ -1,5 +1,5 @@
 Name:                crypto-pubkey
-Version:             0.2.7
+Version:             0.2.8
 Description:
     Public Key cryptography
     .
@@ -58,11 +58,10 @@
                    , crypto-pubkey-types
                    , crypto-numbers
                    , crypto-random
-                   , QuickCheck >= 2
-                   , HUnit
-                   , test-framework >= 0.3.3
-                   , test-framework-quickcheck2 >= 0.2.9
-                   , test-framework-hunit
+                   , tasty
+                   , tasty-quickcheck
+                   , tasty-hunit
+                   , tasty-kat
 
 Benchmark bench-crypto-pubkey
   hs-source-dirs:    Benchs
