packages feed

secp256k1 0.5.3 → 1.0.0

raw patch · 7 files changed

+838/−835 lines, 7 filesdep +hspecdep −test-frameworkdep −test-framework-hunitdep −test-framework-quickcheck2dep ~base

Dependencies added: hspec

Dependencies removed: test-framework, test-framework-hunit, test-framework-quickcheck2

Dependency ranges changed: base

Files

secp256k1.cabal view
@@ -1,149 +1,167 @@-name:                secp256k1-version:             0.5.3-synopsis:            Bindings for secp256k1 library from Bitcoin Core-description:         Please see README.md-homepage:            http://github.com/haskoin/secp256k1-haskell#readme-license:             PublicDomain-license-file:        UNLICENSE-author:              Jean-Pierre Rupp-maintainer:          xenog@protonmail.com-copyright:           (c) 2017 Jean-Pierre Rupp-category:            Crypto-build-type:          Custom+-- This file has been generated from package.yaml by hpack version 0.28.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: 9fd6f5be2cfb4b06721e74cd378459ffdf2d51e1a03a62d8484d9d342e985261++name:           secp256k1+version:        1.0.0+synopsis:       Bindings for secp256k1 library from Bitcoin Core+description:    Sign and verify signatures using the very fast C secp256k1 library from Pieter Wuille. Has Haskell types and abstractions for keys and signatures.+category:       Crypto+homepage:       http://github.com/haskoin/secp256k1-haskell#readme+bug-reports:    https://github.com/haskoin/secp256k1-haskell.git/issues+author:         Jean-Pierre Rupp+maintainer:     xenog@protonmail.com+copyright:      (c) 2017 Jean-Pierre Rupp+license:        PublicDomain+license-file:   UNLICENSE+build-type:     Simple+cabal-version:  >= 1.10 extra-source-files:-    secp256k1/README.md+    README.md     secp256k1/autogen.sh+    secp256k1/build-aux/m4/ax_jni_include_dir.m4+    secp256k1/build-aux/m4/ax_prog_cc_for_build.m4+    secp256k1/build-aux/m4/bitcoin_secp.m4     secp256k1/configure.ac-    secp256k1/Makefile.am+    secp256k1/contrib/lax_der_parsing.c+    secp256k1/contrib/lax_der_parsing.h+    secp256k1/contrib/lax_der_privatekey_parsing.c+    secp256k1/contrib/lax_der_privatekey_parsing.h     secp256k1/COPYING-    secp256k1/src/num_impl.h-    secp256k1/src/bench_verify.c-    secp256k1/src/gen_context.c-    secp256k1/src/bench_recover.c+    secp256k1/include/secp256k1.h+    secp256k1/include/secp256k1_ecdh.h+    secp256k1/include/secp256k1_recovery.h+    secp256k1/libsecp256k1.pc.in+    secp256k1/Makefile.am+    secp256k1/README.md+    secp256k1/sage/group_prover.sage+    secp256k1/sage/secp256k1.sage+    secp256k1/sage/weierstrass_prover.sage+    secp256k1/src/asm/field_10x26_arm.s     secp256k1/src/basic-config.h+    secp256k1/src/bench.h     secp256k1/src/bench_ecdh.c-    secp256k1/src/ecmult_const.h-    secp256k1/src/scalar_low.h-    secp256k1/src/tests_exhaustive.c+    secp256k1/src/bench_internal.c+    secp256k1/src/bench_recover.c+    secp256k1/src/bench_schnorr_verify.c+    secp256k1/src/bench_sign.c+    secp256k1/src/bench_verify.c+    secp256k1/src/ecdsa.h     secp256k1/src/ecdsa_impl.h-    secp256k1/src/ecmult_impl.h+    secp256k1/src/eckey.h+    secp256k1/src/eckey_impl.h+    secp256k1/src/ecmult.h+    secp256k1/src/ecmult_const.h+    secp256k1/src/ecmult_const_impl.h+    secp256k1/src/ecmult_gen.h     secp256k1/src/ecmult_gen_impl.h-    secp256k1/src/scalar_8x32.h-    secp256k1/src/scalar_8x32_impl.h-    secp256k1/src/group.h-    secp256k1/src/testrand_impl.h-    secp256k1/src/modules/ecdh/main_impl.h-    secp256k1/src/modules/ecdh/tests_impl.h-    secp256k1/src/modules/ecdh/Makefile.am.include-    secp256k1/src/modules/recovery/main_impl.h-    secp256k1/src/modules/recovery/tests_impl.h-    secp256k1/src/modules/recovery/Makefile.am.include-    secp256k1/src/ecdsa.h-    secp256k1/src/testrand.h-    secp256k1/src/bench_internal.c+    secp256k1/src/ecmult_impl.h+    secp256k1/src/field.h+    secp256k1/src/field_10x26.h     secp256k1/src/field_10x26_impl.h-    secp256k1/src/eckey.h     secp256k1/src/field_5x52.h     secp256k1/src/field_5x52_asm_impl.h-    secp256k1/src/asm/field_10x26_arm.s-    secp256k1/src/field_10x26.h-    secp256k1/src/util.h-    secp256k1/src/num.h-    secp256k1/src/num_gmp.h-    secp256k1/src/scalar_4x64_impl.h-    secp256k1/src/hash.h-    secp256k1/src/scalar_4x64.h-    secp256k1/src/hash_impl.h-    secp256k1/src/tests.c-    secp256k1/src/scalar_impl.h-    secp256k1/src/bench_sign.c-    secp256k1/src/field_5x52_int128_impl.h     secp256k1/src/field_5x52_impl.h-    secp256k1/src/field.h-    secp256k1/src/secp256k1.c+    secp256k1/src/field_5x52_int128_impl.h+    secp256k1/src/field_impl.h+    secp256k1/src/gen_context.c+    secp256k1/src/group.h     secp256k1/src/group_impl.h-    secp256k1/src/java/org_bitcoin_NativeSecp256k1.h-    secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java+    secp256k1/src/hash.h+    secp256k1/src/hash_impl.h     secp256k1/src/java/org/bitcoin/NativeSecp256k1.java-    secp256k1/src/java/org/bitcoin/Secp256k1Context.java+    secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java     secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java-    secp256k1/src/java/org_bitcoin_Secp256k1Context.h+    secp256k1/src/java/org/bitcoin/Secp256k1Context.java     secp256k1/src/java/org_bitcoin_NativeSecp256k1.c+    secp256k1/src/java/org_bitcoin_NativeSecp256k1.h     secp256k1/src/java/org_bitcoin_Secp256k1Context.c-    secp256k1/src/ecmult_gen.h-    secp256k1/src/ecmult_const_impl.h-    secp256k1/src/eckey_impl.h-    secp256k1/src/field_impl.h-    secp256k1/src/bench.h-    secp256k1/src/scalar_low_impl.h-    secp256k1/src/bench_schnorr_verify.c-    secp256k1/src/scalar.h+    secp256k1/src/java/org_bitcoin_Secp256k1Context.h+    secp256k1/src/modules/ecdh/main_impl.h+    secp256k1/src/modules/ecdh/Makefile.am.include+    secp256k1/src/modules/ecdh/tests_impl.h+    secp256k1/src/modules/recovery/main_impl.h+    secp256k1/src/modules/recovery/Makefile.am.include+    secp256k1/src/modules/recovery/tests_impl.h+    secp256k1/src/num.h+    secp256k1/src/num_gmp.h     secp256k1/src/num_gmp_impl.h-    secp256k1/src/ecmult.h+    secp256k1/src/num_impl.h+    secp256k1/src/scalar.h+    secp256k1/src/scalar_4x64.h+    secp256k1/src/scalar_4x64_impl.h+    secp256k1/src/scalar_8x32.h+    secp256k1/src/scalar_8x32_impl.h+    secp256k1/src/scalar_impl.h+    secp256k1/src/scalar_low.h+    secp256k1/src/scalar_low_impl.h+    secp256k1/src/secp256k1.c+    secp256k1/src/testrand.h+    secp256k1/src/testrand_impl.h+    secp256k1/src/tests.c+    secp256k1/src/tests_exhaustive.c+    secp256k1/src/util.h     secp256k1/TODO-    secp256k1/include/secp256k1_recovery.h-    secp256k1/include/secp256k1.h-    secp256k1/include/secp256k1_ecdh.h-    secp256k1/contrib/lax_der_parsing.c-    secp256k1/contrib/lax_der_privatekey_parsing.c-    secp256k1/contrib/lax_der_privatekey_parsing.h-    secp256k1/contrib/lax_der_parsing.h-    secp256k1/libsecp256k1.pc.in-    secp256k1/sage/group_prover.sage-    secp256k1/sage/weierstrass_prover.sage-    secp256k1/sage/secp256k1.sage-    secp256k1/build-aux/m4/ax_jni_include_dir.m4-    secp256k1/build-aux/m4/ax_prog_cc_for_build.m4-    secp256k1/build-aux/m4/bitcoin_secp.m4-    README.md-cabal-version:       >=1.10 -library-    hs-source-dirs:      src-    exposed-modules:     Crypto.Secp256k1-                       , Crypto.Secp256k1.Internal-    build-depends:       base >= 4.8 && < 5-                       , base16-bytestring-                       , bytestring-                       , cereal-                       , entropy-                       , mtl-                       , QuickCheck-                       , string-conversions-    default-language:    Haskell2010-    ghc-options:         -Wall-    cc-options:          -DHAVE_CONFIG_H-    c-sources:           secp256k1/src/secp256k1.c, secp256k1/contrib/lax_der_parsing.c, secp256k1/contrib/lax_der_privatekey_parsing.c-    include-dirs:        secp256k1, secp256k1/contrib, secp256k1/include--test-suite secp256k1-test-    type:                exitcode-stdio-1.0-    hs-source-dirs:      test-    main-is:             Spec.hs-    other-modules:       Crypto.Secp256k1.Tests-                       , Crypto.Secp256k1.Internal.Tests-    build-depends:       base-                       , base16-bytestring-                       , bytestring-                       , cereal-                       , cryptohash-                       , entropy-                       , HUnit-                       , mtl-                       , QuickCheck-                       , secp256k1-                       , string-conversions-                       , test-framework-                       , test-framework-hunit-                       , test-framework-quickcheck2-    ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N-    default-language:    Haskell2010- source-repository head-    type:     git-    location: https://github.com/haskoin/secp256k1-haskell.git+  type: git+  location: https://github.com/haskoin/secp256k1-haskell.git -custom-setup-    setup-depends:       base >= 4.8 && < 5-                       , Cabal >= 1.10+library+  hs-source-dirs:+      src+  ghc-options: -Wall+  cc-options: -DHAVE_CONFIG_H+  include-dirs:+      secp256k1+      secp256k1/contrib+      secp256k1/include+  c-sources:+      secp256k1/contrib/lax_der_parsing.c+      secp256k1/contrib/lax_der_privatekey_parsing.c+      secp256k1/src/secp256k1.c+  build-depends:+      HUnit+    , QuickCheck+    , base >=4.8 && <5+    , base16-bytestring+    , bytestring+    , cereal+    , cryptohash+    , entropy+    , hspec+    , mtl+    , string-conversions+  exposed-modules:+      Crypto.Secp256k1+      Crypto.Secp256k1.Internal+  other-modules:+      Paths_secp256k1+  default-language: Haskell2010 +test-suite spec+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Crypto.Secp256k1.InternalSpec+      Crypto.Secp256k1Spec+      Paths_secp256k1+  hs-source-dirs:+      test+  build-depends:+      HUnit+    , QuickCheck+    , base >=4.8 && <5+    , base16-bytestring+    , bytestring+    , cereal+    , cryptohash+    , entropy+    , hspec ==2.*+    , mtl+    , secp256k1+    , string-conversions+  default-language: Haskell2010+  build-tool-depends: hspec-discover:hspec-discover == 2.*
src/Crypto/Secp256k1.hs view
@@ -88,7 +88,7 @@  instance Read PubKey where     readPrec = parens $ do-        Ident "PubKey" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ importPubKey =<< decodeHex str @@ -98,11 +98,11 @@  instance Show PubKey where     showsPrec d k = showParen (d > 10) $-        showString "PubKey " . shows (B16.encode $ exportPubKey True k)+        showString "fromString " . shows (B16.encode $ exportPubKey True k)  instance Read Msg where     readPrec = parens $ do-        Ident "Msg" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ msg =<< decodeHex str @@ -112,11 +112,11 @@  instance Show Msg where     showsPrec d m = showParen (d > 10) $-        showString "Msg " . shows (B16.encode $ getMsg m)+        showString "fromString " . shows (B16.encode $ getMsg m)  instance Read Sig where     readPrec = parens $ do-        Ident "Sig" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ importSig =<< decodeHex str @@ -126,7 +126,7 @@  instance Show Sig where     showsPrec d s = showParen (d > 10) $-        showString "Sig " . shows (B16.encode $ exportSig s)+        showString "fromString " . shows (B16.encode $ exportSig s)  recSigFromString :: String -> Maybe RecSig recSigFromString str = do@@ -136,7 +136,7 @@  instance Read RecSig where     readPrec = parens $ do-        Ident "RecSig" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ recSigFromString str @@ -147,11 +147,11 @@  instance Show RecSig where     showsPrec d s = showParen (d > 10) $-        showString "RecSig " . shows (B16.encode . encode $ exportCompactRecSig s)+        showString "fromString " . shows (B16.encode . encode $ exportCompactRecSig s)  instance Read SecKey where     readPrec = parens $ do-        Ident "SecKey" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ secKey =<< decodeHex str @@ -161,11 +161,11 @@  instance Show SecKey where     showsPrec d k = showParen (d > 10) $-        showString "SecKey " . shows (B16.encode $ getSecKey k)+        showString "fromString " . shows (B16.encode $ getSecKey k)  instance Read Tweak where     readPrec = parens $ do-        Ident "Tweak" <- lexP+        Ident "fromString" <- lexP         String str <- lexP         maybe pfail return $ tweak =<< decodeHex str @@ -175,7 +175,7 @@  instance Show Tweak where     showsPrec d k = showParen (d > 10) $-        showString "Tweak " . shows (B16.encode $ getTweak k)+        showString "fromString " . shows (B16.encode $ getTweak k)  instance Eq PubKey where     fp1 == fp2 = getPubKey fp1 == getPubKey fp2
− test/Crypto/Secp256k1/Internal/Tests.hs
@@ -1,437 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-module Crypto.Secp256k1.Internal.Tests (tests) where--import           Control.Monad-import           Control.Monad.Trans-import           Crypto.Secp256k1.Internal-import           Data.ByteString                (ByteString, packCStringLen,-                                                 useAsCStringLen)-import qualified Data.ByteString.Base16         as B16-import           Data.ByteString.Short          (toShort)-import           Foreign-import           System.Entropy-import           Test.Framework                 (Test, testGroup)-import           Test.Framework.Providers.HUnit (testCase)-import           Test.HUnit                     (Assertion, assertBool,-                                                 assertEqual)--tests :: [Test]-tests =-    [ testGroup "Housekeeping"-        [ testCase "Create context"           createContextTest-        , testCase "Randomize context"        randomizeContextTest-        , testCase "Clone context"            cloneContextTest-        ]-    , testGroup "Serialization"-        [ testCase "Parse public key"         ecPubkeyParseTest-        , testCase "Serialize public key"     ecPubKeySerializeTest-        , testCase "Storable public key"      pubkeyStorableTest-        , testCase "Storable signature"       signatureStorableTest-        , testCase "Parse DER signature"      ecdsaSignatureParseDerTest-        , testCase "Lax parse DER signature"  laxDerParseTest-        , testCase "Serialize DER signature"  ecdsaSignatureSerializeDerTest-        ]-    , testGroup "Signatures"-        [ testCase "ECDSA verify"             ecdsaVerifyTest-        -- TODO:-        -- , testCase "RFC6979 nonce function"   nonce_function_rfc6979_test-        , testCase "ECDSA sign"               ecdsaSignTest-        ]-    , testGroup "Secret keys"-        [ testCase "Verify secret key"        ecSecKeyVerifyTest-        , testCase "Create public key"        ecPubkeyCreateTest-        , testCase "Tweak add secret key"     ecSecKeyTweakAddTest-        , testCase "Tweak mult. secret key"   ecSecKeyTweakMulTest-        ]-    , testGroup "Public keys"-        [ testCase "Tweak add public key"     ecPubKeyTweakAddTest-        , testCase "Tweak mult. public key"   ecPubKeyTweakMulTest-        , testCase "Combine public keys"      ecPubKeyCombineTest-        ]-    ]--withEntropy :: (Ptr Seed32 -> IO a) -> IO a-withEntropy f =-    getEntropy 32 >>= \e ->-    alloca $ \s ->-    poke s (Seed32 (toShort e)) >> 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-        alloca $ \pubkey ->-            ecPubKeyParse x pubkey (castPtr i) (fromIntegral il)-    assertBool "parsed public key" (isSuccess ret)-  where-    der = fst $ B16.decode-        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"--ecPubKeySerializeTest :: Assertion-ecPubKeySerializeTest = do-    (ret, dec) <- liftIO $ useAsCStringLen der $ \(i, il) ->-        alloca $ \k -> alloca $ \ol -> allocaBytes 72 $ \o -> do-        poke ol 72-        x <- contextCreate verify-        ret1 <--            ecPubKeyParse x k (castPtr i) (fromIntegral 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 = fst $ B16.decode-        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"--pubkeyStorableTest :: Assertion-pubkeyStorableTest = do-    (pk1, pk2, dec) <- liftIO $ useAsCStringLen der $ \(i, il) -> do-        x <- contextCreate verify-        pk1 <- alloca $ \pk -> do-            ret <--                ecPubKeyParse x pk (castPtr i) (fromIntegral il)-            unless (isSuccess ret) $ error "failed to parse pubkey"-            peek pk-        (pk2, dec) <- alloca $ \pk -> alloca $ \ol -> allocaBytes 72 $ \o -> do-            poke ol 72-            poke pk pk1-            ret <--                ecPubKeySerialize x o ol pk compressed-            unless (isSuccess ret) $ error "failed to serialize pubkey"-            len <- fromIntegral <$> peek ol-            dec <- packCStringLen (castPtr o, len)-            pk2 <- peek pk-            return (pk2, dec)-        return (pk1, pk2, dec)-    assertEqual "poke/peek public key" pk1 pk2-    assertEqual "public key matches" der dec-  where-    der = fst $ B16.decode-        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"--signatureStorableTest :: Assertion-signatureStorableTest = do-    (sig, ret) <- liftIO $ do-        x <- contextCreate verify-        g <- alloca $ \pc -> alloca $ \pg -> do-            poke pc cpt-            ret <- ecdsaSignatureParseCompact x pg (castPtr pc)-            unless (isSuccess ret) $ error "failed to parse signature"-            peek pg-        alloca $ \pc -> alloca $ \pg -> do-            poke pg g-            ret <- ecdsaSignatureSerializeCompact x pc pg-            c <- peek pc-            return (c, ret)-    assertBool "successful serialization" (isSuccess ret)-    assertEqual "signatures match" cpt sig-  where-    cpt = CompactSig-        (toShort $ fst $ B16.decode "f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb22")-        (toShort $ fst $ B16.decode "6f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045")--ecdsaSignatureParseDerTest :: Assertion-ecdsaSignatureParseDerTest = do-    ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do-        x <- contextCreate verify-        ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)-    assertBool "parsed signature successfully" $ isSuccess ret-  where-    der = fst $ B16.decode-        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\-        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\-        \45"--laxDerParseTest :: Assertion-laxDerParseTest = do-    ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do-        x <- contextCreate verify-        laxDerParse x s (castPtr d) (fromIntegral dl)-    assertBool "parsed signature successfully" $ isSuccess ret-  where-    der = fst $ B16.decode-        "30450220f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb\-        \2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045"--parseDer :: Ptr Ctx -> ByteString -> IO Sig64-parseDer x bs = useAsCStringLen bs $ \(d, dl) -> alloca $ \s -> do-    ret <- ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)-    unless (isSuccess ret) $ error "could not parse DER"-    peek s--ecdsaSignatureSerializeDerTest :: Assertion-ecdsaSignatureSerializeDerTest = do-    (ret, enc) <- liftIO $ do-        x <- contextCreate verify-        sig <- parseDer x der-        alloca $ \s -> alloca $ \ol -> allocaBytes 72 $ \o -> do-            poke ol 72-            poke s sig-            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 = fst $ B16.decode-        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\-        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\-        \45"--ecdsaVerifyTest :: Assertion-ecdsaVerifyTest = do-    ret <- liftIO $ do-        x <- contextCreate verify-        sig <- parseDer x der-        pk <- useAsCStringLen pub $ \(p, pl) -> alloca $ \k -> do-            ret <--                ecPubKeyParse x k (castPtr p) (fromIntegral pl)-            unless (isSuccess ret) $ error "could not parse public key"-            peek k-        alloca $ \m -> alloca $ \k -> alloca $ \s -> do-            poke m msg-            poke k pk-            poke s sig-            ecdsaVerify x s m k-    assertBool "signature valid" $ isSuccess ret-  where-    der = fst $ B16.decode-        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\-        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\-        \45"-    pub = fst $ B16.decode-        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\-        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"-    msg = Msg32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"--signCtx :: IO (Ptr Ctx)-signCtx = contextCreate sign >>= \c ->-    withEntropy (contextRandomize c) >>= \r ->-        unless (isSuccess r) (error "failed to randomize context") >> return c--ecdsaSignTest :: Assertion-ecdsaSignTest = do-    (ret, sig) <- liftIO $ do-        x <- signCtx-        alloca $ \s -> alloca $ \m -> alloca $ \k -> alloca $ \ol ->-            allocaBytes 72 $ \o -> do-                poke ol 72-                poke m msg-                poke k key-                ret1 <--                    -- TODO:-                    -- ecdsaSign x s m k nonce_function_default nullPtr-                    ecdsaSign x s m k nullFunPtr nullPtr-                ret2 <- ecdsaSignatureSerializeDer x o ol s-                unless (isSuccess ret2) $ error "could not serialize signature"-                len <- peek ol-                sig <- packCStringLen (castPtr o, fromIntegral len)-                return (ret1, sig)-    assertBool "successful signing" $ isSuccess ret-    assertEqual "signature matches" sig der-  where-    msg = Msg32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"-    key = SecKey32 $ toShort $ fst $ B16.decode-        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"-    der = fst $ B16.decode-        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\-        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\-        \45"--ecSecKeyVerifyTest :: Assertion-ecSecKeyVerifyTest = do-    ret <- liftIO $ alloca $ \k -> do-        poke k key-        x <- signCtx-        ecSecKeyVerify x k-    assertBool "valid secret key" $ isSuccess ret-  where-    key = SecKey32 $ toShort $ fst $ B16.decode-        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"--ecPubkeyCreateTest :: Assertion-ecPubkeyCreateTest = do-    (ret, pk) <- liftIO $ alloca $ \p -> alloca $ \k -> do-        poke k key-        x <- signCtx-        ret <- ecPubKeyCreate x p k-        allocaBytes 65 $ \o -> alloca $ \ol -> do-            poke ol 65-            rets <- ecPubKeySerialize-                x o ol p uncompressed-            unless (isSuccess rets) $ error "failed to serialive public key"-            len <- fromIntegral <$> peek ol-            pk <- packCStringLen (castPtr o, len)-            return (ret, pk)-    assertBool "successful pubkey creation" $ isSuccess ret-    assertEqual "public key matches" pub pk-  where-    key = SecKey32 $ toShort $ fst $ B16.decode-        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"-    pub = fst $ B16.decode-        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\-        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"--ecSecKeyTweakAddTest :: Assertion-ecSecKeyTweakAddTest = do-    (ret, tweaked) <- liftIO $ do-        x <- signCtx-        alloca $ \w -> alloca $ \k -> do-            poke w tweak-            poke k key-            ret <- ecSecKeyTweakAdd x k w-            tweaked <- peek k-            return (ret, tweaked)-    assertBool "successful secret key tweak" $ isSuccess ret-    assertEqual "tweaked keys match" expected tweaked-  where-    key = SecKey32 $ toShort $ fst $ B16.decode-        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"-    tweak = Tweak32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"-    expected = SecKey32 $ toShort $ fst $ B16.decode-        "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"--ecSecKeyTweakMulTest :: Assertion-ecSecKeyTweakMulTest = do-    (ret, tweaked) <- liftIO $ do-        x <- contextCreate sign-        retr <- withEntropy $ contextRandomize x-        unless (isSuccess retr) $ error "failed to randomize context"-        alloca $ \w -> alloca $ \k -> do-            poke w tweak-            poke k key-            ret <- ecSecKeyTweakMul x k w-            tweaked <- peek k-            return (ret, tweaked)-    assertBool "successful secret key tweak" $ isSuccess ret-    assertEqual "tweaked keys match" expected tweaked-  where-    key = SecKey32 $ toShort $ fst $ B16.decode-        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"-    tweak = Tweak32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"-    expected = SecKey32 $ toShort $ fst $ B16.decode-        "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"--serializeKey :: Ptr 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 :: Ptr Ctx -> ByteString -> IO PubKey64-parseKey x bs = alloca $ \p -> useAsCStringLen bs $ \(d, dl) -> do-    ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)-    unless (isSuccess ret) $ error "could not parse public key"-    peek p--ecPubKeyTweakAddTest :: Assertion-ecPubKeyTweakAddTest = do-    (ret, tweaked) <- liftIO $ do-        x <- contextCreate verify-        pk <- parseKey x pub-        alloca $ \w -> alloca $ \p -> do-            poke w tweak-            poke p pk-            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 = fst $ B16.decode-        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\-        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"-    tweak = Tweak32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"-    expected = fst $ B16.decode-        "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\-        \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"--ecPubKeyTweakMulTest :: Assertion-ecPubKeyTweakMulTest = do-    (ret, tweaked) <- liftIO $ do-        x <- contextCreate verify-        pk <- parseKey x pub-        alloca $ \w -> alloca $ \p -> do-            poke w tweak-            poke p pk-            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 = fst $ B16.decode-        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\-        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"-    tweak = Tweak32 $ toShort $ fst $ B16.decode-        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"-    expected = fst $ B16.decode-        "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\-        \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"--ecPubKeyCombineTest :: Assertion-ecPubKeyCombineTest = do-    (ret, com) <- liftIO $ alloca $ \p1 -> alloca $ \p2 -> alloca $ \p3 ->-        allocaArray 3 $ \a -> alloca $ \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 = useAsCStringLen pub $ \(d, dl) -> do-        ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)-        unless (isSuccess ret) $ error "could not parse public key"-    pub1 = fst $ B16.decode-        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\-        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"-    pub2 = fst $ B16.decode-        "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d153f5\-        \77dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"-    pub3 = fst $ B16.decode-        "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee3feb\-        \d908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"-    expected = fst $ B16.decode-        "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\-        \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"
+ test/Crypto/Secp256k1/InternalSpec.hs view
@@ -0,0 +1,429 @@+{-# LANGUAGE OverloadedStrings #-}+module Crypto.Secp256k1.InternalSpec (spec) where++import           Control.Monad+import           Control.Monad.Trans+import           Crypto.Secp256k1.Internal+import           Data.ByteString           (ByteString, packCStringLen,+                                            useAsCStringLen)+import qualified Data.ByteString.Base16    as B16+import           Data.ByteString.Short     (toShort)+import           Foreign+import           System.Entropy+import           Test.Hspec+import           Test.HUnit                (Assertion, assertBool, assertEqual)++spec :: Spec+spec = do+    describe "housekeeping" $ do+        it "creates context" createContextTest+        it "randomizez context" randomizeContextTest+        it "clones context" cloneContextTest+    describe "serialization" $ do+        it "parses public key" ecPubkeyParseTest+        it "serializes public key" ecPubKeySerializeTest+        it "handles storable public key" pubkeyStorableTest+        it "handles storable signature" signatureStorableTest+        it "parses DER signature" ecdsaSignatureParseDerTest+        it "parses lax DER signature" laxDerParseTest+        it "serializes DER signature" ecdsaSignatureSerializeDerTest+    describe "signatures" $ do+        it "verifies signature" ecdsaVerifyTest+        -- TODO:+        -- , testCase "RFC6979 nonce function"   nonce_function_rfc6979_test+        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 ->+    alloca $ \s ->+    poke s (Seed32 (toShort e)) >> 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+        alloca $ \pubkey ->+            ecPubKeyParse x pubkey (castPtr i) (fromIntegral il)+    assertBool "parsed public key" (isSuccess ret)+  where+    der = fst $ B16.decode+        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"++ecPubKeySerializeTest :: Assertion+ecPubKeySerializeTest = do+    (ret, dec) <- liftIO $ useAsCStringLen der $ \(i, il) ->+        alloca $ \k -> alloca $ \ol -> allocaBytes 72 $ \o -> do+        poke ol 72+        x <- contextCreate verify+        ret1 <-+            ecPubKeyParse x k (castPtr i) (fromIntegral 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 = fst $ B16.decode+        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"++pubkeyStorableTest :: Assertion+pubkeyStorableTest = do+    (pk1, pk2, dec) <- liftIO $ useAsCStringLen der $ \(i, il) -> do+        x <- contextCreate verify+        pk1 <- alloca $ \pk -> do+            ret <-+                ecPubKeyParse x pk (castPtr i) (fromIntegral il)+            unless (isSuccess ret) $ error "failed to parse pubkey"+            peek pk+        (pk2, dec) <- alloca $ \pk -> alloca $ \ol -> allocaBytes 72 $ \o -> do+            poke ol 72+            poke pk pk1+            ret <-+                ecPubKeySerialize x o ol pk compressed+            unless (isSuccess ret) $ error "failed to serialize pubkey"+            len <- fromIntegral <$> peek ol+            dec <- packCStringLen (castPtr o, len)+            pk2 <- peek pk+            return (pk2, dec)+        return (pk1, pk2, dec)+    assertEqual "poke/peek public key" pk1 pk2+    assertEqual "public key matches" der dec+  where+    der = fst $ B16.decode+        "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"++signatureStorableTest :: Assertion+signatureStorableTest = do+    (sig, ret) <- liftIO $ do+        x <- contextCreate verify+        g <- alloca $ \pc -> alloca $ \pg -> do+            poke pc cpt+            ret <- ecdsaSignatureParseCompact x pg (castPtr pc)+            unless (isSuccess ret) $ error "failed to parse signature"+            peek pg+        alloca $ \pc -> alloca $ \pg -> do+            poke pg g+            ret <- ecdsaSignatureSerializeCompact x pc pg+            c <- peek pc+            return (c, ret)+    assertBool "successful serialization" (isSuccess ret)+    assertEqual "signatures match" cpt sig+  where+    cpt = CompactSig+        (toShort $ fst $ B16.decode "f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb22")+        (toShort $ fst $ B16.decode "6f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045")++ecdsaSignatureParseDerTest :: Assertion+ecdsaSignatureParseDerTest = do+    ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do+        x <- contextCreate verify+        ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)+    assertBool "parsed signature successfully" $ isSuccess ret+  where+    der = fst $ B16.decode+        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\+        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\+        \45"++laxDerParseTest :: Assertion+laxDerParseTest = do+    ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do+        x <- contextCreate verify+        laxDerParse x s (castPtr d) (fromIntegral dl)+    assertBool "parsed signature successfully" $ isSuccess ret+  where+    der = fst $ B16.decode+        "30450220f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb\+        \2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045"++parseDer :: Ptr Ctx -> ByteString -> IO Sig64+parseDer x bs = useAsCStringLen bs $ \(d, dl) -> alloca $ \s -> do+    ret <- ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)+    unless (isSuccess ret) $ error "could not parse DER"+    peek s++ecdsaSignatureSerializeDerTest :: Assertion+ecdsaSignatureSerializeDerTest = do+    (ret, enc) <- liftIO $ do+        x <- contextCreate verify+        sig <- parseDer x der+        alloca $ \s -> alloca $ \ol -> allocaBytes 72 $ \o -> do+            poke ol 72+            poke s sig+            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 = fst $ B16.decode+        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\+        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\+        \45"++ecdsaVerifyTest :: Assertion+ecdsaVerifyTest = do+    ret <- liftIO $ do+        x <- contextCreate verify+        sig <- parseDer x der+        pk <- useAsCStringLen pub $ \(p, pl) -> alloca $ \k -> do+            ret <-+                ecPubKeyParse x k (castPtr p) (fromIntegral pl)+            unless (isSuccess ret) $ error "could not parse public key"+            peek k+        alloca $ \m -> alloca $ \k -> alloca $ \s -> do+            poke m msg+            poke k pk+            poke s sig+            ecdsaVerify x s m k+    assertBool "signature valid" $ isSuccess ret+  where+    der = fst $ B16.decode+        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\+        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\+        \45"+    pub = fst $ B16.decode+        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\+        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"+    msg = Msg32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"++signCtx :: IO (Ptr Ctx)+signCtx = contextCreate sign >>= \c ->+    withEntropy (contextRandomize c) >>= \r ->+        unless (isSuccess r) (error "failed to randomize context") >> return c++ecdsaSignTest :: Assertion+ecdsaSignTest = do+    (ret, sig) <- liftIO $ do+        x <- signCtx+        alloca $ \s -> alloca $ \m -> alloca $ \k -> alloca $ \ol ->+            allocaBytes 72 $ \o -> do+                poke ol 72+                poke m msg+                poke k key+                ret1 <-+                    -- TODO:+                    -- ecdsaSign x s m k nonce_function_default nullPtr+                    ecdsaSign x s m k nullFunPtr nullPtr+                ret2 <- ecdsaSignatureSerializeDer x o ol s+                unless (isSuccess ret2) $ error "could not serialize signature"+                len <- peek ol+                sig <- packCStringLen (castPtr o, fromIntegral len)+                return (ret1, sig)+    assertBool "successful signing" $ isSuccess ret+    assertEqual "signature matches" sig der+  where+    msg = Msg32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"+    key = SecKey32 $ toShort $ fst $ B16.decode+        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"+    der = fst $ B16.decode+        "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\+        \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\+        \45"++ecSecKeyVerifyTest :: Assertion+ecSecKeyVerifyTest = do+    ret <- liftIO $ alloca $ \k -> do+        poke k key+        x <- signCtx+        ecSecKeyVerify x k+    assertBool "valid secret key" $ isSuccess ret+  where+    key = SecKey32 $ toShort $ fst $ B16.decode+        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"++ecPubkeyCreateTest :: Assertion+ecPubkeyCreateTest = do+    (ret, pk) <- liftIO $ alloca $ \p -> alloca $ \k -> do+        poke k key+        x <- signCtx+        ret <- ecPubKeyCreate x p k+        allocaBytes 65 $ \o -> alloca $ \ol -> do+            poke ol 65+            rets <- ecPubKeySerialize+                x o ol p uncompressed+            unless (isSuccess rets) $ error "failed to serialive public key"+            len <- fromIntegral <$> peek ol+            pk <- packCStringLen (castPtr o, len)+            return (ret, pk)+    assertBool "successful pubkey creation" $ isSuccess ret+    assertEqual "public key matches" pub pk+  where+    key = SecKey32 $ toShort $ fst $ B16.decode+        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"+    pub = fst $ B16.decode+        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\+        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"++ecSecKeyTweakAddTest :: Assertion+ecSecKeyTweakAddTest = do+    (ret, tweaked) <- liftIO $ do+        x <- signCtx+        alloca $ \w -> alloca $ \k -> do+            poke w tweak+            poke k key+            ret <- ecSecKeyTweakAdd x k w+            tweaked <- peek k+            return (ret, tweaked)+    assertBool "successful secret key tweak" $ isSuccess ret+    assertEqual "tweaked keys match" expected tweaked+  where+    key = SecKey32 $ toShort $ fst $ B16.decode+        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"+    tweak = Tweak32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"+    expected = SecKey32 $ toShort $ fst $ B16.decode+        "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"++ecSecKeyTweakMulTest :: Assertion+ecSecKeyTweakMulTest = do+    (ret, tweaked) <- liftIO $ do+        x <- contextCreate sign+        retr <- withEntropy $ contextRandomize x+        unless (isSuccess retr) $ error "failed to randomize context"+        alloca $ \w -> alloca $ \k -> do+            poke w tweak+            poke k key+            ret <- ecSecKeyTweakMul x k w+            tweaked <- peek k+            return (ret, tweaked)+    assertBool "successful secret key tweak" $ isSuccess ret+    assertEqual "tweaked keys match" expected tweaked+  where+    key = SecKey32 $ toShort $ fst $ B16.decode+        "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"+    tweak = Tweak32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"+    expected = SecKey32 $ toShort $ fst $ B16.decode+        "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"++serializeKey :: Ptr 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 :: Ptr Ctx -> ByteString -> IO PubKey64+parseKey x bs = alloca $ \p -> useAsCStringLen bs $ \(d, dl) -> do+    ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)+    unless (isSuccess ret) $ error "could not parse public key"+    peek p++ecPubKeyTweakAddTest :: Assertion+ecPubKeyTweakAddTest = do+    (ret, tweaked) <- liftIO $ do+        x <- contextCreate verify+        pk <- parseKey x pub+        alloca $ \w -> alloca $ \p -> do+            poke w tweak+            poke p pk+            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 = fst $ B16.decode+        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\+        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"+    tweak = Tweak32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"+    expected = fst $ B16.decode+        "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\+        \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"++ecPubKeyTweakMulTest :: Assertion+ecPubKeyTweakMulTest = do+    (ret, tweaked) <- liftIO $ do+        x <- contextCreate verify+        pk <- parseKey x pub+        alloca $ \w -> alloca $ \p -> do+            poke w tweak+            poke p pk+            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 = fst $ B16.decode+        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\+        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"+    tweak = Tweak32 $ toShort $ fst $ B16.decode+        "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"+    expected = fst $ B16.decode+        "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\+        \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"++ecPubKeyCombineTest :: Assertion+ecPubKeyCombineTest = do+    (ret, com) <- liftIO $ alloca $ \p1 -> alloca $ \p2 -> alloca $ \p3 ->+        allocaArray 3 $ \a -> alloca $ \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 = useAsCStringLen pub $ \(d, dl) -> do+        ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)+        unless (isSuccess ret) $ error "could not parse public key"+    pub1 = fst $ B16.decode+        "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\+        \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"+    pub2 = fst $ B16.decode+        "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d153f5\+        \77dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"+    pub3 = fst $ B16.decode+        "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee3feb\+        \d908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"+    expected = fst $ B16.decode+        "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\+        \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"
− test/Crypto/Secp256k1/Tests.hs
@@ -1,252 +0,0 @@-module Crypto.Secp256k1.Tests (tests) where--import           Crypto.Secp256k1-import           Data.Serialize-import qualified Data.ByteString.Base16               as B16-import qualified Data.ByteString.Char8                as B8-import           Data.Maybe                           (fromMaybe)-import           Data.String                          (fromString)-import           Data.String.Conversions              (cs)-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                      (Property, (==>))--tests :: [Test]-tests =-    [ testGroup "Signing"-        [ testProperty "Signing messages" signMsgTest-        , testProperty "Recoverably signing messages" signRecMsgTest-        , testProperty "Bad signatures" badSignatureTest-        , testProperty "Bad recoverable signatures" badRecSignatureTest-        , testProperty "Normalize signatures" normalizeSigTest-        , testProperty "Recover public keys" recoverTest-        , testProperty "Bad recover public keys" badRecoverTest-        ]-    , testGroup "Serialization"-        [ testProperty "Serialize public key" serializePubKeyTest-        , testProperty "Serialize DER signature" serializeSigTest-        , testProperty "Serialize lax DER signature" serializeLaxSigTest-        , testProperty "Serialize compact signature" serializeCompactSigTest-        , testProperty "Serialize compact recoverable signature" serializeCompactRecSigTest-        , testProperty "Serialize secret key" serializeSecKeyTest-        , testProperty "Show/Read public key" (showRead :: PubKey -> Bool)-        , testProperty "Show/Read secret key" (showRead :: SecKey -> Bool)-        , testProperty "Show/Read tweak" (showReadTweak :: SecKey -> Bool)-        , testProperty "Show/Read signature" (showReadSig :: (SecKey, Msg) -> Bool)-        , testProperty "Show/Read recoverable signature" (showReadRecSig :: (SecKey, Msg) -> Bool)-        , testProperty "Show/Read message" (showRead :: Msg -> Bool)-        , testProperty "String public key" isStringPubKey-        , testProperty "String secret key" isStringSecKey-        , testProperty "String signature" isStringSig-        , testProperty "String recoverable signature" isStringRecSig-        , testProperty "String message" isStringMsg-        , testProperty "String tweak" isStringTweak-        ]-    , 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-        ]-    ]--isStringPubKey :: (PubKey, Bool) -> Bool-isStringPubKey (k, c) = k == fromString (cs hex) where-    hex = B16.encode $ exportPubKey c k--isStringSig :: (SecKey, Msg) -> Bool-isStringSig (k, m) = g == fromString (cs hex) where-    g = signMsg k m-    hex = B16.encode $ exportSig g--isStringRecSig :: (SecKey, Msg) -> Bool-isStringRecSig (k, m) = g == fromString (cs hex) where-    g = signRecMsg k m-    hex = B16.encode . encode $ exportCompactRecSig g--isStringMsg :: Msg -> Bool-isStringMsg m = m == fromString (cs m') where-    m' = B16.encode $ getMsg m--isStringSecKey :: SecKey -> Bool-isStringSecKey k = k == fromString (cs hex) where-    hex = B16.encode $ getSecKey k--isStringTweak :: SecKey -> Bool-isStringTweak k = t == fromString (cs hex) where-    t = fromMaybe e . tweak $ getSecKey k-    hex = B16.encode $ getTweak t-    e = error "Could not extract tweak from secret key"--showReadTweak :: SecKey -> Bool-showReadTweak k = showRead t where-    t = tweak $ getSecKey k--showReadSig :: (SecKey, Msg) -> Bool-showReadSig (k, m) = showRead sig where-    sig = signMsg k m--showReadRecSig :: (SecKey, Msg) -> Bool-showReadRecSig (k, m) = showRead recSig where-    recSig = signRecMsg k m--showRead :: (Show a, Read a, Eq a) => a -> Bool-showRead x = read (show x) == x--signMsgTest :: (Msg, SecKey) -> Bool-signMsgTest (fm, fk) = verifySig fp fg fm where-    fp = derivePubKey fk-    fg = signMsg fk fm--signRecMsgTest :: (Msg, SecKey) -> Bool-signRecMsgTest (fm, fk) = verifySig fp fg fm where-    fp = derivePubKey fk-    fg = convertRecSig $ signRecMsg fk fm--recoverTest :: (Msg, SecKey) -> Bool-recoverTest (fm, fk) = recover fg fm == Just fp where-    fp = derivePubKey fk-    fg = signRecMsg fk fm--badRecoverTest :: (Msg, SecKey, Msg) -> Property-badRecoverTest (fm, fk, fm') =-  fm' /= fm ==> fp' /= Nothing ==> fp' /= Just fp-  where-    fg  = signRecMsg fk fm-    fp  = derivePubKey fk-    fp' = recover fg fm'--badSignatureTest :: (Msg, SecKey, PubKey) -> Bool-badSignatureTest (fm, fk, fp) = not $ verifySig fp fg fm where-    fg = signMsg fk fm--badRecSignatureTest :: (Msg, SecKey, PubKey) -> Bool-badRecSignatureTest (fm, fk, fp) = not $ verifySig fp fg fm where-    fg = convertRecSig $ signRecMsg fk fm--normalizeSigTest :: (Msg, SecKey) -> Bool-normalizeSigTest (fm, fk) = not norm && sig == fg where-    fg = signMsg fk fm-    (sig, norm) = normalizeSig fg--serializePubKeyTest :: (PubKey, Bool) -> Bool-serializePubKeyTest (fp, b) =-    case importPubKey $ exportPubKey b fp of-        Just fp' -> fp == fp'-        Nothing -> False--serializeSigTest :: (Msg, SecKey) -> Bool-serializeSigTest (fm, fk) =-    case importSig $ exportSig fg of-        Just fg' -> fg == fg'-        Nothing -> False-  where-    fg = signMsg fk fm--serializeLaxSigTest :: (Msg, SecKey) -> Bool-serializeLaxSigTest (fm, fk) =-    case laxImportSig $ exportSig fg of-        Just fg' -> fg == fg'-        Nothing -> False-  where-    fg = signMsg fk fm--serializeCompactSigTest :: (Msg, SecKey) -> Bool-serializeCompactSigTest (fm, fk) =-    case importCompactSig $ exportCompactSig fg of-        Just fg' -> fg == fg'-        Nothing -> False-  where-    fg = signMsg fk fm--serializeCompactRecSigTest :: (Msg, SecKey) -> Bool-serializeCompactRecSigTest (fm, fk) =-    case importCompactRecSig $ exportCompactRecSig fg of-        Just fg' -> fg == fg'-        Nothing -> False-  where-    fg = signRecMsg fk fm--serializeSecKeyTest :: SecKey -> Bool-serializeSecKeyTest fk =-    case secKey $ getSecKey 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"
+ test/Crypto/Secp256k1Spec.hs view
@@ -0,0 +1,252 @@+module Crypto.Secp256k1Spec (spec) where++import           Crypto.Secp256k1+import qualified Data.ByteString.Base16  as B16+import qualified Data.ByteString.Char8   as B8+import           Data.Maybe              (fromMaybe)+import           Data.Serialize+import           Data.String             (fromString)+import           Data.String.Conversions (cs)+import           Test.Hspec+import           Test.HUnit              (Assertion, assertEqual)+import           Test.QuickCheck         (Property, property, (==>))++spec :: Spec+spec = do+    describe "signatures" $ do+        it "signs message" $ property $ signMsgTest+        it "recovers key from signed message" $ property $ signRecMsgTest+        it "detects bad signature" $ property $ badSignatureTest+        it "detects bad recoverable signature" $ property $ badRecSignatureTest+        it "normalizes signatures" $ property $ normalizeSigTest+        it "recovers public keys" $ property $ recoverTest+        it "Bad recover public keys" $ property $ badRecoverTest+    describe "serialization" $ do+        it "serializes public key" $ property $ serializePubKeyTest+        it "serializes DER signature" $ property $ serializeSigTest+        it "serializes lax DER signature" $ property $ serializeLaxSigTest+        it "serializes compact signature" $ property $ serializeCompactSigTest+        it "serializes compact recoverable signature" $+            property $ serializeCompactRecSigTest+        it "serialize secret key" $ property $ serializeSecKeyTest+        it "shows and reads public key" $+            property $ (showRead :: PubKey -> Bool)+        it "shows and reads secret key" $+            property $ (showRead :: SecKey -> Bool)+        it "shows and reads tweak" $+            property $ (showReadTweak :: SecKey -> Bool)+        it "shows and reads signature" $+            property $ (showReadSig :: (SecKey, Msg) -> Bool)+        it "shows and reads recoverable signature" $+            property $ (showReadRecSig :: (SecKey, Msg) -> Bool)+        it "shows and reads message" $ property $ (showRead :: Msg -> Bool)+        it "reads public key from string" $ property $ isStringPubKey+        it "reads secret key from string" $ property $ isStringSecKey+        it "reads signature from string" $ property $ isStringSig+        it "reads recoverable signature from string" $ property $ isStringRecSig+        it "reads message from string" $ property $ isStringMsg+        it "reads tweak from string" $ property $ isStringTweak+    describe "tweaks" $ do+        it "add secret key" $ property $ tweakAddSecKeyTest+        it "multiply secret key" $ property $ tweakMulSecKeyTest+        it "add public key" $ property $ tweakAddPubKeyTest+        it "multiply public key" $ property $ tweakMulPubKeyTest+        it "combine public keys" $ property $ combinePubKeyTest++isStringPubKey :: (PubKey, Bool) -> Bool+isStringPubKey (k, c) = k == fromString (cs hex) where+    hex = B16.encode $ exportPubKey c k++isStringSig :: (SecKey, Msg) -> Bool+isStringSig (k, m) = g == fromString (cs hex) where+    g = signMsg k m+    hex = B16.encode $ exportSig g++isStringRecSig :: (SecKey, Msg) -> Bool+isStringRecSig (k, m) = g == fromString (cs hex) where+    g = signRecMsg k m+    hex = B16.encode . encode $ exportCompactRecSig g++isStringMsg :: Msg -> Bool+isStringMsg m = m == fromString (cs m') where+    m' = B16.encode $ getMsg m++isStringSecKey :: SecKey -> Bool+isStringSecKey k = k == fromString (cs hex) where+    hex = B16.encode $ getSecKey k++isStringTweak :: SecKey -> Bool+isStringTweak k = t == fromString (cs hex) where+    t = fromMaybe e . tweak $ getSecKey k+    hex = B16.encode $ getTweak t+    e = error "Could not extract tweak from secret key"++showReadTweak :: SecKey -> Bool+showReadTweak k = showRead t where+    t = tweak $ getSecKey k++showReadSig :: (SecKey, Msg) -> Bool+showReadSig (k, m) = showRead sig where+    sig = signMsg k m++showReadRecSig :: (SecKey, Msg) -> Bool+showReadRecSig (k, m) = showRead recSig where+    recSig = signRecMsg k m++showRead :: (Show a, Read a, Eq a) => a -> Bool+showRead x = read (show x) == x++signMsgTest :: (Msg, SecKey) -> Bool+signMsgTest (fm, fk) = verifySig fp fg fm where+    fp = derivePubKey fk+    fg = signMsg fk fm++signRecMsgTest :: (Msg, SecKey) -> Bool+signRecMsgTest (fm, fk) = verifySig fp fg fm where+    fp = derivePubKey fk+    fg = convertRecSig $ signRecMsg fk fm++recoverTest :: (Msg, SecKey) -> Bool+recoverTest (fm, fk) = recover fg fm == Just fp where+    fp = derivePubKey fk+    fg = signRecMsg fk fm++badRecoverTest :: (Msg, SecKey, Msg) -> Property+badRecoverTest (fm, fk, fm') =+  fm' /= fm ==> fp' /= Nothing ==> fp' /= Just fp+  where+    fg  = signRecMsg fk fm+    fp  = derivePubKey fk+    fp' = recover fg fm'++badSignatureTest :: (Msg, SecKey, PubKey) -> Bool+badSignatureTest (fm, fk, fp) = not $ verifySig fp fg fm where+    fg = signMsg fk fm++badRecSignatureTest :: (Msg, SecKey, PubKey) -> Bool+badRecSignatureTest (fm, fk, fp) = not $ verifySig fp fg fm where+    fg = convertRecSig $ signRecMsg fk fm++normalizeSigTest :: (Msg, SecKey) -> Bool+normalizeSigTest (fm, fk) = not norm && sig == fg where+    fg = signMsg fk fm+    (sig, norm) = normalizeSig fg++serializePubKeyTest :: (PubKey, Bool) -> Bool+serializePubKeyTest (fp, b) =+    case importPubKey $ exportPubKey b fp of+        Just fp' -> fp == fp'+        Nothing  -> False++serializeSigTest :: (Msg, SecKey) -> Bool+serializeSigTest (fm, fk) =+    case importSig $ exportSig fg of+        Just fg' -> fg == fg'+        Nothing  -> False+  where+    fg = signMsg fk fm++serializeLaxSigTest :: (Msg, SecKey) -> Bool+serializeLaxSigTest (fm, fk) =+    case laxImportSig $ exportSig fg of+        Just fg' -> fg == fg'+        Nothing  -> False+  where+    fg = signMsg fk fm++serializeCompactSigTest :: (Msg, SecKey) -> Bool+serializeCompactSigTest (fm, fk) =+    case importCompactSig $ exportCompactSig fg of+        Just fg' -> fg == fg'+        Nothing  -> False+  where+    fg = signMsg fk fm++serializeCompactRecSigTest :: (Msg, SecKey) -> Bool+serializeCompactRecSigTest (fm, fk) =+    case importCompactRecSig $ exportCompactRecSig fg of+        Just fg' -> fg == fg'+        Nothing  -> False+  where+    fg = signRecMsg fk fm++serializeSecKeyTest :: SecKey -> Bool+serializeSecKeyTest fk =+    case secKey $ getSecKey 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"
test/Spec.hs view
@@ -1,8 +1,1 @@-import Test.Framework (defaultMain)---- Some simple signing tests-import qualified Crypto.Secp256k1.Tests as T-import qualified Crypto.Secp256k1.Internal.Tests as I--main :: IO ()-main = defaultMain $ T.tests ++ I.tests+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}