commit 62f5420de4650f8aa5152dc795a06f7a0399dd04
parent 39c2e3b013d706c2b9cbeea9e94a9b3ecb67121c
Author: Jared Tobin <jared@jtobin.io>
Date: Mon, 12 Feb 2024 15:28:53 +0400
More initial bindings work.
Diffstat:
2 files changed, 540 insertions(+), 2 deletions(-)
diff --git a/secp256k1-sys/lib/Crypto/Secp256k1/Internal.hs b/secp256k1-sys/lib/Crypto/Secp256k1/Internal.hs
@@ -1,3 +1,540 @@
+{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE RankNTypes #-}
+
module Crypto.Secp256k1.Internal where
+import qualified Data.ByteString as BS
+import Foreign.Ptr (Ptr)
+-- import Foreign.ForeignPtr (ForeignPtr)
+import Foreign.C.Types (CUChar(..), CInt(..), CUInt(..), CSize(..))
+
+-- A nonce generation function.
+--
+-- Per rust-secp256k1:
+--
+-- Nonces are generated deterministically by RFC6979 by
+-- default; there should be no need to ever change this.
+newtype NonceFn a = NonceFn (
+ Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr a
+ -> CUInt
+ -> IO CInt
+ )
+
+-- Hash function to use to post-process an ECDH point to get
+-- a shared secret.
+newtype EcdhHashFn a = EcdhHashFn (
+ Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr a
+ -> IO CInt
+ )
+
+-- Same as secp256k1_nonce function 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.
+newtype SchnorrNonceFn a = SchnorrNonceFn (
+ Ptr CUChar
+ -> Ptr CUChar
+ -> CSize
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> CSize
+ -> Ptr a
+ -> IO CInt
+ )
+
+
+-- A hash function used by `ellswift_ecdh` to hash the final ECDH shared
+-- secret.
+newtype EllswiftEcdhHashFn a = EllswiftEcdhHashFn (
+ Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr a
+ -> IO CInt
+ )
+
+newtype EllswiftXdhHashFn a = EllswiftXdhHashFn (
+ Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr a
+ -> IO CInt
+ )
+
+-- Data structure that contains additional arguments for
+-- schnorrsig_sign_custom.
+data SchnorrSigExtraParams a =
+ SchnorrSigExtraParams
+ !BS.ByteString -- magic
+ (SchnorrNonceFn a) -- nonce_fp
+ (forall b. Ptr b) -- ndata
+
+-- Create a new SchnorrSigExtraParams properly initialized.
+--
+-- `nonce_fp`: pointer to a nonce generation function. If NULL
+-- haskellsecp256k1_v0_5_0_nonce_function_bip340 is used
+--
+-- `ndata`: pointer to arbitrary data used by the nonce
+-- generation function (can be NULL). If it is non-NULL and
+-- haskellsecp256k1_v0_5_0_nonce_function_bip340 is used, then ndata
+-- must be a pointer to 32-byte auxiliary randomness as per BIP-340.
+new_SchnorrSigExtraParams
+ :: SchnorrNonceFn a
+ -> (forall b. Ptr b)
+ -> SchnorrSigExtraParams a
+new_SchnorrSigExtraParams nonce_fp ndata =
+ let magic = BS.pack [0xda, 0x6f, 0xb3, 0x8c]
+ in SchnorrSigExtraParams magic nonce_fp ndata
+
+-- A Secp256k1 context, containing various precomputed values and
+-- such needed to do elliptic curve computations.
+newtype Context = Context CInt
+
+-- Library-internal representation of a Secp256k1 public key
+newtype PublicKey = PublicKey BS.ByteString
+
+-- Library-internal representation of a Secp256k1 secret key (32-byte)
+newtype SecretKey = SecretKey BS.ByteString
+
+-- Library-internal representation of a Secp256k1 signature
+newtype Signature = Signature BS.ByteString
+
+newtype XOnlyPublicKey = XOnlyPublicKey BS.ByteString
+
+newtype KeyPair = KeyPair BS.ByteString
+
+-- Library-internal representation of a ElligatorSwift encoded group element.
+newtype ElligatorSwift = ElligatorSwift BS.ByteString
+
+
+-- Default ECDH hash function
+foreign import capi
+ "secp256k1_ecdh.h haskellsecp256k1_v0_1_0_ecdh_hash_function_default"
+ secp256k1_ecdh_hash_function_default :: EcdhHashFn a
+
+-- Default ECDH hash function for BIP324 key establishment
+foreign import capi
+ "secp256k1_ellswift.h haskellsecp256k1_v0_1_0_ellswift_xdh_hash_function_bip324"
+ secp256k1_ellswift_xdh_hash_function_bip324 :: EllswiftEcdhHashFn a
+
+-- XX won't compile (seem not to be included in header)
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_nonce_function_rfc6979"
+-- secp256k1_v0_1_0_nonce_function_rfc6979 :: NonceFn a
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_nonce_function_default"
+-- secp256k1_v0_1_0_nonce_function_default :: NonceFn a
+
+foreign import capi
+ "secp256k1_schnorrsig.h haskellsecp256k1_v0_1_0_nonce_function_bip340"
+ secp256k1_v0_1_0_nonce_function_bip340 :: SchnorrNonceFn a
+
+-- XX suspected won't compile
+--
+-- #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_9_2_context_no_precomp")]
+-- pub static secp256k1_context_no_precomp: *const Context;
+--
+-- // Contexts
+-- #[cfg_attr(not(rust_secp_no_symbol_renaming), link_name = "rustsecp256k1_v0_9_2_context_preallocated_destroy")]
+-- pub fn secp256k1_context_preallocated_destroy(cx: NonNull<Context>);
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der"
+ secp256k1_v0_1_0_ecdsa_signature_parse_der
+ :: Ptr Context
+ -> Ptr Signature
+ -> Ptr CUChar
+ -> CSize
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_parse_compact"
+ secp256k1_v0_1_0_ecdsa_signature_parse_compact
+ :: Ptr Context
+ -> Ptr Signature
+ -> Ptr CUChar
+ -> IO CInt
+
+-- XX doesn't compile (will these work with ccall?)
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der_lax"
+-- secp256k1_v0_1_0_ecdsa_signature_parse_der_lax
+-- :: Ptr Context
+-- -> Ptr Signature
+-- -> Ptr CUChar
+-- -> CSize
+-- -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_serialize_der"
+ secp256k1_v0_1_0_ecdsa_signature_serialize_der
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CSize
+ -> Ptr Signature
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_serialize_compact"
+ secp256k1_v0_1_0_ecdsa_signature_serialize_compact
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr Signature
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_signature_normalize"
+ secp256k1_v0_1_0_ecdsa_signature_normalize
+ :: Ptr Context
+ -> Ptr Signature
+ -> Ptr Signature
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_seckey_verify"
+ secp256k1_v0_1_0_ec_seckey_verify
+ :: Ptr Context
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_seckey_negate"
+ secp256k1_v0_1_0_ec_seckey_negate
+ :: Ptr Context
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_seckey_tweak_add"
+ secp256k1_v0_1_0_ec_seckey_tweak_add
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_seckey_tweak_mul"
+ secp256k1_v0_1_0_ec_seckey_tweak_mul
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_keypair_sec"
+ secp256k1_v0_1_0_keypair_sec
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr KeyPair
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_keypair_pub"
+ secp256k1_v0_1_0_keypair_pub
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr KeyPair
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_ellswift.h haskellsecp256k1_v0_1_0_ellswift_encode"
+ secp256k1_v0_1_0_ellswift_encode
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_ellswift.h haskellsecp256k1_v0_1_0_ellswift_decode"
+ secp256k1_v0_1_0_ellswift_decode
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_ellswift.h haskellsecp256k1_v0_1_0_ellswift_create"
+ secp256k1_v0_1_0_ellswift_create
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr SecretKey
+ -> Ptr CUChar
+ -> IO CInt
+
+-- XX check pointer to hash function
+--
+foreign import capi
+ "secp256k1_ellswift.h haskellsecp256k1_v0_1_0_ellswift_xdh"
+ secp256k1_v0_1_0_ellswift_xdh
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> CInt
+ -> Ptr (EllswiftXdhHashFn a) -- <- problem
+ -> Ptr b
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_preallocated.h haskellsecp256k1_v0_1_0_context_preallocated_size"
+ secp256k1_v0_1_0_context_preallocated_size
+ :: CUInt
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_preallocated.h haskellsecp256k1_v0_1_0_context_preallocated_create"
+ secp256k1_v0_1_0_context_preallocated_create
+ :: Ptr CUChar -- XX maybe be precise that this is *void; non null
+ -> CUInt
+ -> IO (Ptr Context) -- non null
+
+foreign import capi
+ "secp256k1_preallocated.h haskellsecp256k1_v0_1_0_context_preallocated_clone_size"
+ secp256k1_v0_1_0_context_preallocated_clone_size
+ :: Ptr Context
+ -> IO CSize -- pure?
+
+foreign import capi
+ "secp256k1_preallocated.h haskellsecp256k1_v0_1_0_context_preallocated_clone"
+ secp256k1_v0_1_0_context_preallocated_clone
+ :: Ptr Context
+ -> Ptr a -- non null
+ -> IO (Ptr Context)
+
+foreign import capi
+ "secp256k1_preallocated.h haskellsecp256k1_v0_1_0_context_randomize"
+ secp256k1_v0_1_0_context_randomize
+ :: Ptr Context -- non null
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_parse"
+ secp256k1_v0_1_0_ec_pubkey_parse
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> CSize
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_serialize"
+ secp256k1_v0_1_0_ec_pubkey_serialize
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CSize
+ -> Ptr PublicKey
+ -> CUInt
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_create"
+ secp256k1_v0_1_0_ec_pubkey_create
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_negate"
+ secp256k1_v0_1_0_ec_pubkey_negate
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_cmp"
+ secp256k1_v0_1_0_ec_pubkey_cmp
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr PublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_tweak_add"
+ secp256k1_v0_1_0_ec_pubkey_tweak_add
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_tweak_mul"
+ secp256k1_v0_1_0_ec_pubkey_tweak_mul
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+-- XX requires ccall?
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_ec_pubkey_combine"
+-- secp256k1_v0_1_0_ec_pubkey_combine
+-- :: Ptr Context
+-- -> Ptr PublicKey
+-- -> Ptr (Ptr PublicKey) -- array of pubkeys
+-- -> CSize
+-- -> IO CInt
+
+-- XX problem including hash function
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_ecdh"
+-- secp256k1_v0_1_0_ecdh
+-- :: Ptr Context
+-- -> Ptr CUChar
+-- -> Ptr PublicKey
+-- -> Ptr CUChar
+-- -> EcdhHashFn a
+-- -> Ptr b
+-- -> IO CInt
+
+foreign import capi
+ "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_verify"
+ secp256k1_v0_1_0_ecdsa_verify
+ :: Ptr Context
+ -> Ptr Signature
+ -> Ptr CUChar
+ -> Ptr PublicKey
+ -> IO CInt
+
+-- XX problem including nonce fn
+--
+-- foreign import capi
+-- "secp256k1.h haskellsecp256k1_v0_1_0_ecdsa_sign"
+-- secp256k1_v0_1_0_ecdsa_sign
+-- :: Ptr Context
+-- -> Ptr Signature
+-- -> Ptr CUChar
+-- -> Ptr CUChar
+-- -> NonceFn a
+-- -> Ptr b
+-- -> IO CInt
+
+-- XX s/sign/sign32 following compiler warning
+--
+foreign import capi
+ "secp256k1_schnorrsig.h haskellsecp256k1_v0_1_0_schnorrsig_sign32"
+ secp256k1_v0_1_0_schnorrsig_sign32
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> Ptr KeyPair
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_schnorrsig.h haskellsecp256k1_v0_1_0_schnorrsig_sign_custom"
+ secp256k1_v0_1_0_schnorrsig_sign_custom
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> CSize
+ -> Ptr KeyPair
+ -> Ptr (SchnorrSigExtraParams a)
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_schnorrsig.h haskellsecp256k1_v0_1_0_schnorrsig_verify"
+ secp256k1_v0_1_0_schnorrsig_verify
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr CUChar
+ -> CSize
+ -> Ptr XOnlyPublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_keypair_create"
+ secp256k1_v0_1_0_keypair_create
+ :: Ptr Context
+ -> Ptr KeyPair
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_parse"
+ secp256k1_v0_1_0_xonly_pubkey_parse
+ :: Ptr Context
+ -> Ptr XOnlyPublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_serialize"
+ secp256k1_v0_1_0_xonly_pubkey_serialize
+ :: Ptr Context
+ -> Ptr CUChar
+ -> Ptr XOnlyPublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey"
+ secp256k1_v0_1_0_xonly_pubkey_from_pubkey
+ :: Ptr Context
+ -> Ptr XOnlyPublicKey
+ -> Ptr CInt
+ -> Ptr PublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_cmp"
+ secp256k1_v0_1_0_xonly_pubkey_cmp
+ :: Ptr Context
+ -> Ptr XOnlyPublicKey
+ -> Ptr XOnlyPublicKey
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add"
+ secp256k1_v0_1_0_xonly_pubkey_tweak_add
+ :: Ptr Context
+ -> Ptr PublicKey
+ -> Ptr XOnlyPublicKey
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_keypair_xonly_pub"
+ secp256k1_v0_1_0_keypair_xonly_pub
+ :: Ptr Context
+ -> Ptr XOnlyPublicKey
+ -> Ptr CInt
+ -> Ptr KeyPair
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add"
+ secp256k1_v0_1_0_keypair_xonly_tweak_add
+ :: Ptr Context
+ -> Ptr KeyPair
+ -> Ptr CUChar
+ -> IO CInt
+
+foreign import capi
+ "secp256k1_extrakeys.h haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check"
+ secp256k1_v0_1_0_xonly_pubkey_tweak_add_check
+ :: Ptr Context
+ -> Ptr CUChar
+ -> CInt
+ -> Ptr XOnlyPublicKey
+ -> Ptr CUChar
+ -> IO CInt
diff --git a/secp256k1-sys/secp256k1-sys.cabal b/secp256k1-sys/secp256k1-sys.cabal
@@ -20,7 +20,8 @@ library
exposed-modules:
Crypto.Secp256k1.Internal
build-depends:
- base ^>= 4.18.2.0
+ base
+ , bytestring
include-dirs:
depend/secp256k1/
@@ -35,7 +36,7 @@ library
, depend/secp256k1/src/secp256k1.c
cc-options:
- -D "SECP256k1_API="
+ -D "SECP256K1_API="
-D "ENABLE_MODULE_ECDH=1"
-D "ENABLE_MODULE_SCHNORRSIG=1"
-D "ENABLE_MODULE_EXTRAKEYS=1"