secp256k1-haskell 0.2.1 → 0.2.2
raw patch · 5 files changed
+61/−19 lines, 5 files
Files
- CHANGELOG.md +7/−0
- secp256k1-haskell.cabal +9/−2
- src/Crypto/Secp256k1.hs +29/−15
- src/Crypto/Secp256k1/Internal.hs +3/−0
- test/Crypto/Secp256k1Spec.hs +13/−2
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.2+### Removed+- Hide tweak negation behind a flag for compatibilidy with Debian 9.++### Fixed+- Correct code that was not compiling with some flags enabled.+ ## 0.2.1 ### Changed - Do not depend on hardcoded DER signatures in tests.
secp256k1-haskell.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: aaa369b9f2d9817845daa3c657860285c04c9ef6c6d22ec3c4b566821e7b8f5d+-- hash: 0b75b1185f390c0f03f09dfc8e18349a5bce92770b10888fc121279d4fa9953f name: secp256k1-haskell-version: 0.2.1+version: 0.2.2 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@@ -32,6 +32,11 @@ manual: True default: False +flag negate+ description: Enable tweak negate+ manual: True+ default: False+ flag recovery description: Enable signature key recovery APIs manual: True@@ -68,6 +73,8 @@ cpp-options: -DSCHNORR if flag(recovery) cpp-options: -DRECOVERY+ if flag(negate)+ cpp-options: -DNEGATE default-language: Haskell2010 test-suite spec
src/Crypto/Secp256k1.hs view
@@ -59,7 +59,9 @@ , tweakAddPubKey , tweakMulPubKey , combinePubKeys+#ifdef NEGATE , tweakNegate+#endif #ifdef ECDH -- * Diffie Hellman@@ -89,12 +91,15 @@ import Data.ByteString.Short (fromShort, toShort) import Data.Hashable (Hashable (..)) import Data.Maybe (fromJust, fromMaybe, isJust)+import Data.Serialize (decode, encode) import Data.String (IsString (..)) import Data.String.Conversions (ConvertibleStrings, cs)-import Foreign (ForeignPtr, alloca, allocaArray,- allocaBytes, mallocForeignPtr,+import Foreign (ForeignPtr, alloca,+ allocaArray, allocaBytes,+ mallocForeignPtr, nullPtr, peek, poke, pokeArray, withForeignPtr)+import Foreign.C.Types (CInt) import System.IO.Unsafe (unsafePerformIO) import Test.QuickCheck (Arbitrary (..), arbitraryBoundedRandom, suchThat)@@ -482,15 +487,18 @@ -- | Add multiple public keys together. combinePubKeys :: [PubKey] -> Maybe PubKey-combinePubKeys pubs = withContext $ \ctx -> pointers [] pubs $ \ps ->- allocaArray (length ps) $ \a -> do- pokeArray a ps- fp <- mallocForeignPtr- ret <- withForeignPtr fp $ \p ->- ecPubKeyCombine ctx p a (fromIntegral $ length ps)- if isSuccess ret- then return $ Just $ PubKey fp- else return Nothing+combinePubKeys pubs = withContext $ \ctx ->+ if pubs == []+ then return Nothing+ else pointers [] pubs $ \ps ->+ allocaArray (length ps) $ \a -> do+ pokeArray a ps+ fp <- mallocForeignPtr+ ret <- withForeignPtr fp $ \p ->+ ecPubKeyCombine ctx p a (fromIntegral $ length ps)+ if isSuccess ret+ then return $ Just $ PubKey fp+ else return Nothing where pointers ps [] f = f ps pointers ps (PubKey fp : pubs') f =@@ -539,7 +547,7 @@ withForeignPtr fk $ \k -> withForeignPtr fm $ \m -> do fg <- mallocForeignPtr ret <- withForeignPtr fg $ \g ->- ecdsaSignRecoverable ctx g m k nullFunPtr nullPtr+ ecdsaSignRecoverable ctx g m k nullPtr nullPtr unless (isSuccess ret) $ error "could not sign message" return $ RecSig fg @@ -552,6 +560,7 @@ if isSuccess ret then return $ Just $ PubKey fp else return Nothing #endif +#ifdef NEGATE tweakNegate :: Tweak -> Maybe Tweak tweakNegate (Tweak fk) = withContext $ \ctx -> do fnew <- mallocForeignPtr@@ -563,6 +572,7 @@ if isSuccess ret then Just (Tweak fnew) else Nothing+#endif #ifdef ECDH -- | Compute Diffie-Hellman secret.@@ -608,10 +618,14 @@ if isSuccess ret then return $ Just $ SecKey fk' else return Nothing signMsgSchnorr :: SecKey -> Msg -> SchnorrSig-signMsgSchnorr (SecKey fk) (Msg fm) = withContext $ \ctx ->- withForeignPtr fk $ \k -> withForeignPtr fm $ \m -> do+signMsgSchnorr (SecKey fk) (Msg fm) =+ withContext $ \ctx ->+ withForeignPtr fk $ \k ->+ withForeignPtr fm $ \m -> do fg <- mallocForeignPtr- ret <- withForeignPtr fg $ \g -> schnorrSign ctx g m k nullFunPtr nullPtr+ ret <-+ withForeignPtr fg $ \g ->+ schnorrSign ctx g m k nullPtr nullPtr unless (isSuccess ret) $ error "could not schnorr-sign message" return $ SchnorrSig fg
src/Crypto/Secp256k1/Internal.hs view
@@ -23,6 +23,7 @@ import qualified Data.Serialize.Get as Get import qualified Data.Serialize.Put as Put import Data.Void (Void)+import Data.Word (Word8) import Foreign (ForeignPtr, FunPtr, Ptr, Storable (..), alloca, castPtr, copyArray, newForeignPtr, withForeignPtr)@@ -413,12 +414,14 @@ -> Ptr Tweak32 -> IO Ret +#ifdef NEGATE foreign import ccall "secp256k1.h secp256k1_ec_privkey_negate" ecTweakNegate :: Ptr Ctx -> Ptr Tweak32 -> IO Ret+#endif foreign import ccall "secp256k1.h secp256k1_ec_pubkey_tweak_add"
test/Crypto/Secp256k1Spec.hs view
@@ -6,12 +6,11 @@ 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, (==>))+import Test.QuickCheck (property) spec :: Spec spec = do@@ -57,7 +56,10 @@ 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+#endif #ifdef ECDH describe "ecdh" $ do it "computes dh secret" $ property $ computeDhSecret@@ -277,6 +279,14 @@ expected = importPubKey $ hexToBytes "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8" +combinePubKeyEmptyListTest :: Assertion+combinePubKeyEmptyListTest =+ assertEqual "empty pubkey list must return Nothing" expected combined+ where+ expected = Nothing+ combined = combinePubKeys []++#ifdef NEGATE negateTweakTest :: Assertion negateTweakTest = assertEqual "can recover secret key 1 after adding tweak 1" oneKey subtracted@@ -288,6 +298,7 @@ Just minusOneTwk = tweakNegate oneTwk Just twoKey = tweakAddSecKey oneKey oneTwk Just subtracted = tweakAddSecKey twoKey minusOneTwk+#endif #ifdef ECDH computeDhSecret :: Assertion