{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}

-- |
-- Module      : Crypto.Secp256k1.Prim
-- License     : UNLICENSE
-- Maintainer  : Keagan McClelland <keagan.mcclelland@gmail.com>
-- Stability   : experimental
-- Portability : POSIX
--
-- The API for this module may change at any time. This is an internal module only
-- exposed for hacking and experimentation.
module Crypto.Secp256k1.Prim where

import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BU
import Foreign (FunPtr, Ptr, castPtr)
import Foreign.C (
    CInt (..),
    CSize (..),
    CString,
    CUChar,
    CUInt (..),
 )
import GHC.TypeNats (Nat)
import System.IO.Unsafe (unsafePerformIO)


type Ctx = Ptr LCtx
type CtxFlags = CUInt
type SerFlags = CUInt
type Ret = CInt


verify :: CtxFlags
verify :: SerFlags
verify = SerFlags
0x0101


sign :: CtxFlags
sign :: SerFlags
sign = SerFlags
0x0201


signVerify :: CtxFlags
signVerify :: SerFlags
signVerify = SerFlags
0x0301


compressed :: SerFlags
compressed :: SerFlags
compressed = SerFlags
0x0102


uncompressed :: SerFlags
uncompressed :: SerFlags
uncompressed = SerFlags
0x0002


isSuccess :: Ret -> Bool
isSuccess :: Ret -> Bool
isSuccess Ret
0 = Bool
False
isSuccess Ret
1 = Bool
True
isSuccess Ret
n = [Char] -> Bool
forall a. HasCallStack => [Char] -> a
error ([Char] -> Bool) -> [Char] -> Bool
forall a b. (a -> b) -> a -> b
$ [Char]
"isSuccess expected 0 or 1 but got " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Ret -> [Char]
forall a. Show a => a -> [Char]
show Ret
n


unsafeUseByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString :: forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (Ptr a, CSize) -> IO b
f =
    ByteString -> (CStringLen -> IO b) -> IO b
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BU.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO b) -> IO b) -> (CStringLen -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
b, Int
l) ->
        (Ptr a, CSize) -> IO b
f (Ptr CChar -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
b, Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l)


useByteString :: ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
useByteString :: forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
useByteString ByteString
bs (Ptr a, CSize) -> IO b
f =
    ByteString -> (CStringLen -> IO b) -> IO b
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.useAsCStringLen ByteString
bs ((CStringLen -> IO b) -> IO b) -> (CStringLen -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
b, Int
l) ->
        (Ptr a, CSize) -> IO b
f (Ptr CChar -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
b, Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l)


unsafePackByteString :: (Ptr a, CSize) -> IO ByteString
unsafePackByteString :: forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr a
b, CSize
l) =
    CStringLen -> IO ByteString
BU.unsafePackMallocCStringLen (Ptr a -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr Ptr a
b, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
l)


packByteString :: (Ptr a, CSize) -> IO ByteString
packByteString :: forall a. (Ptr a, CSize) -> IO ByteString
packByteString (Ptr a
b, CSize
l) =
    CStringLen -> IO ByteString
BS.packCStringLen (Ptr a -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr Ptr a
b, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
l)


ctx :: Ctx
ctx :: Ctx
ctx = IO Ctx -> Ctx
forall a. IO a -> a
unsafePerformIO (IO Ctx -> Ctx) -> IO Ctx -> Ctx
forall a b. (a -> b) -> a -> b
$ SerFlags -> IO Ctx
contextCreate SerFlags
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