secp256k1

Pure Haskell cryptographic primitives on the secp256k1 elliptic curve.
git clone git://git.ppad.tech/secp256k1.git
Log | Files | Refs | LICENSE

commit 5fa9baac3bf659987fe41dfe36e2ef1de9b6fe98
parent 9b53ae8528fdf9ba32566ac98f4a4d88b08f00a3
Author: Jared Tobin <jared@jtobin.io>
Date:   Thu, 10 Oct 2024 22:42:38 +0400

test: add noble invalid vectors

Diffstat:
Mtest/Noble.hs | 48++++++++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/test/Noble.hs b/test/Noble.hs @@ -7,6 +7,7 @@ module Noble ( , execute_ecdsa ) where +import Control.Exception import Crypto.Curve.Secp256k1 import Data.Aeson ((.:)) import qualified Data.Aeson as A @@ -16,7 +17,7 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as TE import qualified GHC.Num.Integer as I import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (assertEqual, testCase) +import Test.Tasty.HUnit (assertEqual, assertBool, assertFailure, testCase) data Ecdsa = Ecdsa { ec_valid :: ![(Int, ValidTest)] @@ -25,8 +26,12 @@ data Ecdsa = Ecdsa { execute_ecdsa :: Ecdsa -> TestTree execute_ecdsa Ecdsa {..} = testGroup "noble_ecdsa" [ - testGroup "valid" (fmap execute_valid ec_valid) - ] + testGroup "valid" (fmap execute_valid ec_valid) + , testGroup "invalid (sign)" (fmap execute_invalid_sign iv_sign) + , testGroup "invalid (verify)" (fmap execute_invalid_verify iv_verify) + ] + where + InvalidTest {..} = ec_invalid execute_valid :: (Int, ValidTest) -> TestTree execute_valid (label, ValidTest {..}) = @@ -37,6 +42,29 @@ execute_valid (label, ValidTest {..}) = sig = _sign_no_hash x msg assertEqual mempty pec sig +execute_invalid_sign :: (Int, InvalidSignTest) -> TestTree +execute_invalid_sign (label, InvalidSignTest {..}) = + testCase ("noble-secp256k1, invalid sign (" <> show label <> ")") $ do + let x = ivs_d + m = ivs_m + err <- catch (pure (_sign_no_hash x m) >> pure False) handler + if err + then assertFailure "expected error not caught" + else pure () + where + handler :: ErrorCall -> IO Bool + handler _ = pure True + +execute_invalid_verify :: (Int, InvalidVerifyTest) -> TestTree +execute_invalid_verify (label, InvalidVerifyTest {..}) = + testCase ("noble-secp256k1, invalid verify (" <> show label <> ")") $ + case parse_point ivv_Q of + Nothing -> assertBool "no parse" True + Just pub -> do + let sig = parse_compact ivv_signature + ver = verify ivv_m pub sig + assertBool mempty (not ver) + fi :: (Integral a, Num b) => a -> b fi = fromIntegral {-# INLINE fi #-} @@ -77,14 +105,14 @@ parse_compact bs = in ECDSA r s data InvalidTest = InvalidTest { - iv_sign :: ![InvalidSignTest] - , iv_verify :: ![InvalidVerifyTest] + iv_sign :: ![(Int, InvalidSignTest)] + , iv_verify :: ![(Int, InvalidVerifyTest)] } deriving Show instance A.FromJSON InvalidTest where parseJSON = A.withObject "InvalidTest" $ \m -> InvalidTest - <$> m .: "sign" - <*> m .: "verify" + <$> fmap (zip [0..]) (m .: "sign") + <*> fmap (zip [0..]) (m .: "verify") data InvalidSignTest = InvalidSignTest { ivs_d :: !Integer @@ -97,14 +125,14 @@ instance A.FromJSON InvalidSignTest where <*> fmap toBS (m .: "m") data InvalidVerifyTest = InvalidVerifyTest { - ivv_Q :: !T.Text -- XX check noble pubkey encoding + ivv_Q :: !BS.ByteString , ivv_m :: !BS.ByteString - , ivv_signature :: !BS.ByteString -- XX to sig (from compact?) + , ivv_signature :: !BS.ByteString } deriving Show instance A.FromJSON InvalidVerifyTest where parseJSON = A.withObject "InvalidVerifyTest" $ \m -> InvalidVerifyTest - <$> m .: "Q" + <$> fmap TE.encodeUtf8 (m .: "Q") <*> fmap toBS (m .: "m") <*> fmap toBS (m .: "signature")