web3-tools-0.1.0.0: test/Crypto/Secp256k1/RecoverySpec.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Crypto.Secp256k1.RecoverySpec (spec) where
import Crypto.Secp256k1.Recovery (recoverPubKey)
import qualified Data.ByteString as BS
import Data.Maybe (isJust, isNothing)
import Test.Hspec
import Test.QuickCheck
import Test.QuickCheck.Monadic
-- Arbitrary instance for ByteString
instance Arbitrary BS.ByteString where
arbitrary = BS.pack <$> arbitrary
spec :: Spec
spec = do
describe "recoverPubKey" $ do
describe "input validation" $ do
it "rejects signature that is too short" $ do
let message = BS.replicate 32 0
sig = BS.replicate 64 0 -- Should be 65
result <- recoverPubKey message sig
result `shouldBe` Nothing
it "rejects signature that is too long" $ do
let message = BS.replicate 32 0
sig = BS.replicate 66 0 -- Should be 65
result <- recoverPubKey message sig
result `shouldBe` Nothing
it "rejects message that is too short" $ do
let message = BS.replicate 31 0 -- Should be 32
sig = BS.replicate 65 0
result <- recoverPubKey message sig
result `shouldBe` Nothing
it "rejects message that is too long" $ do
let message = BS.replicate 33 0 -- Should be 32
sig = BS.replicate 65 0
result <- recoverPubKey message sig
result `shouldBe` Nothing
describe "property-based tests" $ do
it "always returns Nothing or Just a 65-byte public key" $ property $
\(message :: BS.ByteString) (sig :: BS.ByteString) -> monadicIO $ do
result <- run $ recoverPubKey message sig
monitor $ classify (isNothing result) "returned Nothing"
monitor $ classify (isJust result) "returned Just pubKey"
case result of
Nothing -> return True
Just pubKey -> return $ BS.length pubKey == 65
it "returns Nothing for invalid signature lengths" $ property $
forAll (choose (0, 128) `suchThat` (/= 65)) $ \len -> monadicIO $ do
let message = BS.replicate 32 0
sig = BS.replicate len 0
result <- run $ recoverPubKey message sig
return $ result == Nothing
it "returns Nothing for invalid message lengths" $ property $
forAll (choose (0, 64) `suchThat` (/= 32)) $ \len -> monadicIO $ do
let message = BS.replicate len 0
sig = BS.replicate 65 0
result <- run $ recoverPubKey message sig
return $ result == Nothing