secp256k1-haskell 1.3.0 → 1.4.0
raw patch · 7 files changed
+13/−233 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Crypto.Secp256k1: data Bip340Sig
- Crypto.Secp256k1: data Rand32
- Crypto.Secp256k1: data XOnlyPubKey
- Crypto.Secp256k1: deriveXOnlyPubKey :: Ctx -> PubKey -> XOnlyPubKey
- Crypto.Secp256k1: mkRand32 :: ByteString -> Maybe Rand32
- Crypto.Secp256k1: signBip340 :: Ctx -> SecKey -> Msg -> Maybe Rand32 -> Maybe Bip340Sig
- Crypto.Secp256k1: verifyBip340 :: Ctx -> XOnlyPubKey -> Msg -> Bip340Sig -> Bool
- Crypto.Secp256k1.Internal.Base: Bip340Sig :: ByteString -> Bip340Sig
- Crypto.Secp256k1.Internal.Base: Rand32 :: ByteString -> Rand32
- Crypto.Secp256k1.Internal.Base: XOnlyPubKey :: ByteString -> XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: [$sel:get:Bip340Sig] :: Bip340Sig -> ByteString
- Crypto.Secp256k1.Internal.Base: [$sel:get:Rand32] :: Rand32 -> ByteString
- Crypto.Secp256k1.Internal.Base: [$sel:get:XOnlyPubKey] :: XOnlyPubKey -> ByteString
- Crypto.Secp256k1.Internal.Base: deriveXOnlyPubKey :: Ctx -> PubKey -> XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: exportXOnlyPubKey :: Ctx -> XOnlyPubKey -> ByteString
- Crypto.Secp256k1.Internal.Base: importXOnlyPubKey :: Ctx -> ByteString -> Maybe XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: instance Data.Hashable.Class.Hashable Crypto.Secp256k1.Internal.Base.XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: instance GHC.Classes.Eq Crypto.Secp256k1.Internal.Base.Bip340Sig
- Crypto.Secp256k1.Internal.Base: instance GHC.Classes.Eq Crypto.Secp256k1.Internal.Base.XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: instance GHC.Show.Show Crypto.Secp256k1.Internal.Base.Bip340Sig
- Crypto.Secp256k1.Internal.Base: instance GHC.Show.Show Crypto.Secp256k1.Internal.Base.XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: mkRand32 :: ByteString -> Maybe Rand32
- Crypto.Secp256k1.Internal.Base: newtype Bip340Sig
- Crypto.Secp256k1.Internal.Base: newtype Rand32
- Crypto.Secp256k1.Internal.Base: newtype XOnlyPubKey
- Crypto.Secp256k1.Internal.Base: signBip340 :: Ctx -> SecKey -> Msg -> Maybe Rand32 -> Maybe Bip340Sig
- Crypto.Secp256k1.Internal.Base: verifyBip340 :: Ctx -> XOnlyPubKey -> Msg -> Bip340Sig -> Bool
- Crypto.Secp256k1.Internal.BaseOps: keyPairCreate :: Ptr LCtx -> Ptr KeyPair -> Ptr SecKey32 -> IO CInt
- Crypto.Secp256k1.Internal.BaseOps: schnorrSign :: Ptr LCtx -> Ptr Sig64 -> Ptr Msg32 -> Ptr KeyPair -> Ptr CUChar -> IO CInt
- Crypto.Secp256k1.Internal.BaseOps: schnorrVerify :: Ptr LCtx -> Ptr Sig64 -> Ptr Msg32 -> CSize -> Ptr XOPubKey32 -> IO CInt
- Crypto.Secp256k1.Internal.BaseOps: xOnlyPubKeyFromPubKey :: Ptr LCtx -> Ptr XOPubKey32 -> Ptr CInt -> Ptr PubKey64 -> IO CInt
- Crypto.Secp256k1.Internal.BaseOps: xOnlyPubKeyParse :: Ptr LCtx -> Ptr XOPubKey32 -> Ptr CUChar -> IO CInt
- Crypto.Secp256k1.Internal.BaseOps: xOnlyPubKeySerialize :: Ptr LCtx -> Ptr CUChar -> Ptr XOPubKey32 -> IO CInt
- Crypto.Secp256k1.Internal.ForeignTypes: data KeyPair
- Crypto.Secp256k1.Internal.ForeignTypes: data XOPubKey32
Files
- CHANGELOG.md +12/−0
- secp256k1-haskell.cabal +1/−1
- src/Crypto/Secp256k1.hs +0/−10
- src/Crypto/Secp256k1/Internal/Base.hs +0/−126
- src/Crypto/Secp256k1/Internal/BaseOps.hs +0/−66
- src/Crypto/Secp256k1/Internal/ForeignTypes.hs +0/−4
- test/Crypto/Secp256k1Spec.hs +0/−26
CHANGELOG.md view
@@ -4,6 +4,18 @@ 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). +## [1.4.0] - 2024-08-28++### Removed++- Removed BIP-340 support. Fedora’s version of secp256k1 libraries do not have required symbols.++## [1.3.0] - 2024-08-28++### Added++- Added BIP-340 support.+ ## [1.2.0] - 2023-03-14 ### Changed
secp256k1-haskell.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: secp256k1-haskell-version: 1.3.0+version: 1.4.0 synopsis: Bindings for secp256k1 description: Sign and verify signatures using the secp256k1 library. category: Crypto
src/Crypto/Secp256k1.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE DuplicateRecordFields #-}- -- | -- Module : Crypto.Secp256k1 -- License : UNLICENSE@@ -58,15 +57,6 @@ tweakMulPubKey, combinePubKeys, tweakNegate,-- -- * BIP340 Support- XOnlyPubKey,- deriveXOnlyPubKey,- Rand32,- mkRand32,- Bip340Sig,- signBip340,- verifyBip340, ) where
src/Crypto/Secp256k1/Internal/Base.hs view
@@ -40,12 +40,6 @@ ecdsaSignatureSerializeCompact, ecdsaSignatureSerializeDer, ecdsaVerify,- keyPairCreate,- schnorrSign,- schnorrVerify,- xOnlyPubKeyFromPubKey,- xOnlyPubKeyParse,- xOnlyPubKeySerialize, ) import Crypto.Secp256k1.Internal.Context (Ctx (..)) import Crypto.Secp256k1.Internal.ForeignTypes@@ -63,7 +57,6 @@ ) import Data.ByteString (ByteString) import Data.ByteString qualified as BS-import Data.ByteString.Unsafe qualified as BU import Data.Hashable (Hashable (..)) import Data.Maybe (fromJust, fromMaybe, isJust) import Data.String (IsString (..))@@ -452,122 +445,3 @@ valid_bs = bs_gen `suchThat` isJust bs_gen = secKey . BS.pack <$> replicateM 32 arbitraryBoundedRandom gen_key = fromJust <$> valid_bs---- | An x-only pubkey corresponds to the keys @(x,y)@ and @(x, -y)@. The--- equality test only checks the x-coordinate. An x-only pubkey serializes to 32--- bytes.------ @since 1.3.0-newtype XOnlyPubKey = XOnlyPubKey {get :: ByteString}- deriving (Eq, Hashable)--instance Show XOnlyPubKey where- showsPrec _ = showsHex . (.get)--newtype Bip340Sig = Bip340Sig {get :: ByteString}- deriving (Eq)--instance Show Bip340Sig where- showsPrec _ = showsHex . (.get)--newtype Rand32 = Rand32 {get :: ByteString}---- | Create a 'Rand32' value from a 32-byte 'ByteString'-mkRand32 :: ByteString -> Maybe Rand32-mkRand32 bytes- | BS.length bytes == 32 = Just $ Rand32 bytes- | otherwise = Nothing---- | Encode an x-only pubkey to bytes------ @since 1.3.0-exportXOnlyPubKey :: Ctx -> XOnlyPubKey -> ByteString-exportXOnlyPubKey (Ctx fctx) pubKey = unsafePerformIO $- withForeignPtr fctx $ \ctx ->- unsafeUseByteString pubKey.get $ \(pub_key, _) ->- allocaBytes 32 $ \out_ptr -> do- result <- xOnlyPubKeySerialize ctx out_ptr pub_key- if isSuccess result- then packByteString (out_ptr, 32)- else free out_ptr >> error "Unable to serialize x-only pubkey"---- | Import an x-only pubkey from bytes------ @since 1.3.0-importXOnlyPubKey :: Ctx -> ByteString -> Maybe XOnlyPubKey-importXOnlyPubKey (Ctx fctx) inputBytes- | BS.length inputBytes == 32 = unsafePerformIO $- withForeignPtr fctx $ \ctx ->- unsafeUseByteString inputBytes $ \(input, _) -> do- pub_key <- mallocBytes 64- result <- xOnlyPubKeyParse ctx pub_key input- if isSuccess result- then Just . XOnlyPubKey <$> unsafePackByteString (pub_key, 64)- else pure Nothing- | otherwise = Nothing---- | Derive an x-only key from a pub key------ @since 1.3.0-deriveXOnlyPubKey :: Ctx -> PubKey -> XOnlyPubKey-deriveXOnlyPubKey (Ctx fctx) pubKey = unsafePerformIO $- withForeignPtr fctx $ \ctx ->- unsafeUseByteString pubKey.get $ \(pub_key, _) -> do- xonly_pub_key <- mallocBytes 64- result <- xOnlyPubKeyFromPubKey ctx xonly_pub_key nullPtr pub_key- if isSuccess result- then XOnlyPubKey <$> unsafePackByteString (xonly_pub_key, 64)- else free xonly_pub_key >> error "Unable to derive x-only pubkey"---- | Sign a message according to BIP 340------ @since 1.3.0-signBip340 ::- Ctx ->- -- | Secret key- SecKey ->- -- | Message- Msg ->- -- | Randomness- Maybe Rand32 ->- -- | Signature- Maybe Bip340Sig-signBip340 (Ctx fctx) theSecKey message rand32 = unsafePerformIO $- withForeignPtr fctx $ \ctx ->- unsafeUseByteString theSecKey.get $ \(sec_key, _) ->- allocaBytes 96 $ \key_pair -> do- -- The 'SecKey' API guarantees that the following call will succeed- _ <- keyPairCreate ctx key_pair sec_key- unsafeUseByteString message.get $ \(msg_ptr, _) -> do- withRand32 $ \(rand_ptr, _) -> do- sig_ptr <- mallocBytes 64- result <- schnorrSign ctx sig_ptr msg_ptr key_pair rand_ptr- if isSuccess result- then Just . Bip340Sig <$> unsafePackByteString (sig_ptr, 64)- else Nothing <$ free sig_ptr- where- withRand32 = maybe ($ (nullPtr, 0)) (unsafeUseByteString . (.get)) rand32---- | Verify a message according to BIP 340------ @since 1.3.0-verifyBip340 ::- Ctx ->- XOnlyPubKey ->- -- | Message- Msg ->- -- | Signature- Bip340Sig ->- Bool-verifyBip340 (Ctx fctx) xOnlyPubKey message sig = unsafePerformIO $- withForeignPtr fctx $ \ctx ->- unsafeUseByteString xOnlyPubKey.get $ \(pub_key, _) ->- unsafeUseByteString message.get $ \(msg_ptr, messageSize) ->- unsafeUseByteString sig.get $ \(sig_ptr, _) ->- isSuccess- <$> schnorrVerify- ctx- sig_ptr- msg_ptr- (fromIntegral messageSize)- pub_key
src/Crypto/Secp256k1/Internal/BaseOps.hs view
@@ -11,7 +11,6 @@ import Crypto.Secp256k1.Internal.ForeignTypes ( Compact64,- KeyPair, LCtx, Msg32, NonceFun,@@ -22,7 +21,6 @@ SerFlags, Sig64, Tweak32,- XOPubKey32, ) import Foreign (FunPtr, Ptr) import Foreign.C@@ -172,67 +170,3 @@ -- | number of public keys CInt -> IO Ret--foreign import ccall unsafe "secp256k1.h secp256k1_schnorrsig_sign"- schnorrSign ::- Ptr LCtx ->- -- | Signature- Ptr Sig64 ->- -- | Message- Ptr Msg32 ->- -- | Keypair- Ptr KeyPair ->- -- | Randomness- Ptr CUChar ->- IO CInt--foreign import ccall unsafe "secp256k1.h secp256k1_schnorrsig_verify"- schnorrVerify ::- Ptr LCtx ->- -- | Signature- Ptr Sig64 ->- -- | Message- Ptr Msg32 ->- -- | Message length- CSize ->- -- | X-Only pubkey- Ptr XOPubKey32 ->- IO CInt--foreign import ccall unsafe "secp256k1.h secp256k1_keypair_create"- keyPairCreate ::- Ptr LCtx ->- -- | Keypair- Ptr KeyPair ->- -- | Secret key- Ptr SecKey32 ->- IO CInt--foreign import ccall unsafe "secp256k1.h secp256k1_xonly_pubkey_parse"- xOnlyPubKeyParse ::- Ptr LCtx ->- -- | Parsed X-Only pubkey- Ptr XOPubKey32 ->- -- | Input buffer- Ptr CUChar ->- IO CInt--foreign import ccall unsafe "secp256k1.h secp256k1_xonly_pubkey_serialize"- xOnlyPubKeySerialize ::- Ptr LCtx ->- -- | Output buffer- Ptr CUChar ->- -- | X-Only pubkey- Ptr XOPubKey32 ->- IO CInt--foreign import ccall unsafe "secp256k1.h secp256k1_xonly_pubkey_from_pubkey"- xOnlyPubKeyFromPubKey ::- Ptr LCtx ->- -- | X-only pubkey- Ptr XOPubKey32 ->- -- | Parity- Ptr CInt ->- -- | Pubkey- Ptr PubKey64 ->- IO CInt
src/Crypto/Secp256k1/Internal/ForeignTypes.hs view
@@ -16,10 +16,6 @@ data PubKey64 -data XOPubKey32--data KeyPair- data Msg32 data Sig64
test/Crypto/Secp256k1Spec.hs view
@@ -72,11 +72,6 @@ property $ combinePubKeyEmptyListTest ctx it "negates tweak" $ \ctx -> property $ negateTweakTest ctx- describe "BIP 340" $ do- it "verifies a signed message (null rand32)" $ \ctx ->- property $ bip340SigTestNull ctx- it "verifies a signed message (not-null rand32)" $ \ctx ->- property $ bip340SigTest ctx hexToBytes :: String -> BS.ByteString hexToBytes = decodeBase16 . assertBase16 . B8.pack@@ -315,24 +310,3 @@ Just minusOneTwk = tweakNegate ctx oneTwk Just twoKey = tweakAddSecKey ctx oneKey oneTwk Just subtracted = tweakAddSecKey ctx twoKey minusOneTwk--bip340SigTestNull :: Ctx -> Assertion-bip340SigTestNull ctx =- assertBool "verifies signature" $- verifyBip340 ctx pk theMsg sig- where- Just sk = secKey $ BS.replicate 32 0x01- pk = deriveXOnlyPubKey ctx $ derivePubKey ctx sk- Just theMsg = msg $ BS.replicate 32 0x02- Just sig = signBip340 ctx sk theMsg Nothing--bip340SigTest :: Ctx -> Assertion-bip340SigTest ctx =- assertBool "verifies signature" $- verifyBip340 ctx pk theMsg sig- where- Just sk = secKey $ BS.replicate 32 0x01- pk = deriveXOnlyPubKey ctx $ derivePubKey ctx sk- Just theMsg = msg $ BS.replicate 32 0x02- Just r = mkRand32 $ BS.replicate 32 0x03- Just sig = signBip340 ctx sk theMsg (Just r)