diff --git a/libsecp256k1.cabal b/libsecp256k1.cabal
--- a/libsecp256k1.cabal
+++ b/libsecp256k1.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           libsecp256k1
-version:        0.0.0
+version:        0.0.1
 synopsis:       Bindings for secp256k1
 description:    Sign and verify signatures using the secp256k1 library.
 category:       Crypto
diff --git a/src/Crypto/Secp256k1.hs b/src/Crypto/Secp256k1.hs
--- a/src/Crypto/Secp256k1.hs
+++ b/src/Crypto/Secp256k1.hs
@@ -317,7 +317,7 @@
         alloca $ \len_ptr ->
             allocaBytes len $ \out_ptr -> do
                 poke len_ptr $ fromIntegral len
-                ret <- Prim.ecPubKeySerialize Prim.ctx out_ptr len_ptr in_ptr flags
+                ret <- Prim.ecPubkeySerialize Prim.ctx out_ptr len_ptr in_ptr flags
                 unless (Prim.isSuccess ret) $ error "could not serialize public key"
                 final_len <- peek len_ptr
                 Prim.packByteString (out_ptr, final_len)
@@ -407,7 +407,7 @@
 derivePubKey (SecKey sec_key) = unsafePerformIO $
     Prim.unsafeUseByteString sec_key $ \(sec_key_ptr, _) -> do
         pub_key_ptr <- mallocBytes 64
-        ret <- Prim.ecPubKeyCreate Prim.ctx pub_key_ptr sec_key_ptr
+        ret <- Prim.ecPubkeyCreate Prim.ctx pub_key_ptr sec_key_ptr
         unless (Prim.isSuccess ret) $ do
             free pub_key_ptr
             error "could not compute public key"
@@ -445,7 +445,7 @@
 tweakAddPubKey (PubKey pub_key) (Tweak t) = unsafePerformIO $
     Prim.unsafeUseByteString new_bs $ \(pub_key_ptr, _) ->
         Prim.unsafeUseByteString t $ \(tweak_ptr, _) -> do
-            ret <- Prim.ecPubKeyTweakAdd Prim.ctx pub_key_ptr tweak_ptr
+            ret <- Prim.ecPubkeyTweakAdd Prim.ctx pub_key_ptr tweak_ptr
             if Prim.isSuccess ret
                 then return (Just (PubKey new_bs))
                 else return Nothing
@@ -459,7 +459,7 @@
 tweakMulPubKey (PubKey pub_key) (Tweak t) = unsafePerformIO $
     Prim.unsafeUseByteString new_bs $ \(pub_key_ptr, _) ->
         Prim.unsafeUseByteString t $ \(tweak_ptr, _) -> do
-            ret <- Prim.ecPubKeyTweakMul Prim.ctx pub_key_ptr tweak_ptr
+            ret <- Prim.ecPubkeyTweakMul Prim.ctx pub_key_ptr tweak_ptr
             if Prim.isSuccess ret
                 then return (Just (PubKey new_bs))
                 else return Nothing
@@ -475,7 +475,7 @@
         allocaArray (length ps) $ \a -> do
             out <- mallocBytes 64
             pokeArray a ps
-            ret <- Prim.ecPubKeyCombine Prim.ctx out a (fromIntegral $ length ps)
+            ret <- Prim.ecPubkeyCombine Prim.ctx out a (fromIntegral $ length ps)
             if Prim.isSuccess ret
                 then do
                     bs <- Prim.unsafePackByteString (out, 64)
diff --git a/src/Crypto/Secp256k1/Prim.hs b/src/Crypto/Secp256k1/Prim.hs
--- a/src/Crypto/Secp256k1/Prim.hs
+++ b/src/Crypto/Secp256k1/Prim.hs
@@ -28,527 +28,1350 @@
 import System.IO.Unsafe (unsafePerformIO)
 
 
