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 +144/−126
- src/Crypto/Secp256k1.hs +12/−12
- test/Crypto/Secp256k1/Internal/Tests.hs +0/−437
- test/Crypto/Secp256k1/InternalSpec.hs +429/−0
- test/Crypto/Secp256k1/Tests.hs +0/−252
- test/Crypto/Secp256k1Spec.hs +252/−0
- test/Spec.hs +1/−8
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 #-}