csecp256k1

secp256k1 bindings.
Log | Files | Refs | README | LICENSE

commit d8f52a71f12f7e9c641d20d223c49901065531ad
parent aa6b4415aadbbec9304528849695c4000c897267
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 24 Feb 2024 16:37:01 +0400

Add basic ECDH functionality.

I encountered a bunch of problems getting this to work, and I'm still
not sure what resolved them exactly.

I find Cabal's docs to be confusing as to where to place the
-DENABLE_MODULE_ECDH option (it seems to state that it should be under
'cc-options'), but GHC suggests placing it under 'cpp-options', where I
had originally put it.

I originally encountered dyld errors around lazy symbol loading when
trying to call secp256k1's ECDH function in a REPL; the solution may
have been to simply build the package with cabal prior to using the
REPL, as swapping the flags and includes around didn't seem to solve
anything.

Diffstat:
Msecp256k1-sys/lib/Crypto/Secp256k1/Internal.hs | 24+++++++++++-------------
Msecp256k1-sys/secp256k1-sys.cabal | 11++++++-----
Msecp256k1-sys/test/Main.hs | 22++++++++++------------
3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/secp256k1-sys/lib/Crypto/Secp256k1/Internal.hs b/secp256k1-sys/lib/Crypto/Secp256k1/Internal.hs @@ -25,7 +25,7 @@ module Crypto.Secp256k1.Internal ( , secp256k1_ecdsa_signature_serialize_der -- ecdh - -- , secp256k1_ecdh + , secp256k1_ecdh ) where import Foreign.Ptr (Ptr) @@ -155,18 +155,16 @@ foreign import capi -- ecdh --- XX seems fine, but GHC bails on call --- --- foreign import capi --- "secp256k1_ecdh.h haskellsecp256k1_v0_1_0_ecdh" --- secp256k1_ecdh --- :: Ptr Context --- -> Ptr CUChar --- -> Ptr PubKey64 --- -> Ptr SecKey32 --- -> Ptr a --- -> Ptr b --- -> IO CInt +foreign import capi + "secp256k1_ecdh.h haskellsecp256k1_v0_1_0_ecdh" + secp256k1_ecdh + :: Ptr Context + -> Ptr CUChar + -> Ptr PubKey64 + -> Ptr SecKey32 + -> Ptr a + -> Ptr b + -> IO CInt -- schnorr diff --git a/secp256k1-sys/secp256k1-sys.cabal b/secp256k1-sys/secp256k1-sys.cabal @@ -24,10 +24,14 @@ library , bytestring ghc-options: - -optc -Wno-implicit-function-declaration + -optc -Wno-implicit-function-declaration include-dirs: - depend/secp256k1/include/ + depend/secp256k1/include/ + + includes: + secp256k1.h + , secp256k1_ecdh.h c-sources: depend/secp256k1/src/precomputed_ecmult_gen.c @@ -36,9 +40,6 @@ library cpp-options: -DENABLE_MODULE_ECDH - -DENABLE_MODULE_SCHNORRSIG - -DENABLE_MODULE_EXTRAKEYS - -DENABLE_MODULE_ELLSWIFT test-suite tests type: exitcode-stdio-1.0 diff --git a/secp256k1-sys/test/Main.hs b/secp256k1-sys/test/Main.hs @@ -268,18 +268,16 @@ verify_ecdsa tex key msg der = do secp256k1_ecdsa_verify tex sip has kep pure (suc == 1) --- XX resurrect when ecdh problems solved --- --- ecdh :: Ptr Context -> BS.ByteString -> BS.ByteString -> IO BS.ByteString --- ecdh tex pub sec = --- A.allocaBytes _SEC_BYTES $ \out -> do --- par <- parse_pubkey tex pub --- BS.useAsCString par $ \(F.castPtr -> pab) -> --- BS.useAsCString sec $ \(F.castPtr -> sep) -> do --- suc <- secp256k1_ecdh tex out pab sep F.nullPtr F.nullPtr --- when (suc /= 1) $ throwIO Secp256k1Error --- let key = F.castPtr out --- BS.packCStringLen (key, _SEC_BYTES) +ecdh :: Ptr Context -> BS.ByteString -> BS.ByteString -> IO BS.ByteString +ecdh tex pub sec = + A.allocaBytes _SEC_BYTES $ \out -> do + par <- parse_pubkey tex pub + BS.useAsCString par $ \(F.castPtr -> pab) -> + BS.useAsCString sec $ \(F.castPtr -> sep) -> do + suc <- secp256k1_ecdh tex out pab sep F.nullPtr F.nullPtr + when (suc /= 1) $ throwIO Secp256k1Error + let key = F.castPtr out + BS.packCStringLen (key, _SEC_BYTES) -- test inputs