libsecp256k1-0.1.0: test/Crypto/Secp256k1/PrimSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Crypto.Secp256k1.PrimSpec (spec) where
import Control.Monad
import Crypto.Secp256k1.Internal
import qualified Data.ByteArray.Encoding as BA
import Data.ByteString (
ByteString,
copy,
packCStringLen,
useAsCStringLen,
)
import Data.Either (fromRight)
import Foreign
import System.Entropy
import Test.HUnit (Assertion, assertBool, assertEqual)
import Test.Hspec
spec :: Spec
spec = do
pure ()
-- describe "housekeeping" $ do
-- it "creates context" createContextTest
-- it "randomizes context" randomizeContextTest
-- it "clones context" cloneContextTest
-- describe "serialization" $ do
-- it "parses public key" ecPubkeyParseTest
-- it "serializes public key" ecPubKeySerializeTest
-- it "parses DER signature" ecdsaSignatureParseDerTest
-- it "serializes DER signature" ecdsaSignatureSerializeDerTest
-- describe "signatures" $ do
-- it "verifies signature" ecdsaVerifyTest
-- it "signs message" ecdsaSignTest
-- describe "secret keys" $ do
-- it "verifies secret key" ecSecKeyVerifyTest
-- it "creates public key" ecPubkeyCreateTest
-- it "adds secret key" ecSecKeyTweakAddTest
-- it "multiplies secret key" ecSecKeyTweakMulTest
-- describe "public keys" $ do
-- it "adds public key" ecPubKeyTweakAddTest
-- it "multiplies public key" ecPubKeyTweakMulTest
-- it "combines public keys" ecPubKeyCombineTest
-- withEntropy :: (Ptr Seed32 -> IO a) -> IO a
-- withEntropy f =
-- getEntropy 32 >>= \e ->
-- useByteString e $ \(s, _) -> f s
-- createContextTest :: Assertion
-- createContextTest = do
-- context_ptr <- liftIO $ contextCreate signVerify
-- assertBool "context not null" $ context_ptr /= nullPtr
-- randomizeContextTest :: Assertion
-- randomizeContextTest = do
-- ret <-
-- liftIO $
-- contextCreate sign >>= \x ->
-- withEntropy (contextRandomize x)
-- assertBool "context randomized" $ isSuccess ret
-- cloneContextTest :: Assertion
-- cloneContextTest = do
-- (x1, x2) <- liftIO $ do
-- x1 <- contextCreate signVerify
-- ret <- withEntropy $ contextRandomize x1
-- unless (isSuccess ret) $ error "failed to randomize context"
-- x2 <- contextClone x1
-- return (x1, x2)
-- assertBool "original context not null" $ x1 /= nullPtr
-- assertBool "cloned context not null" $ x2 /= nullPtr
-- assertBool "context ptrs different" $ x1 /= x2
-- ecPubkeyParseTest :: Assertion
-- ecPubkeyParseTest = do
-- ret <- liftIO $
-- useAsCStringLen der $ \(i, il) -> do
-- x <- contextCreate verify
-- allocaBytes 64 $ \pubkey ->
-- ecPubKeyParse x pubkey (castPtr i) (fromIntegral il)
-- assertBool "parsed public key" (isSuccess ret)
-- where
-- der =
-- fromRight undefined $
-- decodeBase16
-- "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"
-- ecPubKeySerializeTest :: Assertion
-- ecPubKeySerializeTest = do
-- (ret, dec) <- liftIO $
-- useByteString der $ \(i, il) ->
-- allocaBytes 64 $ \k ->
-- alloca $ \ol ->
-- allocaBytes 72 $ \o -> do
-- poke ol 72
-- x <- contextCreate verify
-- ret1 <- ecPubKeyParse x k i il
-- unless (isSuccess ret1) $ error "failed to parse pubkey"
-- ret2 <- ecPubKeySerialize x o ol k compressed
-- len <- fromIntegral <$> peek ol
-- decoded <- packCStringLen (castPtr o, len)
-- return (ret2, decoded)
-- assertBool "serialized public key successfully" $ isSuccess ret
-- assertEqual "public key matches" der dec
-- where
-- der =
-- fromRight undefined $
-- decodeBase16
-- "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"
-- ecdsaSignatureParseDerTest :: Assertion
-- ecdsaSignatureParseDerTest = do
-- ret <- liftIO $
-- useAsCStringLen der $ \(d, dl) -> allocaBytes 64 $ \s -> do
-- x <- contextCreate verify
-- ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)
-- assertBool "parsed signature successfully" $ isSuccess ret
-- where
-- der =
-- fromRight undefined $
-- decodeBase16
-- "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
-- \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
-- \45"
-- parseDer :: Ctx -> ByteString -> IO ByteString
-- parseDer x bs =
-- useAsCStringLen bs $ \(d, dl) ->
-- allocaBytes 64 $ \s -> do
-- ret <- ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)
-- unless (isSuccess ret) $ error "could not parse DER"
-- packByteString (s, 64)
-- ecdsaSignatureSerializeDerTest :: Assertion
-- ecdsaSignatureSerializeDerTest = do
-- (ret, enc) <- liftIO $ do
-- x <- contextCreate verify
-- sig <- parseDer x der
-- alloca $ \ol ->
-- allocaBytes 72 $ \o ->
-- useByteString sig $ \(s, _) -> do
-- poke ol 72
-- ret <- ecdsaSignatureSerializeDer x o ol s
-- len <- fromIntegral <$> peek ol
-- enc <- packCStringLen (castPtr o, len)
-- return (ret, enc)
-- assertBool "serialization successful" $ isSuccess ret
-- assertEqual "signatures match" der enc
-- where
-- der =
-- fromRight undefined $
-- decodeBase16
-- "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
-- \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
-- \45"
-- ecdsaVerifyTest :: Assertion
-- ecdsaVerifyTest = do
-- ret <- liftIO $ do
-- x <- contextCreate verify
-- sig <- parseDer x der
-- pk <- useByteString pub $ \(p, pl) ->
-- allocaBytes 64 $ \k -> do
-- ret <- ecPubKeyParse x k p (fromIntegral pl)
-- unless (isSuccess ret) $ error "could not parse public key"
-- packByteString (k, 64)
-- useByteString msg $ \(m, _) ->
-- useByteString pk $ \(k, _) ->
-- useByteString sig $ \(s, _) ->
-- ecdsaVerify x s m k
-- assertBool "signature valid" $ isSuccess ret
-- where
-- der =
-- fromRight undefined $
-- decodeBase16
-- "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
-- \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
-- \45"
-- pub =
-- fromRight undefined $
-- decodeBase16
-- "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
-- \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-- msg =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- signCtx :: IO Ctx
-- signCtx =
-- contextCreate sign >>= \c ->
-- withEntropy (contextRandomize c) >>= \r ->
-- unless (isSuccess r) (error "failed to randomize context") >> return c
-- createPubKey :: Ctx -> Ptr SecKey32 -> Ptr PubKey64 -> IO ()
-- createPubKey x k p = do
-- ret <- ecPubKeyCreate x p k
-- unless (isSuccess ret) $ error "failed to create public key"
-- ecdsaSignTest :: Assertion
-- ecdsaSignTest = do
-- der <- liftIO $ do
-- x <- signCtx
-- allocaBytes 64 $ \s ->
-- useByteString msg $ \(m, _) ->
-- useByteString key $ \(k, _) ->
-- alloca $ \ol ->
-- allocaBytes 72 $ \o -> do
-- poke ol 72
-- ret1 <- ecdsaSign x s m k nullFunPtr nullPtr
-- unless (isSuccess ret1) $ error "could not sign message"
-- ret2 <- ecdsaSignatureSerializeDer x o ol s
-- unless (isSuccess ret2) $ error "could not serialize signature"
-- len <- peek ol
-- packCStringLen (castPtr o, fromIntegral len)
-- ret <- liftIO $ do
-- pub <- allocaBytes 64 $ \p ->
-- useByteString key $ \(s, _) -> do
-- x <- signCtx
-- createPubKey x s p
-- packByteString (p, 64)
-- useByteString msg $ \(m, _) ->
-- useByteString pub $ \(p, _) -> do
-- x <- contextCreate verify
-- s' <- parseDer x der
-- useByteString s' $ \(s, _) -> ecdsaVerify x s m p
-- assertBool "signature matches" (isSuccess ret)
-- where
-- msg =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- key =
-- fromRight undefined $
-- decodeBase16
-- "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-- ecSecKeyVerifyTest :: Assertion
-- ecSecKeyVerifyTest = do
-- ret <- liftIO $
-- useByteString key $ \(k, _) -> do
-- x <- signCtx
-- ecSecKeyVerify x k
-- assertBool "valid secret key" $ isSuccess ret
-- where
-- key =
-- fromRight undefined $
-- decodeBase16
-- "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-- ecPubkeyCreateTest :: Assertion
-- ecPubkeyCreateTest = do
-- pk <- liftIO $
-- useByteString key $ \(s, _) ->
-- allocaBytes 64 $ \k -> do
-- x <- signCtx
-- createPubKey x s k
-- allocaBytes 65 $ \o ->
-- alloca $ \ol -> do
-- poke ol 65
-- rets <- ecPubKeySerialize x o ol k uncompressed
-- unless (isSuccess rets) $ error "failed to serialize public key"
-- len <- fromIntegral <$> peek ol
-- packCStringLen (castPtr o, len)
-- assertEqual "public key matches" pub pk
-- where
-- key =
-- fromRight undefined $
-- decodeBase16
-- "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-- pub =
-- fromRight undefined $
-- decodeBase16
-- "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
-- \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-- ecSecKeyTweakAddTest :: Assertion
-- ecSecKeyTweakAddTest = do
-- (ret, tweaked) <-
-- liftIO $
-- signCtx >>= \x ->
-- useByteString tweak $ \(w, _) ->
-- useByteString key $ \(k, _) -> do
-- ret <- ecSecKeyTweakAdd x k w
-- tweaked <- packByteString (k, 32)
-- return (ret, tweaked)
-- assertBool "successful secret key tweak" $ isSuccess ret
-- assertEqual "tweaked keys match" expected tweaked
-- where
-- key =
-- fromRight undefined $
-- decodeBase16
-- "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-- tweak =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- expected =
-- fromRight undefined $
-- decodeBase16
-- "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"
-- ecSecKeyTweakMulTest :: Assertion
-- ecSecKeyTweakMulTest = do
-- (ret, tweaked) <- liftIO $ do
-- x <- contextCreate sign
-- retr <- withEntropy $ contextRandomize x
-- unless (isSuccess retr) $ error "failed to randomize context"
-- useByteString tweak $ \(w, _) -> useByteString key $ \(k, _) -> do
-- ret <- ecSecKeyTweakMul x k w
-- tweaked <- packByteString (k, 32)
-- return (ret, tweaked)
-- assertBool "successful secret key tweak" $ isSuccess ret
-- assertEqual "tweaked keys match" expected tweaked
-- where
-- key =
-- fromRight undefined $
-- decodeBase16
-- "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-- tweak =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- expected =
-- fromRight undefined $
-- decodeBase16
-- "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"
-- serializeKey :: Ctx -> Ptr PubKey64 -> IO ByteString
-- serializeKey x p = allocaBytes 72 $ \d -> alloca $ \dl -> do
-- poke dl 72
-- ret <- ecPubKeySerialize x d dl p uncompressed
-- unless (isSuccess ret) $ error "could not serialize public key"
-- len <- peek dl
-- packCStringLen (castPtr d, fromIntegral len)
-- parseKey :: Ctx -> ByteString -> IO ByteString
-- parseKey x bs =
-- allocaBytes 64 $ \p ->
-- useByteString bs $ \(d, dl) -> do
-- ret <- ecPubKeyParse x p d dl
-- unless (isSuccess ret) $ error "could not parse public key"
-- packByteString (p, 64)
-- ecPubKeyTweakAddTest :: Assertion
-- ecPubKeyTweakAddTest = do
-- (ret, tweaked) <- liftIO $ do
-- x <- contextCreate verify
-- pk <- copy <$> parseKey x pub
-- useByteString tweak $ \(w, _) ->
-- useByteString pk $ \(p, _) -> do
-- ret <- ecPubKeyTweakAdd x p w
-- tweaked <- serializeKey x p
-- return (ret, tweaked)
-- assertBool "successful secret key tweak" $ isSuccess ret
-- assertEqual "tweaked keys match" expected tweaked
-- where
-- pub =
-- fromRight undefined $
-- decodeBase16
-- "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
-- \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-- tweak =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- expected =
-- fromRight undefined $
-- decodeBase16
-- "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\
-- \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"
-- ecPubKeyTweakMulTest :: Assertion
-- ecPubKeyTweakMulTest = do
-- (ret, tweaked) <- liftIO $ do
-- x <- contextCreate verify
-- pk <- copy <$> parseKey x pub
-- useByteString tweak $ \(w, _) ->
-- useByteString pk $ \(p, _) -> do
-- ret <- ecPubKeyTweakMul x p w
-- tweaked <- serializeKey x p
-- return (ret, tweaked)
-- assertBool "successful secret key tweak" $ isSuccess ret
-- assertEqual "tweaked keys match" expected tweaked
-- where
-- pub =
-- fromRight undefined $
-- decodeBase16
-- "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
-- \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-- tweak =
-- fromRight undefined $
-- decodeBase16
-- "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-- expected =
-- fromRight undefined $
-- decodeBase16
-- "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\
-- \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"
-- ecPubKeyCombineTest :: Assertion
-- ecPubKeyCombineTest = do
-- (ret, com) <- liftIO $
-- allocaBytes 64 $ \p1 ->
-- allocaBytes 64 $ \p2 ->
-- allocaBytes 64 $ \p3 ->
-- allocaArray 3 $ \a ->
-- allocaBytes 64 $ \p -> do
-- x <- contextCreate verify
-- parse x pub1 p1
-- parse x pub2 p2
-- parse x pub3 p3
-- pokeArray a [p1, p2, p3]
-- ret <- ecPubKeyCombine x p a 3
-- com <- serializeKey x p
-- return (ret, com)
-- assertBool "successful key combination" $ isSuccess ret
-- assertEqual "combined keys match" expected com
-- where
-- parse x pub p = useByteString pub $ \(d, dl) -> do
-- ret <- ecPubKeyParse x p d dl
-- unless (isSuccess ret) $ error "could not parse public key"
-- pub1 =
-- fromRight undefined $
-- decodeBase16
-- "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
-- \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-- pub2 =
-- fromRight undefined $
-- decodeBase16
-- "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d153f5\
-- \77dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"
-- pub3 =
-- fromRight undefined $
-- decodeBase16
-- "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee3feb\
-- \d908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"
-- expected =
-- fromRight undefined $
-- decodeBase16
-- "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\
-- \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"