packages feed

secp256k1-0.1.0: test/Crypto/Secp256k1/Tests.hs

module Crypto.Secp256k1.Tests (tests) where

import           Crypto.Secp256k1
import qualified Data.ByteString                      as BS
import qualified Data.ByteString.Base16               as B16
import qualified Data.ByteString.Char8                as B8
import           Data.Maybe
import           Test.Framework                       (Test, testGroup)
import           Test.Framework.Providers.HUnit       (testCase)
import           Test.Framework.Providers.QuickCheck2 (testProperty)
import           Test.HUnit                           (Assertion, assertEqual)
import           Test.QuickCheck

tests :: [Test]
tests =
    [ testGroup "Signing"
        [ testProperty "Signing messages" signMsgTest
        , testProperty "Bad signatures" badSignatureTest
        ]
    , testGroup "Serialization"
        [ testProperty "Serialize public key" serializePubKeyTest
        , testProperty "Serialize signature" serializeSigTest
        , testProperty "Serialize secret key" serializeSecKeyTest
        ]
    , testGroup "Tweaks"
        [ testCase "Tweak add secret key" tweakAddSecKeyTest
        , testCase "Tweak multiply secret key" tweakMulSecKeyTest
        , testCase "Tweak add public key" tweakAddPubKeyTest
        , testCase "Tweak multiply public key" tweakMulPubKeyTest
        , testCase "Combine public keys" combinePubKeyTest
        ]
    ]

newtype GenMsg = GenMsg Msg deriving (Show, Eq)
newtype GenSecKey = GenSecKey SecKey deriving (Show, Eq)
newtype GenPubKey = GenPubKey PubKey deriving (Show, Eq)

instance Arbitrary GenMsg where
    arbitrary = gen_msg
      where
        valid_bs = bs_gen `suchThat` isJust
        bs_gen = (msg . BS.pack) <$> sequence (replicate 32 arbitrary)
        gen_msg = (GenMsg . fromJust) <$> valid_bs

instance Arbitrary GenSecKey where
    arbitrary = gen_key
      where
        valid_bs = bs_gen `suchThat` isJust
        bs_gen = (secKey . BS.pack) <$> sequence (replicate 32 arbitrary)
        gen_key = (GenSecKey . fromJust) <$> valid_bs

instance Arbitrary GenPubKey where
    arbitrary = do
        GenSecKey key <- arbitrary
        return $ GenPubKey $ pubKey key

signMsgTest :: (GenMsg, GenSecKey) -> Bool
signMsgTest (GenMsg fm, GenSecKey fk) = verifySig fp fg fm where
    fp = pubKey fk
    fg = signMsg fk fm

badSignatureTest :: (GenMsg, GenSecKey, GenPubKey) -> Bool
badSignatureTest (GenMsg fm, GenSecKey fk, GenPubKey fp) =
    not $ verifySig fp fg fm
  where
    fg = signMsg fk fm

serializePubKeyTest :: (GenPubKey, Bool) -> Bool
serializePubKeyTest (GenPubKey fp, b) =
    case importPubKey $ exportPubKey b fp of
        Just fp' -> fp == fp'
        Nothing -> False

serializeSigTest :: (GenMsg, GenSecKey) -> Bool
serializeSigTest (GenMsg fm, GenSecKey fk) =
    case importSig $ exportSig fg of
        Just fg' -> fg == fg'
        Nothing -> False
  where
    fg = signMsg fk fm

serializeSecKeyTest :: (GenSecKey, Bool) -> Bool
serializeSecKeyTest (GenSecKey fk, b) =
    case importSecKey $ exportSecKey b fk of
        Just fk' -> fk == fk'
        Nothing -> False

tweakAddSecKeyTest :: Assertion
tweakAddSecKeyTest =
    assertEqual "tweaked keys match" expected tweaked
  where
    tweaked = do
        key <- secKey $ fst $ B16.decode $ B8.pack $
            "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
        twk <- tweak $ fst $ B16.decode $ B8.pack $
            "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
        tweakAddSecKey key twk
    expected = secKey $ fst $ B16.decode $ B8.pack $
        "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"

tweakMulSecKeyTest :: Assertion
tweakMulSecKeyTest =
    assertEqual "tweaked keys match" expected tweaked
  where
    tweaked = do
        key <- secKey $ fst $ B16.decode $ B8.pack $
            "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
        twk <- tweak $ fst $ B16.decode $ B8.pack $
            "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
        tweakMulSecKey key twk
    expected = secKey $ fst $ B16.decode $ B8.pack $
        "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"

tweakAddPubKeyTest :: Assertion
tweakAddPubKeyTest =
    assertEqual "tweaked keys match" expected tweaked
  where
    tweaked = do
        pub <- importPubKey $ fst $ B16.decode $ B8.pack $
            "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705\
            \12213d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
        twk <- tweak $ fst $ B16.decode $ B8.pack $
            "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
        tweakAddPubKey pub twk
    expected = importPubKey $ fst $ B16.decode $ B8.pack $
        "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\
        \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"

tweakMulPubKeyTest :: Assertion
tweakMulPubKeyTest =
    assertEqual "tweaked keys match" expected tweaked
  where
    tweaked = do
        pub <- importPubKey $ fst $ B16.decode $ B8.pack $
            "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705\
            \12213d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
        twk <- tweak $ fst $ B16.decode $ B8.pack $
            "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
        tweakMulPubKey pub twk
    expected = importPubKey $ fst $ B16.decode $ B8.pack $
        "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\
        \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"

combinePubKeyTest :: Assertion
combinePubKeyTest =
    assertEqual "combined keys match" expected combined
  where
    combined = do
        pub1 <- importPubKey $ fst $ B16.decode $ B8.pack
            "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705\
            \12213d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
        pub2 <- importPubKey $ fst $ B16.decode $ B8.pack
            "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d1\
            \53f577dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"
        pub3 <- importPubKey $ fst $ B16.decode $ B8.pack
            "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee\
            \3febd908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"
        combinePubKeys [pub1, pub2, pub3]
    expected = importPubKey $ fst $ B16.decode $ B8.pack
        "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\
        \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"