secp256k1-haskell 0.5.0 → 0.6.0
raw patch · 5 files changed
+69/−61 lines, 5 filesdep +base16dep −base16-bytestringPVP ok
version bump matches the API change (PVP)
Dependencies added: base16
Dependencies removed: base16-bytestring
API changes (from Hackage documentation)
Files
- CHANGELOG.md +9/−0
- secp256k1-haskell.cabal +6/−6
- src/Crypto/Secp256k1.hs +12/−14
- test/Crypto/Secp256k1/InternalSpec.hs +32/−31
- test/Crypto/Secp256k1Spec.hs +10/−10
CHANGELOG.md view
@@ -4,6 +4,15 @@ 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.6.0+### Changed+- Remove all use of CPP.+- Depend on base16 instead of the old base16-bytestring package.+- Target ghc-9.0.1 compiler.++### Fixed+- Do not crash on bytestrings that are backed by null C pointers.+ ## 0.5.0 ### Changed - Include version boundaries and other changes submitted by Emily Pillmore.
secp256k1-haskell.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.24 --- This file has been generated from package.yaml by hpack version 0.34.2.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack name: secp256k1-haskell-version: 0.5.0+version: 0.6.0 synopsis: Bindings for secp256k1 description: Sign and verify signatures using the secp256k1 library. category: Crypto@@ -39,13 +39,13 @@ build-depends: QuickCheck >=2.9.2 && <2.15 , base >=4.9 && <5- , base16-bytestring >=0.1.1.6 && <1.1+ , base16 >=0.3.0.1 , bytestring >=0.10.8 && <0.11 , cereal >=0.5.4 && <0.6 , deepseq >=1.4.2 && <1.5 , entropy >=0.3.8 && <0.5 , hashable >=1.2.6 && <1.4- , string-conversions >=0.4 && <0.5+ , string-conversions ==0.4.* , unliftio-core >=0.1.0 && <0.3 default-language: Haskell2010 @@ -63,7 +63,7 @@ HUnit , QuickCheck >=2.9.2 && <2.15 , base >=4.9 && <5- , base16-bytestring >=0.1.1.6 && <1.1+ , base16 >=0.3.0.1 , bytestring >=0.10.8 && <0.11 , cereal >=0.5.4 && <0.6 , deepseq >=1.4.2 && <1.5@@ -73,7 +73,7 @@ , monad-par , mtl , secp256k1-haskell- , string-conversions >=0.4 && <0.5+ , string-conversions ==0.4.* , unliftio-core >=0.1.0 && <0.3 default-language: Haskell2010 build-tool-depends: hspec-discover:hspec-discover
src/Crypto/Secp256k1.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -116,14 +115,9 @@ get = CompactSig <$> getByteString 64 decodeHex :: ConvertibleStrings a ByteString => a -> Maybe ByteString-#if MIN_VERSION_base16_bytestring(1,0,0)-decodeHex str = case B16.decode $ cs str of+decodeHex str = case B16.decodeBase16 $ cs str of Right bs -> Just bs Left _ -> Nothing-#else-decodeHex str = if BS.null r then Just bs else Nothing where- (bs, r) = B16.decode $ cs str-#endif instance Read PubKey where readPrec = do@@ -138,7 +132,7 @@ e = error "Could not decode public key from hex string" instance Show PubKey where- showsPrec _ = shows . B16.encode . exportPubKey True+ showsPrec _ = shows . B16.encodeBase16 . exportPubKey True instance Read Msg where readPrec = parens $ do@@ -153,7 +147,7 @@ e = error "Could not decode message from hex string" instance Show Msg where- showsPrec _ = shows . B16.encode . getMsg+ showsPrec _ = shows . B16.encodeBase16 . getMsg instance Read Sig where readPrec = parens $ do@@ -168,7 +162,7 @@ i `hashWithSalt` s = i `hashWithSalt` exportSig s instance Show Sig where- showsPrec _ = shows . B16.encode . exportSig+ showsPrec _ = shows . B16.encodeBase16 . exportSig instance Read SecKey where readPrec = parens $ do@@ -183,7 +177,7 @@ e = error "Colud not decode secret key from hex string" instance Show SecKey where- showsPrec _ = shows . B16.encode . getSecKey+ showsPrec _ = shows . B16.encodeBase16 . getSecKey instance Hashable Tweak where i `hashWithSalt` t = i `hashWithSalt` getTweak t@@ -198,7 +192,7 @@ e = error "Could not decode tweak from hex string" instance Show Tweak where- showsPrec _ = shows . B16.encode . getTweak+ showsPrec _ = shows . B16.encodeBase16 . getTweak -- | Import 32-byte 'ByteString' as 'Msg'. msg :: ByteString -> Maybe Msg@@ -240,7 +234,9 @@ -- | Import DER-encoded public key. importPubKey :: ByteString -> Maybe PubKey-importPubKey bs = unsafePerformIO $+importPubKey bs+ | BS.null bs = Nothing+ | otherwise = unsafePerformIO $ unsafeUseByteString bs $ \(input, len) -> do pub_key <- mallocBytes 64 ret <- ecPubKeyParse ctx pub_key input len@@ -293,7 +289,9 @@ -- | Import DER-encoded signature. importSig :: ByteString -> Maybe Sig-importSig bs = unsafePerformIO $+importSig bs+ | BS.null bs = Nothing+ | otherwise = unsafePerformIO $ unsafeUseByteString bs $ \(in_ptr, in_len) -> do out_sig <- mallocBytes 64 ret <- ecdsaSignatureParseDer ctx out_sig in_ptr in_len
test/Crypto/Secp256k1/InternalSpec.hs view
@@ -4,13 +4,14 @@ import Control.Monad import Control.Monad.Trans import Crypto.Secp256k1.Internal-import Data.ByteString (ByteString, packCStringLen,- useAsCStringLen, copy)+import Data.ByteString (ByteString, copy, packCStringLen,+ useAsCStringLen) import qualified Data.ByteString.Base16 as B16+import Data.Either (fromRight) import Foreign import System.Entropy-import Test.Hspec import Test.HUnit (Assertion, assertBool, assertEqual)+import Test.Hspec spec :: Spec spec = do@@ -74,7 +75,7 @@ ecPubKeyParse x pubkey (castPtr i) (fromIntegral il) assertBool "parsed public key" (isSuccess ret) where- der = fst $ B16.decode+ der = fromRight undefined $ B16.decodeBase16 "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705" ecPubKeySerializeTest :: Assertion@@ -95,7 +96,7 @@ assertBool "serialized public key successfully" $ isSuccess ret assertEqual "public key matches" der dec where- der = fst $ B16.decode+ der = fromRight undefined $ B16.decodeBase16 "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705" ecdsaSignatureParseDerTest :: Assertion@@ -105,7 +106,7 @@ ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl) assertBool "parsed signature successfully" $ isSuccess ret where- der = fst $ B16.decode+ der = fromRight undefined $ B16.decodeBase16 "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\ \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\ \45"@@ -134,7 +135,7 @@ assertBool "serialization successful" $ isSuccess ret assertEqual "signatures match" der enc where- der = fst $ B16.decode+ der = fromRight undefined $ B16.decodeBase16 "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\ \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\ \45"@@ -155,14 +156,14 @@ ecdsaVerify x s m k assertBool "signature valid" $ isSuccess ret where- der = fst $ B16.decode+ der = fromRight undefined $ B16.decodeBase16 "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\ \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\ \45"- pub = fst $ B16.decode+ pub = fromRight undefined $ B16.decodeBase16 "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\ \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"- msg = fst $ B16.decode+ msg = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00" signCtx :: IO Ctx@@ -204,9 +205,9 @@ useByteString s' $ \(s, _) -> ecdsaVerify x s m p assertBool "signature matches" (isSuccess ret) where- msg = fst $ B16.decode+ msg = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"- key = fst $ B16.decode+ key = fromRight undefined $ B16.decodeBase16 "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a" @@ -217,7 +218,7 @@ ecSecKeyVerify x k assertBool "valid secret key" $ isSuccess ret where- key = fst $ B16.decode+ key = fromRight undefined $ B16.decodeBase16 "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a" ecPubkeyCreateTest :: Assertion@@ -236,9 +237,9 @@ packCStringLen (castPtr o, len) assertEqual "public key matches" pub pk where- key = fst $ B16.decode+ key = fromRight undefined $ B16.decodeBase16 "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"- pub = fst $ B16.decode+ pub = fromRight undefined $ B16.decodeBase16 "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\ \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf" @@ -254,11 +255,11 @@ assertBool "successful secret key tweak" $ isSuccess ret assertEqual "tweaked keys match" expected tweaked where- key = fst $ B16.decode+ key = fromRight undefined $ B16.decodeBase16 "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"- tweak = fst $ B16.decode+ tweak = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"- expected = fst $ B16.decode+ expected = fromRight undefined $ B16.decodeBase16 "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059" ecSecKeyTweakMulTest :: Assertion@@ -274,11 +275,11 @@ assertBool "successful secret key tweak" $ isSuccess ret assertEqual "tweaked keys match" expected tweaked where- key = fst $ B16.decode+ key = fromRight undefined $ B16.decodeBase16 "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"- tweak = fst $ B16.decode+ tweak = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"- expected = fst $ B16.decode+ expected = fromRight undefined $ B16.decodeBase16 "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0" serializeKey :: Ctx -> Ptr PubKey64 -> IO ByteString@@ -310,12 +311,12 @@ assertBool "successful secret key tweak" $ isSuccess ret assertEqual "tweaked keys match" expected tweaked where- pub = fst $ B16.decode+ pub = fromRight undefined $ B16.decodeBase16 "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\ \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"- tweak = fst $ B16.decode+ tweak = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"- expected = fst $ B16.decode+ expected = fromRight undefined $ B16.decodeBase16 "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\ \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368" @@ -332,12 +333,12 @@ assertBool "successful secret key tweak" $ isSuccess ret assertEqual "tweaked keys match" expected tweaked where- pub = fst $ B16.decode+ pub = fromRight undefined $ B16.decodeBase16 "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\ \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"- tweak = fst $ B16.decode+ tweak = fromRight undefined $ B16.decodeBase16 "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"- expected = fst $ B16.decode+ expected = fromRight undefined $ B16.decodeBase16 "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\ \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845" @@ -363,15 +364,15 @@ parse x pub p = useByteString pub $ \(d, dl) -> do ret <- ecPubKeyParse x p d dl unless (isSuccess ret) $ error "could not parse public key"- pub1 = fst $ B16.decode+ pub1 = fromRight undefined $ B16.decodeBase16 "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\ \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"- pub2 = fst $ B16.decode+ pub2 = fromRight undefined $ B16.decodeBase16 "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d153f5\ \77dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"- pub3 = fst $ B16.decode+ pub3 = fromRight undefined $ B16.decodeBase16 "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee3feb\ \d908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"- expected = fst $ B16.decode+ expected = fromRight undefined $ B16.decodeBase16 "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\ \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"
test/Crypto/Secp256k1Spec.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} module Crypto.Secp256k1Spec (spec) where import Control.Monad.Par@@ -7,11 +6,12 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Char8 as B8+import Data.Either (fromRight) import Data.Maybe (fromMaybe, isNothing) import Data.String (fromString) import Data.String.Conversions (cs)-import Test.Hspec import Test.HUnit (Assertion, assertEqual)+import Test.Hspec import Test.QuickCheck spec :: Spec@@ -68,29 +68,29 @@ it "negates tweak" $ property negateTweakTest hexToBytes :: String -> BS.ByteString-hexToBytes = fst . B16.decode . B8.pack+hexToBytes = fromRight undefined . B16.decodeBase16 . B8.pack isStringPubKey :: (PubKey, Bool) -> Bool isStringPubKey (k, c) = k == fromString (cs hex) where- hex = B16.encode $ exportPubKey c k+ hex = B16.encodeBase16 $ exportPubKey c k isStringSig :: (SecKey, Msg) -> Bool isStringSig (k, m) = g == fromString (cs hex) where g = signMsg k m- hex = B16.encode $ exportSig g+ hex = B16.encodeBase16 $ exportSig g isStringMsg :: Msg -> Bool isStringMsg m = m == fromString (cs m') where- m' = B16.encode $ getMsg m+ m' = B16.encodeBase16 $ getMsg m isStringSecKey :: SecKey -> Bool isStringSecKey k = k == fromString (cs hex) where- hex = B16.encode $ getSecKey k+ hex = B16.encodeBase16 $ getSecKey k isStringTweak :: SecKey -> Bool isStringTweak k = t == fromString (cs hex) where t = fromMaybe e . tweak $ getSecKey k- hex = B16.encode $ getTweak t+ hex = B16.encodeBase16 $ getTweak t e = error "Could not extract tweak from secret key" showReadTweak :: SecKey -> Bool@@ -239,9 +239,9 @@ negateTweakTest = assertEqual "can recover secret key 1 after adding tweak 1" oneKey subtracted where- Just oneKey = secKey $ fst $ B16.decode $ B8.pack+ Just oneKey = secKey $ fromRight undefined $ B16.decodeBase16 $ B8.pack "0000000000000000000000000000000000000000000000000000000000000001"- Just oneTwk = tweak $ fst $ B16.decode $ B8.pack+ Just oneTwk = tweak $ fromRight undefined $ B16.decodeBase16 $ B8.pack "0000000000000000000000000000000000000000000000000000000000000001" Just minusOneTwk = tweakNegate oneTwk Just twoKey = tweakAddSecKey oneKey oneTwk