packages feed

secp256k1-haskell 0.2.2 → 0.2.3

raw patch · 5 files changed

+102/−56 lines, 5 filesdep +monad-par

Dependencies added: monad-par

Files

CHANGELOG.md view
@@ -4,6 +4,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.2.3+### Changed+- Return meaningful error upon encountering weird ret status from upstream code.++### Added+- Test parallel signature creation and verification.+ ## 0.2.2 ### Removed - Hide tweak negation behind a flag for compatibilidy with Debian 9.
secp256k1-haskell.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.33.0. -- -- see: https://github.com/sol/hpack ----- hash: 0b75b1185f390c0f03f09dfc8e18349a5bce92770b10888fc121279d4fa9953f+-- hash: 16aee2fed95caee7ec390abc8e88433479bf9a3c51dc68b00b1d5eaaebe5b5a1  name:           secp256k1-haskell-version:        0.2.2+version:        0.2.3 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@@ -86,6 +86,7 @@       Paths_secp256k1_haskell   hs-source-dirs:       test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:       HUnit     , QuickCheck@@ -97,8 +98,17 @@     , entropy     , hashable     , hspec+    , monad-par     , mtl     , secp256k1-haskell     , string-conversions+  if flag(ecdh)+    cpp-options: -DECDH+  if flag(schnorr)+    cpp-options: -DSCHNORR+  if flag(recovery)+    cpp-options: -DRECOVERY+  if flag(negate)+    cpp-options: -DNEGATE   default-language: Haskell2010   build-tool-depends: hspec-discover:hspec-discover
src/Crypto/Secp256k1/Internal.hs view
@@ -261,7 +261,7 @@ isSuccess :: Ret -> Bool isSuccess (Ret 0) = False isSuccess (Ret 1) = True-isSuccess _       = undefined+isSuccess (Ret n) = error $ "isSuccess expected 0 or 1 but got " <> show n  {-# NOINLINE fctx #-} fctx :: ForeignPtr Ctx
test/Crypto/Secp256k1/InternalSpec.hs view
@@ -219,6 +219,12 @@     withEntropy (contextRandomize c) >>= \r ->         unless (isSuccess r) (error "failed to randomize context") >> return c +createPubKey :: Ptr Ctx -> Ptr SecKey32 -> Ptr PubKey64 -> SecKey32 -> IO ()+createPubKey x k p key = do+    poke k key+    ret <- ecPubKeyCreate x p k+    unless (isSuccess ret) $ error "failed to create public key"+ ecdsaSignTest :: Assertion ecdsaSignTest = do     der <- liftIO $ do@@ -234,14 +240,11 @@                 ret2 <- ecdsaSignatureSerializeDer x o ol s                 unless (isSuccess ret2) $ error "could not serialize signature"                 len <- peek ol-                der <- packCStringLen (castPtr o, fromIntegral len)-                return der+                packCStringLen (castPtr o, fromIntegral len)     ret <- liftIO $ do         p <- alloca $ \p -> alloca $ \k -> do-            poke k key             x <- signCtx-            ret <- ecPubKeyCreate x p k-            unless (isSuccess ret) $ error "failed to create public key"+            createPubKey x k p key             return p         alloca $ \m -> alloca $ \s -> do             x <- contextCreate verify@@ -270,20 +273,16 @@  ecPubkeyCreateTest :: Assertion ecPubkeyCreateTest = do-    (ret, pk) <- liftIO $ alloca $ \p -> alloca $ \k -> do-        poke k key+    pk <- liftIO $ alloca $ \p -> alloca $ \k -> do         x <- signCtx-        ret <- ecPubKeyCreate x p k-        unless (isSuccess ret) $ error "failed to create public key"+        createPubKey x k p key         allocaBytes 65 $ \o -> alloca $ \ol -> do             poke ol 65             rets <- ecPubKeySerialize                 x o ol p uncompressed             unless (isSuccess rets) $ error "failed to serialize public key"             len <- fromIntegral <$> peek ol-            pk <- packCStringLen (castPtr o, len)-            return (ret, pk)-    assertBool "successful pubkey creation" $ isSuccess ret+            packCStringLen (castPtr o, len)     assertEqual "public key matches" pub pk   where     key = SecKey32 $ toShort $ fst $ B16.decode
test/Crypto/Secp256k1Spec.hs view
@@ -1,87 +1,112 @@ {-# LANGUAGE CPP #-} module Crypto.Secp256k1Spec (spec) where +import qualified Control.Monad.Par       as P import           Crypto.Secp256k1 import qualified Data.ByteString         as BS import qualified Data.ByteString.Base16  as B16 import qualified Data.ByteString.Char8   as B8 import           Data.Maybe              (fromMaybe)+import qualified Data.Serialize          as S import           Data.String             (fromString) import           Data.String.Conversions (cs) import           Test.Hspec import           Test.HUnit              (Assertion, assertEqual)-import           Test.QuickCheck         (property)+import           Test.QuickCheck  spec :: Spec spec = do     describe "signatures" $ do-        it "signs message" $ property $ signMsgTest-        it "detects bad signature" $ property $ badSignatureTest-        it "normalizes signatures" $ property $ normalizeSigTest-#ifdef RECOVERY-        it "recovers public keys" $ property $ recoverTest-        it "recovers key from signed message" $ property $ signRecMsgTest-        it "does not recover bad public keys" $ property $ badRecoverTest-        it "detects bad recoverable signature" $ property $ badRecSignatureTest-#endif+        it "signs message" $+            property signMsgTest+        it "signs messages in parallel" $+            property signMsgParTest+        it "detects bad signature" $+            property badSignatureTest+        it "normalizes signatures" $+            property normalizeSigTest     describe "serialization" $ do-        it "serializes public key" $ property $ serializePubKeyTest-        it "serializes DER signature" $ property $ serializeSigTest-        it "serializes compact signature" $ property $ serializeCompactSigTest-        it "serialize secret key" $ property $ serializeSecKeyTest+        it "serializes public key" $+            property serializePubKeyTest+        it "serializes DER signature" $+            property serializeSigTest+        it "serializes compact signature" $+            property serializeCompactSigTest+        it "serialize secret key" $+            property serializeSecKeyTest         it "shows and reads public key" $-            property $ (showRead :: PubKey -> Bool)+            property (showRead :: PubKey -> Bool)         it "shows and reads secret key" $-            property $ (showRead :: SecKey -> Bool)+            property (showRead :: SecKey -> Bool)         it "shows and reads tweak" $-            property $ (showReadTweak :: SecKey -> Bool)+            property (showReadTweak :: SecKey -> Bool)         it "shows and reads signature" $-            property $ (showReadSig :: (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 message from string" $ property $ isStringMsg-        it "reads tweak from string" $ property $ isStringTweak+            property (showReadSig :: (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 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+        it "can't combine 0 public keys" $ property combinePubKeyEmptyListTest #ifdef RECOVERY+    describe "recovery" $ do+        it "recovers public keys" $+            property recoverTest+        it "recovers key from signed message" $+            property signRecMsgTest+        it "does not recover bad public keys" $+            property badRecoverTest+        it "detects bad recoverable signature" $+            property badRecSignatureTest         it "serializes compact recoverable signature" $-            property $ serializeCompactRecSigTest+            property serializeCompactRecSigTest         it "shows and reads recoverable signature" $-            property $ (showReadRecSig :: (SecKey, Msg) -> Bool)+            property (showReadRecSig :: (SecKey, Msg) -> Bool)         it "reads recoverable signature from string" $ property $ isStringRecSig #endif-    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-        it "can't combine 0 public keys" $ property $ combinePubKeyEmptyListTest #ifdef NEGATE-        it "negates tweak" $ property $ negateTweakTest+    describe "negate" $+        it "negates tweak" $ property negateTweakTest #endif #ifdef ECDH     describe "ecdh" $ do-        it "computes dh secret" $ property $ computeDhSecret+        it "computes dh secret" $ property computeDhSecret #endif #ifdef SCHNORR     describe "schnorr (bip-340)" $ do-        it "validates test vector 0" $ property bip340Vector0-        it "rejects test vector 5" $ property $+        it "validates test vector 0" $+            property bip340Vector0+        it "rejects test vector 5" $+            property $             failingVectorToAssertion InvalidPubKey               (                 hexToBytes "eefdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34",                 hexToBytes "243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89",                 hexToBytes "667c2f778e0616e611bd0c14b8a600c5884551701a949ef0ebfd72d452d64e844160bcfc3f466ecb8facd19ade57d8699d74e7207d78c6aedc3799b52a8e0598"               )-        it "rejects test vector 6" $ property $+        it "rejects test vector 6" $+            property $             failingVectorToAssertion InvalidSig               (                 hexToBytes "dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659",                 hexToBytes "243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89",                 hexToBytes "f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9935554d1aa5f0374e5cdaacb3925035c7c169b27c4426df0a6b19af3baeab138"               )-        it "makes a valid taproot key spend signature" $ property taprootKeySpend+        it "makes a valid taproot key spend signature" $+            property taprootKeySpend #endif  hexToBytes :: String -> BS.ByteString@@ -100,7 +125,7 @@ isStringRecSig :: (SecKey, Msg) -> Bool isStringRecSig (k, m) = g == fromString (cs hex) where     g = signRecMsg k m-    hex = B16.encode . encode $ exportCompactRecSig g+    hex = B16.encode . S.encode $ exportCompactRecSig g #endif  isStringMsg :: Msg -> Bool@@ -138,6 +163,11 @@ signMsgTest (fm, fk) = verifySig fp fg fm where     fp = derivePubKey fk     fg = signMsg fk fm++signMsgParTest :: [(Msg, SecKey)] -> Bool+signMsgParTest xs = P.runPar $ do+    ys <- mapM (P.spawnP . signMsgTest) xs+    and <$> mapM P.get ys  #ifdef RECOVERY signRecMsgTest :: (Msg, SecKey) -> Bool