-data LCtx
-data Pubkey64
-data XonlyPubkey64
-data Keypair96
-data Msg32
-data RecSig65
-data Sig64
-data Compact64
-data Seed32
-data Seckey32
-data Tweak32
-data SchnorrExtra
-data Scratch
-data Bytes (n :: Nat)
-
-
-type CtxFlags = CUInt
-type SerFlags = CUInt
-type Ret = CInt
-
-
-type NonceFun a =
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr a ->
-    CInt ->
-    IO CInt
-
-
-type NonceFunHardened a =
-    Ptr CUChar ->
-    Ptr CUChar ->
-    CSize ->
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr CUChar ->
-    CSize ->
-    Ptr a ->
-    IO CInt
-
-
-type EcdhHashFun a =
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr CUChar ->
-    Ptr a ->
-    IO CInt
-
-
-type Ctx = Ptr LCtx
-
-
-verify :: CtxFlags
-verify = 0x0101
-
-
-sign :: CtxFlags
-sign = 0x0201
-
-
-signVerify :: CtxFlags
-signVerify = 0x0301
-
-
-compressed :: SerFlags
-compressed = 0x0102
-
-
-uncompressed :: SerFlags
-uncompressed = 0x0002
-
-
-isSuccess :: Ret -> Bool
-isSuccess 0 = False
-isSuccess 1 = True
-isSuccess n = error $ "isSuccess expected 0 or 1 but got " ++ show n
-
-
-unsafeUseByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
-unsafeUseByteString bs f =
-    BU.unsafeUseAsCStringLen bs $ \(b, l) ->
-        f (castPtr b, fromIntegral l)
-
-
-useByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
-useByteString bs f =
-    BS.useAsCStringLen bs $ \(b, l) ->
-        f (castPtr b, fromIntegral l)
-
-
-unsafePackByteString :: (Ptr a, CSize) -> IO ByteString
-unsafePackByteString (b, l) =
-    BU.unsafePackMallocCStringLen (castPtr b, fromIntegral l)
-
-
-packByteString :: (Ptr a, CSize) -> IO ByteString
-packByteString (b, l) =
-    BS.packCStringLen (castPtr b, fromIntegral l)
-
-
-ctx :: Ctx
-ctx = unsafePerformIO $ contextCreate signVerify
-{-# NOINLINE ctx #-}
-
-
--- secp256k1_context_clone
-foreign import ccall safe "secp256k1.h secp256k1_context_clone"
-    contextClone :: Ctx -> IO Ctx
-
-
--- secp256k1_context_create
-foreign import ccall safe "secp256k1.h secp256k1_context_create"
-    contextCreate :: CtxFlags -> IO Ctx
-
-
--- secp256k1_context_destroy
-foreign import ccall safe "secp256k1.h &secp256k1_context_destroy"
-    contextDestroy :: FunPtr (Ctx -> IO ())
-
-
--- secp256k1_context_no_precomp
-foreign import ccall safe "secp256k1.h secp256k1_context_no_precomp"
-    contextNoPrecomp :: Ctx
-
-
--- secp256k1_context_preallocated_clone
-foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_clone"
-    contextPreallocatedClone :: Ctx -> Ptr (Bytes n) -> IO Ctx
-
-
--- secp256k1_context_preallocated_clone_size
-foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_clone_size"
-    contextPreallocatedCloneSize :: Ctx -> IO CSize
-
-
--- secp256k1_context_preallocated_create
-foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_create"
-    contextPreallocatedCreate :: Ptr (Bytes n) -> CUInt -> IO Ctx
-
-
--- secp256k1_context_preallocated_destroy
-foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_destroy"
-    contextPreallocatedDestroy :: Ctx -> IO ()
-
-
--- secp256k1_context_preallocated_size
-foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_size"
-    contextPreallocatedSize :: CUInt -> IO CSize
-
-
--- secp256k1_context_randomize
-foreign import ccall safe "secp256k1.h secp256k1_context_randomize"
-    contextRandomize :: Ctx -> Ptr Seed32 -> IO Ret
-
-
--- secp256k1_context_set_error_callback
-foreign import ccall safe "secp256k1.h secp256k1_context_set_error_callback"
-    setErrorCallback ::
-        Ctx ->
-        -- | message, data
-        FunPtr (CString -> Ptr a -> IO ()) ->
-        -- | data
-        Ptr a ->
-        IO ()
-
-
--- secp256k1_context_set_illegal_callback
-foreign import ccall safe "secp256k1.h secp256k1_context_set_illegal_callback"
-    setIllegalCallback ::
-        Ctx ->
-        -- | message, data
-        FunPtr (CString -> Ptr a -> IO ()) ->
-        -- | data
-        Ptr a ->
-        IO ()
-
-
--- secp256k1_ecdh
-foreign import ccall safe "secp256k1.h secp256k1_ecdh"
-    ecdh :: Ctx -> Ptr (Bytes n) -> Ptr Pubkey64 -> Ptr Seckey32 -> FunPtr (EcdhHashFun a) -> Ptr a -> IO Ret
-
-
--- secp256k1_ecdh_hash_function_default
-foreign import ccall safe "secp256k1.h &secp256k1_ecdh_hash_function_default"
-    ecdhHashFunctionDefault :: FunPtr (EcdhHashFun a)
-
-
--- secp256k1_ecdh_hash_function_sha256
-foreign import ccall safe "secp256k1.h &secp256k1_ecdh_hash_sha256"
-    ecdhHashSha256 :: FunPtr (EcdhHashFun a)
-
-
--- secp256k1_ecdsa_recover
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recover"
-    ecdsaRecover :: Ctx -> Ptr Pubkey64 -> Ptr RecSig65 -> Ptr Msg32 -> IO Ret
-
-
--- secp256k1_ecdsa_recoverable_signature_convert
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_convert"
-    ecdsaRecoverableSignatureConvert :: Ctx -> Ptr Sig64 -> Ptr RecSig65 -> IO Ret
-
-
--- secp256k1_ecdsa_recoverable_signature_parse_compact
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_parse_compact"
-    ecdsaRecoverableSignatureParseCompact :: Ctx -> Ptr RecSig65 -> Ptr (Bytes 64) -> CInt -> IO Ret
-
-
--- secp256k1_ecdsa_recoverable_signature_serialize_compact
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_serialize_compact"
-    ecdsaRecoverableSignatureSerializeCompact :: Ctx -> Ptr (Bytes 64) -> Ptr CInt -> Ptr RecSig65 -> IO Ret
-
-
--- secp256k1_ecdsa_sign
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_sign"
-    ecdsaSign ::
-        Ctx ->
-        Ptr Sig64 ->
-        Ptr Msg32 ->
-        Ptr Seckey32 ->
-        FunPtr (NonceFun a) ->
-        -- | nonce data
-        Ptr a ->
-        IO Ret
-
-
--- secp256k1_ecdsa_signature_normalize
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_normalize"
-    ecdsaSignatureNormalize ::
-        Ctx ->
-        -- | output
-        Ptr Sig64 ->
-        -- | input
-        Ptr Sig64 ->
-        IO Ret
-
-
--- secp256k1_ecdsa_signature_parse_compact
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_parse_compact"
-    ecdsaSignatureParseCompact ::
-        Ctx ->
-        Ptr Sig64 ->
-        Ptr Compact64 ->
-        IO Ret
-
-
--- secp256k1_ecdsa_signature_parse_der
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_parse_der"
-    ecdsaSignatureParseDer ::
-        Ctx ->
-        Ptr Sig64 ->
-        -- | encoded DER signature
-        Ptr (Bytes n) ->
-        -- | size of encoded signature
-        CSize ->
-        IO Ret
-
-
--- secp256k1_ecdsa_signature_serialize_compact
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_serialize_compact"
-    ecdsaSignatureSerializeCompact ::
-        Ctx ->
-        Ptr Compact64 ->
-        Ptr Sig64 ->
-        IO Ret
-
-
--- secp256k1_ecdsa_signature_serialize_der
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_serialize_der"
-    ecdsaSignatureSerializeDer ::
-        Ctx ->
-        -- | array for encoded signature, must be large enough
-        Ptr (Bytes n) ->
-        -- | size of encoded signature, will be updated
-        Ptr CSize ->
-        Ptr Sig64 ->
-        IO Ret
-
-
--- secp256k1_ecdsa_sign_recoverable
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_sign_recoverable"
-    ecdsaSignRecoverable ::
-        Ctx -> Ptr RecSig65 -> Ptr Msg32 -> Ptr Seckey32 -> FunPtr (NonceFun a) -> Ptr a -> IO Ret
-
-
--- secp256k1_ecdsa_verify
-foreign import ccall safe "secp256k1.h secp256k1_ecdsa_verify"
-    ecdsaVerify ::
-        Ctx ->
-        Ptr Sig64 ->
-        Ptr Msg32 ->
-        Ptr Pubkey64 ->
-        IO Ret
-
-
--- secp256k1_ec_privkey_negate
-{-# DEPRECATED ecPrivkeyNegate "use ecSeckeyNegate instead" #-}
-foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_negate"
-    ecPrivkeyNegate ::
-        Ctx ->
-        Ptr Tweak32 ->
-        IO Ret
-
-
--- secp256k1_ec_privkey_tweak_add
-{-# DEPRECATED ecPrivkeyTweakAdd "use ecSeckeyTweakAdd instead" #-}
-foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_tweak_add"
-    ecPrivkeyTweakAdd ::
-        Ctx ->
-        Ptr Seckey32 ->
-        Ptr Tweak32 ->
-        IO Ret
-
-
--- secp256k1_ec_privkey_tweak_mul
-{-# DEPRECATED ecPrivkeyTweakMul "use ecSeckeyTweakMul instead" #-}
-foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_tweak_mul"
-    ecPrivkeyTweakMul ::
-        Ctx ->
-        Ptr Seckey32 ->
-        Ptr Tweak32 ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_cmp
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_cmp"
-    ecPubkeyCmp ::
-        Ctx ->
-        Ptr Pubkey64 ->
-        Ptr Pubkey64
-
-
--- secp256k1_ec_pubkey_combine
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_combine"
-    ecPubKeyCombine ::
-        Ctx ->
-        -- | pointer to public key storage
-        Ptr Pubkey64 ->
-        -- | pointer to array of public keys
-        Ptr (Ptr Pubkey64) ->
-        -- | number of public keys
-        CInt ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_create
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_create"
-    ecPubKeyCreate ::
-        Ctx ->
-        Ptr Pubkey64 ->
-        Ptr Seckey32 ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_negate
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_negate"
-    ecPubkeyNegate :: Ctx -> Ptr Pubkey64 -> IO Ret
-
-
--- secp256k1_ec_pubkey_parse
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_parse"
-    ecPubkeyParse ::
-        Ctx ->
-        Ptr Pubkey64 ->
-        -- | encoded public key array
-        Ptr (Bytes n) ->
-        -- | size of encoded public key array
-        CSize ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_serialize
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_serialize"
-    ecPubKeySerialize ::
-        Ctx ->
-        -- | array for encoded public key, must be large enough
-        Ptr (Bytes n) ->
-        -- | size of encoded public key, will be updated
-        Ptr CSize ->
-        Ptr Pubkey64 ->
-        SerFlags ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_tweak_add
-foreign import ccall unsafe "secp256k1.h secp256k1_ec_pubkey_tweak_add"
-    ecPubKeyTweakAdd ::
-        Ctx ->
-        Ptr Pubkey64 ->
-        Ptr Tweak32 ->
-        IO Ret
-
-
--- secp256k1_ec_pubkey_tweak_mul
-foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_tweak_mul"
-    ecPubKeyTweakMul ::
-        Ctx ->
-        Ptr Pubkey64 ->
-        Ptr Tweak32 ->
-        IO Ret
-
-
--- secp256k1_ec_seckey_negate
-foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_negate"
-    ecSeckeyNegate :: Ctx -> Ptr Seckey32 -> IO Ret
-
-
--- secp256k1_ec_seckey_tweak_add
-foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_tweak_add"
-    ecSeckeyTweakAdd :: Ctx -> Ptr Seckey32 -> Ptr Tweak32 -> IO Ret
-
-
--- secp256k1_ec_seckey_tweak_mul
-foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_tweak_mul"
-    ecSeckeyTweakMul :: Ctx -> Ptr Seckey32 -> Ptr Tweak32 -> IO Ret
-
-
--- secp256k1_ec_seckey_verify
-foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_verify"
-    ecSecKeyVerify ::
-        Ctx ->
-        Ptr Seckey32 ->
-        IO Ret
-
-
--- secp256k1_keypair_create
-foreign import ccall safe "secp256k1.h secp256k1_keypair_create"
-    keypairCreate :: Ctx -> Ptr Keypair96 -> Ptr Seckey32 -> IO Ret
-
-
--- secp256k1_keypair_pub
-foreign import ccall safe "secp256k1.h secp256k1_keypair_pub"
-    keypairPub :: Ctx -> Ptr Pubkey64 -> Ptr Keypair96 -> IO Ret
-
-
--- secp256k1_keypair_sec
-foreign import ccall safe "secp256k1.h secp256k1_keypair_sec"
-    keypairSec :: Ctx -> Ptr Seckey32 -> Ptr Keypair96 -> IO Ret
-
-
--- secp256k1_keypair_xonly_pub
-foreign import ccall safe "secp256k1.h secp256k1_keypair_xonly_pub"
-    keypairXonlyPub :: Ctx -> Ptr XonlyPubkey64 -> Ptr CInt -> Ptr Keypair96 -> IO Ret
-
-
--- secp256k1_keypair_xonly_tweak_add
-foreign import ccall safe "secp256k1.h secp256k1_keypair_xonly_tweak_add"
-    keypairXonlyTweakAdd :: Ctx -> Ptr Keypair96 -> Ptr Tweak32 -> IO Ret
-
-
--- secp256k1_nonce_function_bip340
-foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_bip340"
-    nonceFunctionBip340 :: FunPtr (NonceFunHardened a)
-
-
--- secp256k1_nonce_function_default
-foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_default"
-    nonceFunctionDefault :: FunPtr (NonceFun a)
-
-
--- secp256k1_nonce_function_rfc6979
-foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_rfc6979"
-    nonceFunctionRfc6979 :: FunPtr (NonceFun a)
-
-
--- secp256k1_schnorrsig_sign
-foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_sign"
-    schnorrsigSign :: Ctx -> Ptr Sig64 -> Ptr Msg32 -> Ptr Keypair96 -> Ptr (Bytes 32) -> IO Ret
-
-
--- secp256k1_schnorrsig_sign_custom
-foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_sign_custom"
-    schnorrsigSignCustom :: Ctx -> Ptr Sig64 -> Ptr (Bytes n) -> CSize -> Ptr Keypair96 -> Ptr SchnorrExtra -> IO Ret
-
-
--- secp256k1_schnorrsig_verify
-foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_verify"
-    schnorrSigSignVerify :: Ctx -> Ptr Sig64 -> Ptr (Bytes n) -> CSize -> Ptr XonlyPubkey64 -> IO Ret
-
-
--- secp256k1_scratch_space_create
-foreign import ccall safe "secp256k1.h secp256k1_scratch_space_create"
-    scratchSpaceCreate :: Ctx -> CSize -> IO (Ptr Scratch)
-
-
--- secp256k1_scratch_space_destroy
-foreign import ccall safe "secp256k1.h secp256k1_scratch_space_destroy"
-    scratchSpaceDestroy :: Ctx -> Ptr Scratch -> IO ()
-
-
--- secp256k1_tagged_sha256
-foreign import ccall safe "secp256k1.h secp256k1_tagged_sha256"
-    taggedSha256 :: Ctx -> Ptr (Bytes 32) -> Ptr (Bytes n) -> CSize -> Ptr (Bytes n) -> CSize -> IO Ret
-
-
--- secp256k1_xonly_pubkey_cmp
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_cmp"
-    xonlyPubkeyCmp :: Ctx -> Ptr XonlyPubkey64 -> Ptr XonlyPubkey64 -> IO Ret
-
-
--- secp256k1_xonly_pubkey_from_pubkey
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_from_pubkey"
-    xonlyPubkeyFromPubkey :: Ctx -> Ptr XonlyPubkey64 -> Ptr CInt -> Ptr Pubkey64 -> IO Ret
-
-
--- secp256k1_xonly_pubkey_parse
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_parse"
-    xonlyPubkeyParse :: Ctx -> Ptr XonlyPubkey64 -> Ptr (Bytes 32) -> IO Ret
-
-
--- secp256k1_xonly_pubkey_serialize
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_serialize"
-    xonlyPubkeySerialize :: Ctx -> Ptr (Bytes 32) -> Ptr XonlyPubkey64 -> IO Ret
-
-
--- secp256k1_xonly_pubkey_tweak_add
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_tweak_add"
-    xonlyPubkeyTweakAdd :: Ctx -> Ptr Pubkey64 -> Ptr XonlyPubkey64 -> Ptr Tweak32 -> IO Ret
-
-
--- secp256k1_xonly_pubkey_tweak_add_check
-foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_tweak_add_check"
-    xonlyPubkeyTweakAddCheck :: Ctx -> Ptr (Bytes 32) -> CInt -> Ptr XonlyPubkey64 -> Ptr Tweak32 -> IO Ret
+type Ctx = Ptr LCtx
+type CtxFlags = CUInt
+type SerFlags = CUInt
+type Ret = CInt
+
+
+verify :: CtxFlags
+verify = 0x0101
+
+
+sign :: CtxFlags
+sign = 0x0201
+
+
+signVerify :: CtxFlags
+signVerify = 0x0301
+
+
+compressed :: SerFlags
+compressed = 0x0102
+
+
+uncompressed :: SerFlags
+uncompressed = 0x0002
+
+
+isSuccess :: Ret -> Bool
+isSuccess 0 = False
+isSuccess 1 = True
+isSuccess n = error $ "isSuccess expected 0 or 1 but got " ++ show n
+
+
+unsafeUseByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
+unsafeUseByteString bs f =
+    BU.unsafeUseAsCStringLen bs $ \(b, l) ->
+        f (castPtr b, fromIntegral l)
+
+
+useByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
+useByteString bs f =
+    BS.useAsCStringLen bs $ \(b, l) ->
+        f (castPtr b, fromIntegral l)
+
+
+unsafePackByteString :: (Ptr a, CSize) -> IO ByteString
+unsafePackByteString (b, l) =
+    BU.unsafePackMallocCStringLen (castPtr b, fromIntegral l)
+
+
+packByteString :: (Ptr a, CSize) -> IO ByteString
+packByteString (b, l) =
+    BS.packCStringLen (castPtr b, fromIntegral l)
+
+
+ctx :: Ctx
+ctx = unsafePerformIO $ contextCreate signVerify
+{-# NOINLINE ctx #-}
+
+
+-- * Context Operations
+
+
+-- | Updates the context randomization to protect against side-channel leakage.
+--
+-- While secp256k1 code is written to be constant-time no matter what secret
+-- values are, it's possible that a future compiler may output code which isn't,
+-- and also that the CPU may not emit the same radio frequencies or draw the same
+-- amount power for all values.
+--
+-- This function provides a seed which is combined into the blinding value: that
+-- blinding value is added before each multiplication (and removed afterwards) so
+-- that it does not affect function results, but shields against attacks which
+-- rely on any input-dependent behaviour.
+--
+-- This function has currently an effect only on contexts initialized for signing
+-- because randomization is currently used only for signing. However, this is not
+-- guaranteed and may change in the future. It is safe to call this function on
+-- contexts not initialized for signing; then it will have no effect and return 1.
+--
+-- You should call this after 'contextCreate' or
+-- 'contextClone' (and 'contextPreallocatedCreate' or
+-- 'contextClone', resp.), and you may call this repeatedly afterwards.
+foreign import ccall safe "secp256k1.h secp256k1_context_randomize"
+    contextRandomize ::
+        -- | __Mutated__: pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Input__: pointer to a 32-byte random seed (NULL resets to initial state)
+        Ptr Seed32 ->
+        -- | __Returns__: 1 if randomization successfully updated or nothing to randomize OR 0 if there was an error
+        IO Ret
+
+
+-- ** Allocating
+
+
+-- | Copy a secp256k1 context object (into dynamically allocated memory).
+--
+--  This function uses malloc to allocate memory. It is guaranteed that malloc is
+--  called at most once for every call of this function. If you need to avoid dynamic
+--  memory allocation entirely, see the functions in the [Preallocated](#g:preallocated) section.
+foreign import ccall safe "secp256k1.h secp256k1_context_clone"
+    contextClone ::
+        -- | __Input:__ an existing context to copy (cannot be NULL)
+        Ctx ->
+        -- | __Returns:__ a newly created context object.
+        IO Ctx
+
+
+-- | Create a secp256k1 context object (in dynamically allocated memory).
+--
+--  This function uses malloc to allocate memory. It is guaranteed that malloc is
+--  called at most once for every call of this function. If you need to avoid dynamic
+--  memory allocation entirely, see the functions in secp256k1_preallocated.h.
+--
+--  See also 'contextRandomize'.
+foreign import ccall safe "secp256k1.h secp256k1_context_create"
+    contextCreate ::
+        -- | __Input:__ which parts of the context to initialize.
+        CtxFlags ->
+        -- | __Returns:__ a newly created context object.
+        IO Ctx
+
+
+-- | Destroy a secp256k1 context object (created in dynamically allocated memory).
+--
+--  The context pointer may not be used afterwards.
+--
+--  The context to destroy must have been created using 'contextCreate'
+--  or 'contextClone'. If the context has instead been created using
+--  'contextPreallocatedCreate' or 'contextPreallocatedClone', the
+--  behaviour is undefined. In that case, 'contextPreallocatedDestroy' must
+--  be used instead.
+foreign import ccall safe "secp256k1.h secp256k1_context_destroy"
+    contextDestroy ::
+        -- | an existing context to destroy, constructed using 'contextCreate' or 'contextClone'
+        Ctx ->
+        IO ()
+
+
+-- ** Preallocated #preallocated#
+
+
+-- $preallocated
+-- functions in this secion are intended for settings in which it
+-- is not possible or desirable to rely on dynamic memory allocation. It provides
+-- functions for creating, cloning, and destroying secp256k1 context objects in a
+-- contiguous fixed-size block of memory provided by the caller.
+--
+-- Context objects created by functions in this section can be used like contexts
+-- objects created by functions in secp256k1.h, i.e., they can be passed to any
+-- API function that expects a context object (see secp256k1.h for details). The
+-- only exception is that context objects created by functions in this module
+-- must be destroyed using 'contextPreallocatedDestroy' (in this
+-- section) instead of 'contextDestroy'
+--
+-- It is guaranteed that functions in this module will not call malloc or its
+-- friends realloc, calloc, and free.
+
+
+-- | A simple secp256k1 context object with no precomputed tables. These are useful for
+--  type serialization/parsing functions which require a context object to maintain
+--  API consistency, but currently do not require expensive precomputations or dynamic
+--  allocations.
+foreign import ccall safe "secp256k1.h secp256k1_context_no_precomp"
+    contextNoPrecomp :: Ctx
+
+
+-- | Copy a secp256k1 context object into caller-provided memory.
+--
+--  The caller must provide a pointer to a rewritable contiguous block of memory
+--  of size at least 'contextPreallocatedSize' (flags) bytes, suitably
+--  aligned to hold an object of any type.
+--
+--  The block of memory is exclusively owned by the created context object during
+--  the lifetime of this context object, see the description of
+--  'contextPreallocatedCreate' for details.
+foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_clone"
+    contextPreallocatedClone ::
+        -- | __Mutated:__ an existing context to copy (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ a pointer to a rewritable contiguous block of memory of size at least
+        -- 'contextPreallocatedSize' (flags) bytes, as detailed above (cannot be NULL)
+        Ptr (Bytes n) ->
+        -- | __Returns:__ a newly created context object.
+        IO Ctx
+
+
+-- | Determine the memory size of a secp256k1 context object to be copied into
+--  caller-provided memory.
+foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_clone_size"
+    contextPreallocatedCloneSize ::
+        -- | __Input:__ an existing context to copy (cannot be NULL)
+        Ctx ->
+        -- | __Returns:__ the required size of the caller-provided memory block.
+        IO CSize
+
+
+-- | Create a secp256k1 context object in caller-provided memory.
+--
+--  The caller must provide a pointer to a rewritable contiguous block of memory
+--  of size at least 'contextPreallocatedSize' (flags) bytes, suitably
+--  aligned to hold an object of any type.
+--
+--  The block of memory is exclusively owned by the created context object during
+--  the lifetime of this context object, which begins with the call to this
+--  function and ends when a call to 'contextPreallocatedDestroy'
+--  (which destroys the context object again) returns. During the lifetime of the
+--  context object, the caller is obligated not to access this block of memory,
+--  i.e., the caller may not read or write the memory, e.g., by copying the memory
+--  contents to a different location or trying to create a second context object
+--  in the memory. In simpler words, the prealloc pointer (or any pointer derived
+--  from it) should not be used during the lifetime of the context object.
+--
+--  See also 'contextRandomize'
+--  and 'contextPreallocatedDestroy'.
+foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_create"
+    contextPreallocatedCreate ::
+        -- | __Mutated:__ a pointer to a rewritable contiguous block of memory of
+        -- size at least 'contextPreallocatedSize' (flags)
+        -- bytes, as detailed above (cannot be NULL)
+        Ptr (Bytes n) ->
+        -- | __Input:__ which parts of the context to initialize.
+        CUInt ->
+        -- | __Returns:__ a newly created context object.
+        IO Ctx
+
+
+-- | Destroy a secp256k1 context object that has been created in
+--  caller-provided memory.
+--
+--  The context pointer may not be used afterwards.
+--
+--  The context to destroy must have been created using
+--  'contextPreallocatedCreate' or 'contextPreallocatedClone'.
+--  If the context has instead been created using 'contextCreate' or
+--  'contextClone', the behaviour is undefined. In that case,
+--  'contextDestroy' must be used instead.
+--
+--  If required, it is the responsibility of the caller to deallocate the block
+--  of memory properly after this function returns, e.g., by calling free on the
+--  preallocated pointer given to 'contextPreallocatedCreate' or
+--  'contextPreallocatedClone'.
+foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_destroy"
+    contextPreallocatedDestroy ::
+        -- | an existing context to destroy, constructed using 'contextPreallocatedCreate' or
+        -- 'contextPreallocatedClone' (cannot be NULL)
+        Ctx ->
+        IO ()
+
+
+-- | Determine the memory size of a secp256k1 context object to be created in
+--  caller-provided memory.
+--
+--  The purpose of this function is to determine how much memory must be provided
+--  to 'contextPreallocatedCreate'.
+foreign import ccall safe "secp256k1.h secp256k1_context_preallocated_size"
+    contextPreallocatedSize ::
+        -- | __Input:__ which parts of the context to initialize.
+        CUInt ->
+        -- | __Returns:__ the required size of the caller-provided memory block
+        IO CSize
+
+
+-- ** Callbacks
+
+
+-- | Set a callback function to be called when an internal consistency check
+--  fails. The default is crashing.
+--
+--  This can only trigger in case of a hardware failure, miscompilation,
+--  memory corruption, serious bug in the library, or other error would can
+--  otherwise result in undefined behaviour. It will not trigger due to mere
+--  incorrect usage of the API (see 'contextSetIllegalCallback'
+--  for that). After this callback returns, anything may happen, including
+--  crashing.
+--
+--  See also 'contextSetIllegalCallback'.
+foreign import ccall safe "secp256k1.h secp256k1_context_set_error_callback"
+    contextSetErrorCallback ::
+        -- | an existing context object (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ a pointer to a function to call when an internal error occurs,
+        -- taking a message and an opaque pointer (NULL restores the
+        -- default handler, see contextSetIllegalCallback
+        -- for details).
+        FunPtr (CString -> Ptr a -> IO ()) ->
+        -- | __Input:__ the opaque pointer to pass to fun above.
+        Ptr a ->
+        IO ()
+
+
+-- | Set a callback function to be called when an illegal argument is passed to
+--  an API call. It will only trigger for violations that are mentioned
+--  explicitly in the header.
+--
+--  The philosophy is that these shouldn't be dealt with through a
+--  specific return value, as calling code should not have branches to deal with
+--  the case that this code itself is broken.
+--
+--  On the other hand, during debug stage, one would want to be informed about
+--  such mistakes, and the default (crashing) may be inadvisable.
+--  When this callback is triggered, the API function called is guaranteed not
+--  to cause a crash, though its return value and output arguments are
+--  undefined.
+--
+--  When this function has not been called (or called with fn==NULL), then the
+--  default handler will be used. The library provides a default handler which
+--  writes the message to stderr and calls abort. This default handler can be
+--  replaced at link time if the preprocessor macro
+--  USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
+--  has been configured with @--enable-external-default-callbacks@. Then the
+--  following two symbols must be provided to link against:
+--   - void secp256k1_default_illegal_callback_fn(const char* message, void* data);
+--   - void secp256k1_default_error_callback_fn(const char* message, void* data);
+--  The library can call these default handlers even before a proper callback data
+--  pointer could have been set using 'contextSetIllegalCallback' or
+--  'contextSetErrorCallback', e.g., when the creation of a context
+--  fails. In this case, the corresponding default handler will be called with
+--  the data pointer argument set to NULL.
+--
+--  See also 'contextSetErrorCallback'.
+foreign import ccall safe "secp256k1.h secp256k1_context_set_illegal_callback"
+    contextSetIllegalCallback ::
+        -- | an existing context object (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ a pointer to a function to call when an illegal argument is passed to the API, taking a message
+        -- and an opaque pointer.  (NULL restores the default handler.)
+        FunPtr (CString -> Ptr a -> IO ()) ->
+        -- | __Input:__ the opaque pointer to pass to fun above.
+        Ptr a ->
+        IO ()
+
+
+-- * ECDH Operations
+
+
+-- | Compute an EC Diffie-Hellman secret in constant time
+foreign import ccall safe "secp256k1.h secp256k1_ecdh"
+    ecdh ::
+        -- | pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to an array to be filled by hashfp
+        Ptr (Bytes n) ->
+        -- | __Input:__ a pointer to a 'Pubkey64' containing an initialized public key
+        Ptr Pubkey64 ->
+        -- | __Input:__ a 32-byte scalar with which to multiply the point
+        Ptr Seckey32 ->
+        -- | __Input:__ pointer to a hash function. If NULL, 'ecdhHashFunctionSha256' is used
+        -- (in which case, 32 bytes will be written to output)
+        FunPtr (EcdhHashFun a) ->
+        -- | __Input:__ arbitrary data pointer that is passed through to hashfp
+        Ptr a ->
+        -- | __Returns:__ 1 if exponentiation was successful, 0 if scalar was invalid (zero or overflow)
+        -- or hashfp returned 0
+        IO Ret
+
+
+-- | A default ECDH hash function (currently equal to 'ecdhHashFunctionSha256').
+-- Populates the output parameter with 32 bytes.
+foreign import ccall safe "secp256k1.h &secp256k1_ecdh_hash_function_default"
+    ecdhHashFunctionDefault :: FunPtr (EcdhHashFun a)
+
+
+-- | An implementation of SHA256 hash function that applies to compressed public key.
+-- Populates the output parameter with 32 bytes.
+foreign import ccall safe "secp256k1.h &secp256k1_ecdh_hash_sha256"
+    ecdhHashSha256 :: FunPtr (EcdhHashFun a)
+
+
+-- * ECDSA
+
+
+-- | A default safe nonce generation function (currently equal to 'nonceFunctionRfc6979').
+foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_default"
+    nonceFunctionDefault :: FunPtr (NonceFun a)
+
+
+-- | An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
+-- If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
+-- extra entropy.
+foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_rfc6979"
+    nonceFunctionRfc6979 :: FunPtr (NonceFun a)
+
+
+-- ** Recoverable
+
+
+-- | Recover an ECDSA public key from a signature.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recover"
+    ecdsaRecover ::
+        -- | pointer to a context object, initialized for verification (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to the recovered public key (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to initialized signature that supports pubkey recovery (cannot be NULL)
+        Ptr RecSig65 ->
+        -- | __Input:__ the 32-byte message hash assumed to be signed (cannot be NULL)
+        Ptr Msg32 ->
+        -- | __Returns:__ 1: public key successfully recovered (which guarantees a correct signature).
+        -- 0: otherwise.
+        IO Ret
+
+
+-- | Convert a recoverable signature into a normal signature.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_convert"
+    ecdsaRecoverableSignatureConvert ::
+        -- | a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ pointer to a normal signature (cannot be NULL).
+        Ptr Sig64 ->
+        -- | __Input:__ a pointer to a recoverable signature (cannot be NULL).
+        Ptr RecSig65 ->
+        -- | __Returns:__ 1
+        IO Ret
+
+
+-- | Parse a compact ECDSA signature (64 bytes + recovery id).
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_parse_compact"
+    ecdsaRecoverableSignatureParseCompact ::
+        -- | a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to a signature object
+        Ptr RecSig65 ->
+        -- | __Input:__ a pointer to a 64-byte compact signature
+        Ptr (Bytes 64) ->
+        -- | __Input:__ the recovery id (0, 1, 2 or 3)
+        CInt ->
+        -- | __Returns:__ 1 when the signature could be parsed, 0 otherwise
+        IO Ret
+
+
+-- | Serialize an ECDSA signature in compact format (64 bytes + recovery id).
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_recoverable_signature_serialize_compact"
+    ecdsaRecoverableSignatureSerializeCompact ::
+        --  Args: ctx:      a secp256k1 context object
+        Ctx ->
+        --  Out:  output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
+        Ptr (Bytes 64) ->
+        --        recid:    a pointer to an integer to hold the recovery id (can be NULL).
+        Ptr CInt ->
+        --  In:   sig:      a pointer to an initialized signature object (cannot be NULL)
+        Ptr RecSig65 ->
+        --  Returns: 1
+        IO Ret
+
+
+-- | Create a recoverable ECDSA signature.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_sign_recoverable"
+    ecdsaSignRecoverable ::
+        --  Args:    ctx:       pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        --  Out:     sig:       pointer to an array where the signature will be placed (cannot be NULL)
+        Ptr RecSig65 ->
+        --  In:      msghash32: the 32-byte message hash being signed (cannot be NULL)
+        Ptr Msg32 ->
+        --           seckey:    pointer to a 32-byte secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        --           noncefp:   pointer to a nonce generation function. If NULL, 'nonceFunctionDefault' is used
+        FunPtr (NonceFun a) ->
+        --           ndata:     pointer to arbitrary data used by the nonce generation function (can be NULL)
+        Ptr a ->
+        --  Returns: 1: signature created
+        --           0: the nonce generation function failed, or the secret key was invalid.
+        IO Ret
+
+
+-- ** Non-Recoverable
+
+
+-- | Create an ECDSA signature.
+--
+-- The created signature is always in lower-S form. See
+-- 'ecdsaSignatureNormalize' for more details.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_sign"
+    ecdsaSign ::
+        -- | pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to an array where the signature will be placed (cannot be NULL)
+        Ptr Sig64 ->
+        -- | __Input:__ the 32-byte message hash being signed (cannot be NULL)
+        Ptr Msg32 ->
+        -- | __Input:__ pointer to a 32-byte secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Input:__ pointer to a nonce generation function. If NULL, 'nonceFunctionDefault' is used
+        FunPtr (NonceFun a) ->
+        -- | __Input:__ pointer to arbitrary data used by the nonce generation function (can be NULL)
+        Ptr a ->
+        -- | __Returns:__ 1: signature created
+        -- 0: the nonce generation function failed, or the secret key was invalid.
+        IO Ret
+
+
+-- | Verify an ECDSA signature.
+--
+-- To avoid accepting malleable signatures, only ECDSA signatures in lower-S
+-- form are accepted.
+--
+-- If you need to accept ECDSA signatures from sources that do not obey this
+-- rule, apply 'ecdsaSignatureNormalize' to the signature prior to
+-- validation, but be aware that doing so results in malleable signatures.
+--
+-- For details, see the comments for that function.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_verify"
+    ecdsaVerify ::
+        -- | a secp256k1 context object, initialized for verification.
+        Ctx ->
+        -- | __Input:__ the signature being verified (cannot be NULL)
+        Ptr Sig64 ->
+        -- | __Input:__ the 32-byte message hash being verified (cannot be NULL).
+        -- The verifier must make sure to apply a cryptographic
+        -- hash function to the message by itself and not accept an
+        -- msghash32 value directly. Otherwise, it would be easy to
+        -- create a "valid" signature without knowledge of the
+        -- secret key. See also
+        -- https://bitcoin.stackexchange.com/a/81116/35586 for more
+        -- background on this topic.
+        Ptr Msg32 ->
+        -- | __Input:__ pointer to an initialized public key to verify with (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Returns:__ 1 if correct signature, 0 if incorrect or unparseable signature
+        IO Ret
+
+
+-- | Convert a signature to a normalized lower-S form.
+--
+--  With ECDSA a third-party can forge a second distinct signature of the same
+--  message, given a single initial signature, but without knowing the key. This
+--  is done by negating the S value modulo the order of the curve, "flipping"
+--  the sign of the random point R which is not included in the signature.
+--
+--  Forgery of the same message isn't universally problematic, but in systems
+--  where message malleability or uniqueness of signatures is important this can
+--  cause issues. This forgery can be blocked by all verifiers forcing signers
+--  to use a normalized form.
+--
+--  The lower-S form reduces the size of signatures slightly on average when
+--  variable length encodings (such as DER) are used and is cheap to verify,
+--  making it a good choice. Security of always using lower-S is assured because
+--  anyone can trivially modify a signature after the fact to enforce this
+--  property anyway.
+--
+--  The lower S value is always between 0x1 and
+--  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
+--  inclusive.
+--
+--  No other forms of ECDSA malleability are known and none seem likely, but
+--  there is no formal proof that ECDSA, even with this additional restriction,
+--  is free of other malleability. Commonly used serialization schemes will also
+--  accept various non-unique encodings, so care should be taken when this
+--  property is required for an application.
+--
+--  The 'ecdsaSign' function will by default create signatures in the
+--  lower-S form, and 'ecdsaVerify' will not accept others. In case
+--  signatures come from a system that cannot enforce this property,
+--  'ecdsaSignatureNormalize' must be called before verification.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_normalize"
+    ecdsaSignatureNormalize ::
+        -- | a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to a signature to fill with the normalized form,
+        -- or copy if the input was already normalized. (can be NULL if
+        -- you're only interested in whether the input was already
+        -- normalized).
+        Ptr Sig64 ->
+        -- | __Input:__ a pointer to a signature to check/normalize (cannot be NULL,
+        -- can be identical to sigout)
+        Ptr Sig64 ->
+        -- | __Returns:__ 1 if sigin was not normalized, 0 if it already was.
+        IO Ret
+
+
+-- *** Parsing / Serialization
+
+
+-- | Parse an ECDSA signature in compact (64 bytes) format.
+--
+--  The signature must consist of a 32-byte big endian R value, followed by a
+--  32-byte big endian S value. If R or S fall outside of [0..order-1], the
+--  encoding is invalid. R and S with value 0 are allowed in the encoding.
+--
+--  After the call, sig will always be initialized. If parsing failed or R or
+--  S are zero, the resulting sig value is guaranteed to fail validation for any
+--  message and public key.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_parse_compact"
+    ecdsaSignatureParseCompact ::
+        -- | __Input:__ a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to a signature object
+        Ptr Sig64 ->
+        -- | __Input:__ a pointer to the 64-byte array to parse
+        Ptr Compact64 ->
+        -- | __Returns:__ 1 when the signature could be parsed, 0 otherwise.
+        IO Ret
+
+
+-- | Parse a DER ECDSA signature.
+--
+--  This function will accept any valid DER encoded signature, even if the
+--  encoded numbers are out of range.
+--
+--  After the call, sig will always be initialized. If parsing failed or the
+--  encoded numbers are out of range, signature validation with it is
+--  guaranteed to fail for every message and public key.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_parse_der"
+    ecdsaSignatureParseDer ::
+        -- | __Input:__ a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to a signature object
+        Ptr Sig64 ->
+        -- | __Input:__ a pointer to the signature to be parsed
+        Ptr (Bytes n) ->
+        -- | __Input:__ the length of the array pointed to be input
+        CSize ->
+        -- | __Returns:__ 1 when the signature could be parsed, 0 otherwise.
+        IO Ret
+
+
+-- | Serialize an ECDSA signature in compact (64 byte) format.
+--
+--  See 'ecdsaSignatureParseCompact' for details about the encoding.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_serialize_compact"
+    ecdsaSignatureSerializeCompact ::
+        -- | __Input:__ a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to a 64-byte array to store the compact serialization
+        Ptr Compact64 ->
+        -- | __Input:__ a pointer to an initialized signature object
+        Ptr Sig64 ->
+        -- | __Returns:__ 1
+        IO Ret
+
+
+-- | Serialize an ECDSA signature in DER format.
+foreign import ccall safe "secp256k1.h secp256k1_ecdsa_signature_serialize_der"
+    ecdsaSignatureSerializeDer ::
+        -- | __Input:__ a secp256k1 context object
+        Ctx ->
+        -- | __Output:__ a pointer to an array to store the DER serialization
+        Ptr (Bytes n) ->
+        -- | __Mutates:__ a pointer to a length integer. Initially, this integer
+        -- should be set to the length of output. After the call
+        -- it will be set to the length of the serialization (even
+        -- if 0 was returned).
+        Ptr CSize ->
+        -- | __Input:__ a pointer to an initialized signature object
+        Ptr Sig64 ->
+        -- | __Returns:__ 1 if enough space was available to serialize, 0 otherwise
+        IO Ret
+
+
+-- * Pubkey Operations
+
+
+-- | Compare two public keys using lexicographic (of compressed serialization) order
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_cmp"
+    ecPubkeyCmp ::
+        -- | __Input:__ a secp256k1 context object.
+        Ctx ->
+        -- | __Input:__ first public key to compare
+        Ptr Pubkey64 ->
+        -- | __Input:__ second public key to compare
+        Ptr Pubkey64 ->
+        -- __Returns:__ <0 if the first public key is less than the second
+        -- >0 if the first public key is greater than the second
+        -- 0 if the two public keys are equal
+        IO Ret
+
+
+-- | Add a number of public keys together.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_combine"
+    ecPubkeyCombine ::
+        -- | pointer to a context object
+        Ctx ->
+        -- | __Output:__ pointer to a public key object for placing the resulting public key (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to array of pointers to public keys (cannot be NULL)
+        Ptr (Ptr Pubkey64) ->
+        -- | __Input:__ the number of public keys to add together (must be at least 1)
+        CInt ->
+        -- | __Returns:__ 1: the sum of the public keys is valid.
+        -- 0: the sum of the public keys is not valid.
+        IO Ret
+
+
+-- | Compute the public key for a secret key.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_create"
+    ecPubkeyCreate ::
+        -- | pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to the created public key (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to a 32-byte secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Returns:__ 1: secret was valid, public key stores
+        -- 0: secret was invalid, try again
+        IO Ret
+
+
+-- | Negates a public key in place.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_negate"
+    ecPubkeyNegate ::
+        -- | pointer to a context object
+        Ctx ->
+        -- | __Mutates:__ pointer to the public key to be negated (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Returns:__ 1 always
+        IO Ret
+
+
+-- | Parse a variable-length public key into the pubkey object.
+--
+--  This function supports parsing compressed (33 bytes, header byte 0x02 or
+--  0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header
+--  byte 0x06 or 0x07) format public keys.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_parse"
+    ecPubkeyParse ::
+        -- | a secp256k1 context object.
+        Ctx ->
+        -- | __Output:__ pointer to a pubkey object. If 1 is returned, it is set to a
+        -- parsed version of input. If not, its value is undefined.
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to a serialized public key
+        Ptr (Bytes n) ->
+        -- | __Input:__ length of the array pointed to by input
+        CSize ->
+        -- | __Returns:__ 1 if the public key was fully valid.
+        -- 0 if the public key could not be parsed or is invalid.
+        IO Ret
+
+
+-- | Serialize a pubkey object into a serialized byte sequence.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_serialize"
+    ecPubkeySerialize ::
+        -- | a secp256k1 context object.
+        Ctx ->
+        -- | __Output:__ a pointer to a 65-byte (if compressed==0) or 33-byte (if
+        -- compressed==1) byte array to place the serialized key in.
+        Ptr (Bytes n) ->
+        -- | __Mutates:__ a pointer to an integer which is initially set to the
+        -- size of output, and is overwritten with the written size.
+        Ptr CSize ->
+        -- | __Input:__ a pointer to a 'Pubkey64' containing an
+        -- initialized public key.
+        Ptr Pubkey64 ->
+        -- | __Input:__ 'compressed' if serialization should be in
+        -- compressed format, otherwise 'uncompressed'.
+        SerFlags ->
+        --  Returns: 1 always.
+        IO Ret
+
+
+-- | Tweak a public key by adding tweak times the generator to it.
+foreign import ccall unsafe "secp256k1.h secp256k1_ec_pubkey_tweak_add"
+    ecPubkeyTweakAdd ::
+        -- | pointer to a context object initialized for validation (cannot be NULL).
+        Ctx ->
+        -- | __Mutates:__ pointer to a public key object. pubkey will be set to an
+        -- invalid value if this function returns 0 (cannot be NULL).
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to a 32-byte tweak. If the tweak is invalid according to
+        -- 'ecSeckeyVerify', this function returns 0. For
+        -- uniformly random 32-byte arrays the chance of being invalid
+        -- is negligible (around 1 in 2^128) (cannot be NULL).
+        Ptr Tweak32 ->
+        -- | __Returns:__ 0 if the arguments are invalid or the resulting public key would be
+        -- invalid (only when the tweak is the negation of the corresponding
+        -- secret key). 1 otherwise.
+        IO Ret
+
+
+-- | Tweak a public key by multiplying it by a tweak value.
+foreign import ccall safe "secp256k1.h secp256k1_ec_pubkey_tweak_mul"
+    ecPubkeyTweakMul ::
+        -- | pointer to a context object initialized for validation (cannot be NULL).
+        Ctx ->
+        -- | __Mutates:__ pointer to a public key object. pubkey will be set to an
+        -- invalid value if this function returns 0 (cannot be NULL).
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to a 32-byte tweak. If the tweak is invalid according to
+        -- 'ecSeckeyVerify', this function returns 0. For
+        -- uniformly random 32-byte arrays the chance of being invalid
+        -- is negligible (around 1 in 2^128) (cannot be NULL).
+        Ptr Tweak32 ->
+        -- | __Returns:__ 0 if the arguments are invalid. 1 otherwise.
+        IO Ret
+
+
+-- | Negates a secret key in place.
+foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_negate"
+    ecSeckeyNegate ::
+        -- | pointer to a context object
+        Ctx ->
+        -- | __Mutates:__ pointer to the 32-byte secret key to be negated. If the
+        -- secret key is invalid according to
+        -- ecSeckeyVerify, this function returns 0 and
+        -- seckey will be set to some unspecified value. (cannot be
+        -- NULL)
+        Ptr Seckey32 ->
+        -- | __Returns:__ 0 if the given secret key is invalid according to
+        -- 'ecSeckeyVerify'. 1 otherwise
+        IO Ret
+
+
+-- | Tweak a secret key by adding tweak to it.
+foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_tweak_add"
+    ecSeckeyTweakAdd ::
+        -- | pointer to a context object (cannot be NULL).
+        Ctx ->
+        -- | __Mutates:__ pointer to a 32-byte secret key. If the secret key is
+        -- invalid according to 'ecSeckeyVerify', this
+        -- function returns 0. seckey will be set to some unspecified
+        -- value if this function returns 0. (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Input:__ pointer to a 32-byte tweak. If the tweak is invalid according to
+        -- ecSeckeyVerify, this function returns 0. For
+        -- uniformly random 32-byte arrays the chance of being invalid
+        -- is negligible (around 1 in 2^128) (cannot be NULL).
+        Ptr Tweak32 ->
+        -- | __Returns:__ 0 if the arguments are invalid or the resulting secret key would be
+        -- invalid (only when the tweak is the negation of the secret key). 1
+        -- otherwise.
+        IO Ret
+
+
+-- | Tweak a secret key by multiplying it by a tweak.
+foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_tweak_mul"
+    ecSeckeyTweakMul ::
+        -- | pointer to a context object (cannot be NULL).
+        Ctx ->
+        -- __Mutates:__ pointer to a 32-byte secret key. If the secret key is
+        -- invalid according to 'ecSeckeyVerify', this
+        -- function returns 0. seckey will be set to some unspecified
+        -- value if this function returns 0. (cannot be NULL)
+        Ptr Seckey32 ->
+        -- __Input:__ pointer to a 32-byte tweak. If the tweak is invalid according to
+        -- 'ecSeckeyVerify', this function returns 0. For
+        -- uniformly random 32-byte arrays the chance of being invalid
+        -- is negligible (around 1 in 2^128) (cannot be NULL).
+        Ptr Tweak32 ->
+        -- __Returns:__ 0 if the arguments are invalid. 1 otherwise.
+        IO Ret
+
+
+-- | Verify an ECDSA secret key.
+--
+--  A secret key is valid if it is not 0 and less than the secp256k1 curve order
+--  when interpreted as an integer (most significant byte first). The
+--  probability of choosing a 32-byte string uniformly at random which is an
+--  invalid secret key is negligible.
+foreign import ccall safe "secp256k1.h secp256k1_ec_seckey_verify"
+    ecSecKeyVerify ::
+        -- | pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ pointer to a 32-byte secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Returns:__ 1 if secret key is valid, 0 if secret key is invalid
+        IO Ret
+
+
+-- | Compute the keypair for a secret key.
+foreign import ccall safe "secp256k1.h secp256k1_keypair_create"
+    keypairCreate ::
+        -- | pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to the created keypair (cannot be NULL)
+        Ptr Keypair96 ->
+        -- | __Input:__ pointer to a 32-byte secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Returns:__ 1: secret was valid, keypair is ready to use
+        -- 0: secret was invalid, try again with a different secret
+        IO Ret
+
+
+-- | Get the public key from a keypair.
+foreign import ccall safe "secp256k1.h secp256k1_keypair_pub"
+    keypairPub ::
+        -- | pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to a pubkey object. If 1 is returned, it is set to
+        -- the keypair public key. If not, it's set to an invalid value.
+        -- (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Input:__ pointer to a keypair (cannot be NULL)
+        Ptr Keypair96 ->
+        -- | __Returns:__ 0 if the arguments are invalid. 1 otherwise.
+        IO Ret
+
+
+-- | Get the secret key from a keypair.
+foreign import ccall safe "secp256k1.h secp256k1_keypair_sec"
+    keypairSec ::
+        -- | pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to a 32-byte buffer for the secret key (cannot be NULL)
+        Ptr Seckey32 ->
+        -- | __Input:__ pointer to a keypair (cannot be NULL)
+        Ptr Keypair96 ->
+        -- | __Returns:__ 0 if the arguments are invalid. 1 otherwise.
+        IO Ret
+
+
+-- | Get the x-only public key from a keypair.
+--
+--  This is the same as calling 'keypairPub' and then
+--  'xonlyPubkeyFromPubkey'.
+--
+--  Returns: 0 if the arguments are invalid. 1 otherwise.
+--  Args:   ctx: pointer to a context object (cannot be NULL)
+--  Out: pubkey: pointer to an xonly_pubkey object. If 1 is returned, it is set
+--               to the keypair public key after converting it to an
+--               xonly_pubkey. If not, it's set to an invalid value (cannot be
+--               NULL).
+--    pk_parity: pointer to an integer that will be set to the pk_parity
+--               argument of 'xonlyPubkeyFromPubkey' (can be NULL).
+--  In: keypair: pointer to a keypair (cannot be NULL)
+foreign import ccall safe "secp256k1.h secp256k1_keypair_xonly_pub"
+    keypairXonlyPub ::
+        Ctx ->
+        Ptr XonlyPubkey64 ->
+        Ptr CInt ->
+        Ptr Keypair96 ->
+        IO Ret
+
+
+-- | Tweak a keypair by adding tweak32 to the secret key and updating the public
+--  key accordingly.
+--
+--  Calling this function and then 'keypairPub' results in the same
+--  public key as calling 'keypairXonlyPub' and then
+--  'xonlyPubkeyTweakAdd'.
+--
+--  Returns: 0 if the arguments are invalid or the resulting keypair would be
+--           invalid (only when the tweak is the negation of the keypair's
+--           secret key). 1 otherwise.
+--
+--  Args:       ctx: pointer to a context object initialized for verification
+--                   (cannot be NULL)
+--  In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to
+--                   an invalid value if this function returns 0 (cannot be
+--                   NULL).
+--  In:     tweak32: pointer to a 32-byte tweak. If the tweak is invalid according
+--                   to 'ecSeckeyVerify', this function returns 0. For
+--                   uniformly random 32-byte arrays the chance of being invalid
+--                   is negligible (around 1 in 2^128) (cannot be NULL).
+foreign import ccall safe "secp256k1.h secp256k1_keypair_xonly_tweak_add"
+    keypairXonlyTweakAdd ::
+        Ctx ->
+        Ptr Keypair96 ->
+        Ptr Tweak32 ->
+        IO Ret
+
+
+-- * Schnorr Operations
+
+
+-- | An implementation of the nonce generation function as defined in Bitcoin
+--  Improvement Proposal 340 "Schnorr Signatures for secp256k1"
+--  (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
+--
+--  If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
+--  auxiliary random data as defined in BIP-340. If the data pointer is NULL,
+--  the nonce derivation procedure follows BIP-340 by setting the auxiliary
+--  random data to zero. The algo argument must be non-NULL, otherwise the
+--  function will fail and return 0. The hash will be tagged with algo.
+--  Therefore, to create BIP-340 compliant signatures, algo must be set to
+--  "BIP0340/nonce" and algolen to 13.
+foreign import ccall safe "secp256k1.h &secp256k1_nonce_function_bip340"
+    nonceFunctionBip340 :: FunPtr (NonceFunHardened a)
+
+
+-- | Create a Schnorr signature.
+--
+--  Does _not_ strictly follow BIP-340 because it does not verify the resulting
+--  signature. Instead, you can manually use 'schnorrsigVerify' and
+--  abort if it fails.
+--
+--  This function only signs 32-byte messages. If you have messages of a
+--  different size (or the same size but without a context-specific tag
+--  prefix), it is recommended to create a 32-byte message hash with
+--  'taggedSha256' and then sign the hash. Tagged hashing allows
+--  providing an context-specific tag for domain separation. This prevents
+--  signatures from being valid in multiple contexts by accident.
+foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_sign"
+    schnorrsigSign ::
+        -- | pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to a 64-byte array to store the serialized signature (cannot be NULL)
+        Ptr Sig64 ->
+        -- | __Input:__ the 32-byte message being signed (cannot be NULL)
+        Ptr Msg32 ->
+        -- | __Input:__ pointer to an initialized keypair (cannot be NULL)
+        Ptr Keypair96 ->
+        -- | __Input:__ 32 bytes of fresh randomness. While recommended to provide
+        -- this, it is only supplemental to security and can be NULL. See
+        -- BIP-340 "Default Signing" for a full explanation of this
+        -- argument and for guidance if randomness is expensive.
+        Ptr (Bytes 32) ->
+        -- | __Returns:__ 1 on success, 0 on failure.
+        IO Ret
+
+
+-- | Create a Schnorr signature with a more flexible API.
+--
+--  Same arguments as 'schnorrsigSign' except that it allows signing
+--  variable length messages and accepts a pointer to an extraparams object that
+--  allows customizing signing by passing additional arguments.
+--
+--  Creates the same signatures as schnorrsig_sign if msglen is 32 and the
+--  extraparams.ndata is the same as aux_rand32.
+foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_sign_custom"
+    schnorrsigSignCustom ::
+        -- | pointer to a context object, initialized for signing (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to a 64-byte array to store the serialized signature (cannot be NULL)
+        Ptr Sig64 ->
+        -- | __Input:__ the message being signed. Can only be NULL if msglen is 0.
+        Ptr (Bytes n) ->
+        -- | __Input:__ length of the message
+        CSize ->
+        -- | __Input:__ 32 bytes of fresh randomness. While recommended to provide
+        -- this, it is only supplemental to security and can be NULL. See
+        -- BIP-340 "Default Signing" for a full explanation of this
+        -- argument and for guidance if randomness is expensive.
+        Ptr Keypair96 ->
+        -- | __Input:__ pointer to a extraparams object (can be NULL)
+        Ptr SchnorrExtra ->
+        -- | __Returns:__ 1 on success, 0 on failure.
+        IO Ret
+
+
+-- | Verify a Schnorr signature.
+foreign import ccall safe "secp256k1.h secp256k1_schnorrsig_verify"
+    schnorrSigSignVerify ::
+        -- | a secp256k1 context object, initialized for verification.
+        Ctx ->
+        -- | __Input:__ pointer to the 64-byte signature to verify (cannot be NULL)
+        Ptr Sig64 ->
+        -- | __Input:__ the message being verified. Can only be NULL if msglen is 0.
+        Ptr (Bytes n) ->
+        -- | __Input:__ length of the message
+        CSize ->
+        -- | __Input:__ pointer to an x-only public key to verify with (cannot be NULL)
+        Ptr XonlyPubkey64 ->
+        -- | __Returns:__ 1 on correct signature, 0 on incorrect signature
+        IO Ret
+
+
+-- | Compute a tagged hash as defined in BIP-340.
+--
+--  This is useful for creating a message hash and achieving domain separation
+--  through an application-specific tag. This function returns
+--  SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash
+--  implementations optimized for a specific tag can precompute the SHA256 state
+--  after hashing the tag hashes.
+foreign import ccall safe "secp256k1.h secp256k1_tagged_sha256"
+    taggedSha256 ::
+        -- | pointer to a context object
+        Ctx ->
+        -- | __Output:__ pointer to a 32-byte array to store the resulting hash
+        Ptr (Bytes 32) ->
+        -- | __Input:__ pointer to an array containing the tag
+        Ptr (Bytes n) ->
+        -- | __Input:__ length of the tag array
+        CSize ->
+        -- | __Input:__ pointer to an array containing the message
+        Ptr (Bytes n) ->
+        -- | __Input:__ length of the message array
+        CSize ->
+        -- | __Returns:__ 0 if the arguments are invalid and 1 otherwise.
+        IO Ret
+
+
+-- * XOnly Operations
+
+
+-- | Compare two x-only public keys using lexicographic order
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_cmp"
+    xonlyPubkeyCmp ::
+        -- | a secp256k1 context object.
+        Ctx ->
+        -- | __Input:__ first public key to compare
+        Ptr XonlyPubkey64 ->
+        -- | __Input:__ second public key to compare
+        Ptr XonlyPubkey64 ->
+        -- | __Returns:__ <0 if the first public key is less than the second
+        -- >0 if the first public key is greater than the second
+        -- 0 if the two public keys are equal
+        IO Ret
+
+
+-- | Converts a 'Pubkey64' into a 'XonlyPubkey64'.
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_from_pubkey"
+    xonlyPubkeyFromPubkey ::
+        -- | pointer to a context object (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to an x-only public key object for placing the
+        -- converted public key (cannot be NULL)
+        Ptr XonlyPubkey64 ->
+        -- __Mutates:__ pointer to an integer that will be set to 1 if the point
+        -- encoded by xonly_pubkey is the negation of the pubkey and
+        -- set to 0 otherwise. (can be NULL)
+        Ptr CInt ->
+        -- | __Input:__ pubkey: pointer to a public key that is converted (cannot be NULL)
+        Ptr Pubkey64 ->
+        -- | __Returns:__ 1 if the public key was successfully converted
+        -- 0 otherwise
+        IO Ret
+
+
+-- | Parse a 32-byte sequence into a 'XonlyPubkey64' object.
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_parse"
+    xonlyPubkeyParse ::
+        -- | a secp256k1 context object (cannot be NULL).
+        Ctx ->
+        -- | __Output:__ pointer to a pubkey object. If 1 is returned, it is set to a
+        -- parsed version of input. If not, it's set to an invalid value.
+        -- (cannot be NULL).
+        Ptr XonlyPubkey64 ->
+        -- | __Input:__ pointer to a serialized xonly_pubkey (cannot be NULL)
+        Ptr (Bytes 32) ->
+        -- | __Returns:__ 1 if the public key was fully valid.
+        -- 0 if the public key could not be parsed or is invalid.
+        IO Ret
+
+
+-- | Serialize an 'XonlyPubkey64' object into a 32-byte sequence.
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_serialize"
+    xonlyPubkeySerialize ::
+        -- | a secp256k1 context object (cannot be NULL).
+        Ctx ->
+        -- | __Output:__ a pointer to a 32-byte array to place the serialized key in
+        -- (cannot be NULL).
+        Ptr (Bytes 32) ->
+        -- | __Input:__ a pointer to a 'XonlyPubkey64' containing an
+        -- initialized public key (cannot be NULL).
+        Ptr XonlyPubkey64 ->
+        -- | __Returns:__ 1 always.
+        IO Ret
+
+
+-- | Tweak an x-only public key by adding the generator multiplied with tweak32
+--  to it.
+--
+--  Note that the resulting point can not in general be represented by an x-only
+--  pubkey because it may have an odd Y coordinate. Instead, the output_pubkey
+--  is a normal 'Pubkey64'.
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_tweak_add"
+    xonlyPubkeyTweakAdd ::
+        -- | pointer to a context object initialized for verification
+        -- (cannot be NULL)
+        Ctx ->
+        -- | __Output:__ pointer to a public key to store the result. Will be set
+        -- to an invalid value if this function returns 0 (cannot
+        -- be NULL)
+        Ptr Pubkey64 ->
+        -- | __Input:__ internal_pubkey: pointer to an x-only pubkey to apply the tweak to.
+        -- (cannot be NULL).
+        Ptr XonlyPubkey64 ->
+        -- | __Input:__ pointer to a 32-byte tweak. If the tweak is invalid
+        -- according to 'ecSeckeyVerify', this function
+        -- returns 0. For uniformly random 32-byte arrays the
+        -- chance of being invalid is negligible (around 1 in
+        -- 2^128) (cannot be NULL).
+        Ptr Tweak32 ->
+        -- | __Returns:__ 0 if the arguments are invalid or the resulting public key would be
+        -- invalid (only when the tweak is the negation of the corresponding
+        -- secret key). 1 otherwise.
+        IO Ret
+
+
+-- | Checks that a tweaked pubkey is the result of calling
+-- 'xonlyPubkeyTweakAdd' with internal_pubkey and tweak32.
+--
+--  The tweaked pubkey is represented by its 32-byte x-only serialization and
+--  its pk_parity, which can both be obtained by converting the result of
+--  tweak_add to a 'XonlyPubkey64'.
+--
+--  Note that this alone does _not_ verify that the tweaked pubkey is a
+--  commitment. If the tweak is not chosen in a specific way, the tweaked pubkey
+--  can easily be the result of a different internal_pubkey and tweak.
+foreign import ccall safe "secp256k1.h secp256k1_xonly_pubkey_tweak_add_check"
+    xonlyPubkeyTweakAddCheck ::
+        -- | pointer to a context object initialized for verification
+        -- (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ pointer to a serialized xonly_pubkey (cannot be NULL)
+        Ptr (Bytes 32) ->
+        -- | __Input:__ the parity of the tweaked pubkey (whose serialization
+        -- is passed in as tweaked_pubkey32). This must match the
+        -- pk_parity value that is returned when calling
+        -- 'XonlyPubkey64' with the tweaked pubkey, or
+        -- this function will fail.
+        CInt ->
+        -- | __Input__ pointer to an x-only public key object to apply the
+        -- tweak to (cannot be NULL)
+        Ptr XonlyPubkey64 ->
+        -- | __Input:__ pointer to a 32-byte tweak (cannot be NULL)
+        Ptr Tweak32 ->
+        -- | __Returns:__ 0 if the arguments are invalid or the tweaked pubkey is not the
+        -- result of tweaking the internal_pubkey with tweak32. 1 otherwise.
+        IO Ret
+
+
+-- * Scratch Space
+
+
+-- | Create a secp256k1 scratch space object.
+foreign import ccall safe "secp256k1.h secp256k1_scratch_space_create"
+    scratchSpaceCreate ::
+        -- | an existing context object (cannot be NULL)
+        Ctx ->
+        -- | __Input:__ amount of memory to be available as scratch space. Some extra
+        -- (<100 bytes) will be allocated for extra accounting.
+        CSize ->
+        -- | __Returns:__ a newly created scratch space.
+        IO (Ptr Scratch)
+
+
+-- | Destroy a secp256k1 scratch space.
+--
+--  The pointer may not be used afterwards.
+foreign import ccall safe "secp256k1.h secp256k1_scratch_space_destroy"
+    scratchSpaceDestroy ::
+        -- | a secp256k1 context object.
+        Ctx ->
+        -- | __Input:__ space to destroy
+        Ptr Scratch ->
+        IO ()
+
+
+-- * Deprecated
+{-# DEPRECATED ecPrivkeyNegate "use ecSeckeyNegate instead" #-}
+foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_negate"
+    ecPrivkeyNegate ::
+        Ctx ->
+        Ptr Tweak32 ->
+        IO Ret
+
+
+{-# DEPRECATED ecPrivkeyTweakAdd "use ecSeckeyTweakAdd instead" #-}
+foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_tweak_add"
+    ecPrivkeyTweakAdd ::
+        Ctx ->
+        Ptr Seckey32 ->
+        Ptr Tweak32 ->
+        IO Ret
+
+
+{-# DEPRECATED ecPrivkeyTweakMul "use ecSeckeyTweakMul instead" #-}
+foreign import ccall safe "secp256k1.h secp256k1_ec_privkey_tweak_mul"
+    ecPrivkeyTweakMul ::
+        Ctx ->
+        Ptr Seckey32 ->
+        Ptr Tweak32 ->
+        IO Ret
+
+
+-- * Pointer Types
+data LCtx
+data Pubkey64
+data XonlyPubkey64
+data Keypair96
+data Msg32
+data RecSig65
+data Sig64
+data Compact64
+data Seed32
+data Seckey32
+data Tweak32
+data SchnorrExtra
+data Scratch
+data Bytes (n :: Nat)
+
+
+-- * Function Pointer Types
+
+
+-- | A pointer to a function to deterministically generate a nonce.
+-- Except for test cases, this function should compute some cryptographic hash of
+-- the message, the algorithm, the key and the attempt.
+type NonceFun a =
+    -- | __Output:__ pointer to a 32-byte array to be filled by the function.
+    Ptr CUChar ->
+    -- | __Input:__ the 32-byte message hash being verified (will not be NULL)
+    Ptr CUChar ->
+    -- | __Input:__ pointer to a 32-byte secret key (will not be NULL)
+    Ptr CUChar ->
+    -- | __Input:__ pointer to a 16-byte array describing the signature
+    -- algorithm (will be NULL for ECDSA for compatibility).
+    Ptr CUChar ->
+    -- | __Input:__ Arbitrary data pointer that is passed through.
+    Ptr a ->
+    -- | __Input:__ how many iterations we have tried to find a nonce.
+    -- This will almost always be 0, but different attempt values
+    -- are required to result in a different nonce.
+    CInt ->
+    -- | __Returns:__ 1 if a nonce was successfully generated. 0 will cause signing to fail.
+    IO CInt
+
+
+-- | A pointer to a function to deterministically generate a nonce.
+--
+--  Same as 'NonceFun' with the exception of accepting an
+--  additional pubkey argument and not requiring an attempt argument. The pubkey
+--  argument can protect signature schemes with key-prefixed challenge hash
+--  inputs against reusing the nonce when signing with the wrong precomputed
+--  pubkey.
+--
+--
+--  Except for test cases, this function should compute some cryptographic hash of
+--  the message, the key, the pubkey, the algorithm description, and data.
+type NonceFunHardened a =
+    -- | __Output:__ pointer to a 32-byte array to be filled by the function
+    Ptr CUChar ->
+    -- | __Input:__ the message being verified. Is NULL if and only if msglen is 0.
+    Ptr CUChar ->
+    -- | __Input:__ the length of the message
+    CSize ->
+    -- | __Input:__ pointer to a 32-byte secret key (will not be NULL)
+    Ptr CUChar ->
+    -- | __Input:__ the 32-byte serialized xonly pubkey corresponding to key32 (will not be NULL)
+    Ptr CUChar ->
+    -- | __Input:__ pointer to an array describing the signature algorithm (will not be NULL)
+    Ptr CUChar ->
+    -- | __Input:__ the length of the algo array
+    CSize ->
+    -- | __Input:__ arbitrary data pointer that is passed through
+    Ptr a ->
+    -- | __Returns:__ 1 if a nonce was successfully generated. 0 will cause signing to return an error.
+    IO CInt
+
+
+-- | A pointer to a function that hashes an EC point to obtain an ECDH secret
+type EcdhHashFun a =
+    -- | __Output:__ pointer to an array to be filled by the function
+    Ptr CUChar ->
+    -- | __Input:__ pointer to a 32-byte x coordinate
+    Ptr CUChar ->
+    -- | __Input:__ pointer to a 32-byte y coordinate
+    Ptr CUChar ->
+    -- | __Input:__ arbitrary data pointer that is passed through
+    Ptr a ->
+    -- | __Returns:__ 1 if the point was successfully hashed.
+    -- 0 will cause 'ecdh' to fail and return 0.
+    -- Other return values are not allowed, and the behaviour of
+    -- 'ecdh' is undefined for other return values.
+    IO CInt
