packages feed

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 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)