diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,7 +1,7 @@
-import Distribution.PackageDescription
-import Distribution.Simple
-import Distribution.Simple.Setup
-import Distribution.Simple.Utils
+import           Distribution.PackageDescription
+import           Distribution.Simple
+import           Distribution.Simple.Setup
+import           Distribution.Simple.Utils
 
 main :: IO ()
 main = defaultMainWithHooks autoconfUserHooks
diff --git a/haskell/src/Crypto/Secp256k1.hs b/haskell/src/Crypto/Secp256k1.hs
--- a/haskell/src/Crypto/Secp256k1.hs
+++ b/haskell/src/Crypto/Secp256k1.hs
@@ -12,26 +12,50 @@
 Depends on <https://github.com/bitcoin/secp256k1 secp256k1>.
 -}
 module Crypto.Secp256k1
-( -- * Messages
-  Msg, msg, getMsg
-  -- * Secret Key
-, SecKey, importSecKey, exportSecKey, pubKey
-  -- ** Raw Secret Key
-, secKey, getSecKey
-  -- * Public Key
-, PubKey, importPubKey, exportPubKey
-  -- * Signature
-, Sig, CompactSig(..)
-, importSig, laxImportSig, exportSig
-, exportCompactSig, importCompactSig
-, signMsg, verifySig, normalizeSig
-  -- * Addition & Multiplication
-, Tweak, tweak, getTweak
-, tweakAddSecKey, tweakMulSecKey
-, tweakAddPubKey, tweakMulPubKey
-, combinePubKeys
-) where
+    ( -- * Messages
+    Msg
+    , msg
+    , getMsg
 
+    -- * Secret Keys
+    , SecKey
+    , secKey
+    , getSecKey
+    , derivePubKey
+    -- ** BER
+    , importSecKey
+    , exportSecKey
+
+    -- * Public Keys
+    , PubKey
+    , importPubKey
+    , exportPubKey
+
+    -- * Signatures
+    , Sig
+    , CompactSig(..)
+    , signMsg
+    , verifySig
+    , normalizeSig
+    -- ** DER
+    , importSig
+    , laxImportSig
+    , exportSig
+    -- ** Compact
+    , exportCompactSig
+    , importCompactSig
+
+    -- * Addition & Multiplication
+    , Tweak
+    , tweak
+    , getTweak
+    , tweakAddSecKey
+    , tweakMulSecKey
+    , tweakAddPubKey
+    , tweakMulPubKey
+    , combinePubKeys
+    ) where
+
 import           Control.Applicative
 import           Control.Monad
 import           Crypto.Secp256k1.Internal
@@ -177,10 +201,10 @@
         fp <- mallocForeignPtr
         ret <- withForeignPtr fp $ \p -> do
             poke p (SecKey32 bs)
-            ec_seckey_verify ctx p
+            ecSecKeyVerify ctx p
         if isSuccess ret
             then return $ Just $ SecKey fp
-            else return $ Nothing
+            else return Nothing
     | otherwise = Nothing
 
 -- | Convert signature to a normalized lower-S form. Boolean value 'True'
@@ -190,7 +214,7 @@
 normalizeSig (Sig fg) = unsafePerformIO $ do
     fg' <- mallocForeignPtr
     ret <- withForeignPtr fg $ \pg -> withForeignPtr fg' $ \pg' ->
-        ecdsa_signature_normalize ctx pg' pg
+        ecdsaSignatureNormalize ctx pg' pg
     return (Sig fg', isSuccess ret)
 
 -- | Create internal tweak data from 32-byte 'ByteString'.
@@ -212,26 +236,25 @@
 
 -- | Get 32-byte message.
 getMsg :: Msg -> ByteString
-getMsg (Msg fm) = getMsg32 $ unsafePerformIO $ withForeignPtr fm $ peek
+getMsg (Msg fm) = getMsg32 $ unsafePerformIO $ withForeignPtr fm peek
 
 -- | Get 32-byte tweak.
 getTweak :: Tweak -> ByteString
-getTweak (Tweak ft) = getTweak32 $ unsafePerformIO $ withForeignPtr ft $ peek
+getTweak (Tweak ft) = getTweak32 $ unsafePerformIO $ withForeignPtr ft peek
 
 -- | Read DER-encoded public key.
 importPubKey :: ByteString -> Maybe PubKey
-importPubKey bs = unsafePerformIO $ do
-    useByteString bs $ \(b, l) -> do
-        fp <- mallocForeignPtr
-        ret <- withForeignPtr fp $ \p -> ec_pubkey_parse ctx p b l
-        if isSuccess ret then return $ Just $ PubKey fp else return Nothing
+importPubKey bs = unsafePerformIO $ useByteString bs $ \(b, l) -> do
+    fp <- mallocForeignPtr
+    ret <- withForeignPtr fp $ \p -> ecPubKeyParse ctx p b l
+    if isSuccess ret then return $ Just $ PubKey fp else return Nothing
 
 -- | Encode public key as DER.  First argument 'True' for compressed output.
 exportPubKey :: Bool -> PubKey -> ByteString
 exportPubKey compress (PubKey pub) = unsafePerformIO $
     withForeignPtr pub $ \p -> alloca $ \l -> allocaBytes z $ \o -> do
         poke l (fromIntegral z)
-        ret <- ec_pubkey_serialize ctx o l p c
+        ret <- ecPubKeySerialize ctx o l p c
         unless (isSuccess ret) $ error "could not serialize public key"
         n <- peek l
         packByteString (o, n)
@@ -243,7 +266,7 @@
 exportCompactSig :: Sig -> CompactSig
 exportCompactSig (Sig fg) = unsafePerformIO $
     withForeignPtr fg $ \pg -> alloca $ \pc -> do
-        ret <- ecdsa_signature_serialize_compact ctx pc pg
+        ret <- ecdsaSignatureSerializeCompact ctx pc pg
         unless (isSuccess ret) $ error "Could not obtain compact signature"
         peek pc
 
@@ -252,7 +275,7 @@
 importCompactSig c = unsafePerformIO $ alloca $ \pc -> do
     poke pc c
     fg <- mallocForeignPtr
-    ret <- withForeignPtr fg $ \pg -> ecdsa_signature_parse_compact ctx pg pc
+    ret <- withForeignPtr fg $ \pg -> ecdsaSignatureParseCompact ctx pg pc
     if isSuccess ret then return $ Just $ Sig fg else return Nothing
 
 -- | Read DER-encoded signature.
@@ -260,7 +283,7 @@
 importSig bs = unsafePerformIO $
     useByteString bs $ \(b, l) -> do
         fg <- mallocForeignPtr
-        ret <- withForeignPtr fg $ \g -> ecdsa_signature_parse_der ctx g b l
+        ret <- withForeignPtr fg $ \g -> ecdsaSignatureParseDer ctx g b l
         if isSuccess ret then return $ Just $ Sig fg else return Nothing
 
 -- | Relaxed DER parsing. Allows certain DER errors and violations.
@@ -268,7 +291,7 @@
 laxImportSig bs = unsafePerformIO $
     useByteString bs $ \(b, l) -> do
         fg <- mallocForeignPtr
-        ret <- withForeignPtr fg $ \g -> lax_der_parse ctx g b l
+        ret <- withForeignPtr fg $ \g -> laxDerParse ctx g b l
         if isSuccess ret then return $ Just $ Sig fg else return Nothing
 
 -- | Encode signature as DER.
@@ -276,7 +299,7 @@
 exportSig (Sig fg) = unsafePerformIO $
     withForeignPtr fg $ \g -> alloca $ \l -> allocaBytes 72 $ \o -> do
         poke l 72
-        ret <- ecdsa_signature_serialize_der ctx o l g
+        ret <- ecdsaSignatureSerializeDer ctx o l g
         unless (isSuccess ret) $ error "could not serialize signature"
         n <- peek l
         packByteString (o, n)
@@ -285,32 +308,31 @@
 verifySig :: PubKey -> Sig -> Msg -> Bool
 verifySig (PubKey fp) (Sig fg) (Msg fm) = unsafePerformIO $
     withForeignPtr fp $ \p -> withForeignPtr fg $ \g ->
-        withForeignPtr fm $ \m -> isSuccess <$> ecdsa_verify ctx g m p
+        withForeignPtr fm $ \m -> isSuccess <$> ecdsaVerify ctx g m p
 
 -- | Sign message using secret key.
 signMsg :: SecKey -> Msg -> Sig
 signMsg (SecKey fk) (Msg fm) = unsafePerformIO $
     withForeignPtr fk $ \k -> withForeignPtr fm $ \m -> do
         fg <- mallocForeignPtr
-        ret <- withForeignPtr fg $ \g -> ecdsa_sign ctx g m k nullFunPtr nullPtr
+        ret <- withForeignPtr fg $ \g -> ecdsaSign ctx g m k nullFunPtr nullPtr
         unless (isSuccess ret) $ error "could not sign message"
         return $ Sig fg
 
 -- | Obtain public key from secret key.
-pubKey :: SecKey -> PubKey
-pubKey (SecKey fk) = unsafePerformIO $
-    withForeignPtr fk $ \k -> do
-        fp <- mallocForeignPtr
-        ret <- withForeignPtr fp $ \p -> ec_pubkey_create ctx p k
-        unless (isSuccess ret) $ error "could not compute public key"
-        return $ PubKey fp
+derivePubKey :: SecKey -> PubKey
+derivePubKey (SecKey fk) = unsafePerformIO $ withForeignPtr fk $ \k -> do
+    fp <- mallocForeignPtr
+    ret <- withForeignPtr fp $ \p -> ecPubKeyCreate ctx p k
+    unless (isSuccess ret) $ error "could not compute public key"
+    return $ PubKey fp
 
 -- | Read BER-encoded secret key.
 importSecKey :: ByteString -> Maybe SecKey
 importSecKey bs = unsafePerformIO $
     useByteString bs $ \(b, l) -> do
         fk <- mallocForeignPtr
-        ret <- withForeignPtr fk $ \k -> ec_privkey_import ctx k b l
+        ret <- withForeignPtr fk $ \k -> ecSecKeyImport ctx k b l
         if isSuccess ret then return $ Just $ SecKey fk else return Nothing
 
 -- | Encode secret key as BER.  First argument 'True' for compressed output.
@@ -318,7 +340,7 @@
 exportSecKey compress (SecKey fk) = unsafePerformIO $
     withForeignPtr fk $ \k -> alloca $ \l -> allocaBytes 279 $ \o -> do
         poke l 279
-        ret <- ec_privkey_export ctx o l k c
+        ret <- ecSecKeyExport ctx o l k c
         unless (isSuccess ret) $ error "could not export secret key"
         n <- peek l
         packByteString (o, n)
@@ -333,7 +355,7 @@
         ret <- withForeignPtr fk' $ \k' ->  do
             key <- peek k
             poke k' key
-            ec_privkey_tweak_add ctx k' t
+            ecSecKeyTweakAdd ctx k' t
         if isSuccess ret then return $ Just $ SecKey fk' else return Nothing
 
 -- | Multiply secret key by tweak using ECDSA multiplication.
@@ -344,7 +366,7 @@
         ret <- withForeignPtr fk' $ \k' ->  do
             key <- peek k
             poke k' key
-            ec_privkey_tweak_mul ctx k' t
+            ecSecKeyTweakMul ctx k' t
         if isSuccess ret then return $ Just $ SecKey fk' else return Nothing
 
 -- | Perform ECDSA addition between the public key point and the point obtained
@@ -356,7 +378,7 @@
         ret <- withForeignPtr fp' $ \p' ->  do
             pub <- peek p
             poke p' pub
-            ec_pubkey_tweak_add ctx p' t
+            ecPubKeyTweakAdd ctx p' t
         if isSuccess ret then return $ Just $ PubKey fp' else return Nothing
 
 -- | Perform ECDSA multiplication between the public key point and the point
@@ -368,7 +390,7 @@
         ret <- withForeignPtr fp' $ \p' ->  do
             pub <- peek p
             poke p' pub
-            ec_pubkey_tweak_mul ctx p' t
+            ecPubKeyTweakMul ctx p' t
         if isSuccess ret then return $ Just $ PubKey fp' else return Nothing
 
 -- | Add multiple public keys together using ECDSA addition.
@@ -378,7 +400,7 @@
         pokeArray a ps
         fp <- mallocForeignPtr
         ret <- withForeignPtr fp $ \p ->
-            ec_pubkey_combine ctx p a (fromIntegral $ length ps)
+            ecPubKeyCombine ctx p a (fromIntegral $ length ps)
         if isSuccess ret
             then return $ Just $ PubKey fp
             else return Nothing
@@ -391,18 +413,17 @@
     arbitrary = gen_msg
       where
         valid_bs = bs_gen `suchThat` isJust
-        bs_gen = (msg . BS.pack) <$> sequence (replicate 32 arbitrary)
+        bs_gen = (msg . BS.pack) <$> replicateM 32 arbitrary
         gen_msg = fromJust <$> valid_bs
 
 instance Arbitrary SecKey where
-    arbitrary = gen_key
-      where
+    arbitrary = gen_key where
         valid_bs = bs_gen `suchThat` isJust
-        bs_gen = (secKey . BS.pack) <$> sequence (replicate 32 arbitrary)
+        bs_gen = (secKey . BS.pack) <$> replicateM 32 arbitrary
         gen_key = fromJust <$> valid_bs
 
 instance Arbitrary PubKey where
     arbitrary = do
         key <- arbitrary
-        return $ pubKey key
+        return $ derivePubKey key
 
diff --git a/haskell/src/Crypto/Secp256k1/Internal.hs b/haskell/src/Crypto/Secp256k1/Internal.hs
--- a/haskell/src/Crypto/Secp256k1/Internal.hs
+++ b/haskell/src/Crypto/Secp256k1/Internal.hs
@@ -12,7 +12,7 @@
 module Crypto.Secp256k1.Internal where
 
 import           Control.Monad
-import           Data.Binary            (get, put)
+import           Data.Binary            (Binary, get, put)
 import           Data.Binary.Get        (runGet)
 import           Data.Binary.Put        (runPut)
 import           Data.ByteString        (ByteString, packCStringLen)
@@ -116,14 +116,15 @@
 instance Storable CompactSig where
     sizeOf _ = 64
     alignment _ = 1
-    peek p = do
-        bs <- unsafePackCStringLen (castPtr p, 64)
-        let LargeKey r s = runGet get (fromStrict bs)
+    peek p = (runGet get . fromStrict) <$> unsafePackCStringLen (castPtr p, 64)
+    poke p cs = useByteString bs $ \(b, _) -> copyArray (castPtr p) b 64 where
+        bs = toStrict $ runPut $ put cs
+
+instance Binary CompactSig where
+    get = do
+        LargeKey r s <- get
         return $ CompactSig r s
-    poke p (CompactSig r s) = useByteString bs $
-        \(b, _) -> copyArray (castPtr p) b 64
-      where
-        bs = toStrict $ runPut $ put (LargeKey r s)
+    put (CompactSig r s) = put (LargeKey r s)
 
 instance Storable Msg32 where
     sizeOf _ = 32
@@ -175,32 +176,32 @@
 {-# NOINLINE ctx #-}
 ctx :: Ptr Ctx
 ctx = unsafePerformIO $ do
-    x <- context_create signVerify
+    x <- contextCreate signVerify
     e <- getEntropy 32
-    ret <- alloca $ \s -> poke s (Seed32 e) >> context_randomize x s
+    ret <- alloca $ \s -> poke s (Seed32 e) >> contextRandomize x s
     unless (isSuccess ret) $ error "failed to randomize context"
     return x
 
 foreign import ccall
     "secp256k1.h secp256k1_context_create"
-    context_create
+    contextCreate
     :: CtxFlags
     -> IO (Ptr Ctx)
 
 foreign import ccall
     "secp256k1.h secp256k1_context_clone"
-    context_clone
+    contextClone
     :: Ptr Ctx
     -> IO (Ptr Ctx)
 
 foreign import ccall
     "secp256k1.h &secp256k1_context_destroy"
-    context_destroy
+    contextDestroy
     :: FunPtr (Ptr Ctx -> IO ())
 
 foreign import ccall
     "secp256k1.h secp256k1_context_set_illegal_callback"
-    set_illegal_callback
+    setIllegalCallback
     :: Ptr Ctx
     -> FunPtr (CString -> Ptr a -> IO ()) -- ^ message, data
     -> Ptr a                              -- ^ data
@@ -208,7 +209,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_context_set_error_callback"
-    set_error_callback
+    setErrorCallback
     :: Ptr Ctx
     -> FunPtr (CString -> Ptr a -> IO ()) -- ^ message, data
     -> Ptr a                              -- ^ data
@@ -216,7 +217,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_parse"
-    ec_pubkey_parse
+    ecPubKeyParse
     :: Ptr Ctx
     -> Ptr PubKey64
     -> Ptr CUChar -- ^ encoded public key array
@@ -225,7 +226,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_serialize"
-    ec_pubkey_serialize
+    ecPubKeySerialize
     :: Ptr Ctx
     -> Ptr CUChar -- ^ array for encoded public key, must be large enough
     -> Ptr CSize  -- ^ size of encoded public key, will be updated
@@ -235,7 +236,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_signature_parse_compact"
-    ecdsa_signature_parse_compact
+    ecdsaSignatureParseCompact
     :: Ptr Ctx
     -> Ptr Sig64
     -> Ptr CompactSig
@@ -244,7 +245,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_signature_parse_der"
-    ecdsa_signature_parse_der
+    ecdsaSignatureParseDer
     :: Ptr Ctx
     -> Ptr Sig64
     -> Ptr CUChar -- ^ encoded DER signature
@@ -253,7 +254,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_signature_serialize_der"
-    ecdsa_signature_serialize_der
+    ecdsaSignatureSerializeDer
     :: Ptr Ctx
     -> Ptr CUChar -- ^ array for encoded signature, must be large enough
     -> Ptr CSize  -- ^ size of encoded signature, will be updated
@@ -262,7 +263,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_signature_serialize_compact"
-    ecdsa_signature_serialize_compact
+    ecdsaSignatureSerializeCompact
     :: Ptr Ctx
     -> Ptr CompactSig
     -> Ptr Sig64
@@ -270,7 +271,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_verify"
-    ecdsa_verify
+    ecdsaVerify
     :: Ptr Ctx
     -> Ptr Sig64
     -> Ptr Msg32
@@ -279,7 +280,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_signature_normalize"
-    ecdsa_signature_normalize
+    ecdsaSignatureNormalize
     :: Ptr Ctx
     -> Ptr Sig64 -- | output
     -> Ptr Sig64 -- | input
@@ -287,28 +288,16 @@
 
 foreign import ccall
     "lax_der.h lax_der_parse"
-    lax_der_parse
+    laxDerParse
     :: Ptr Ctx
     -> Ptr Sig64
     -> Ptr CUChar
     -> CSize
     -> IO Ret
 
--- TODO:
--- foreign import ccall
---     "secp256k1.h &secp256k1_nonce_function_rfc6979"
---     nonce_function_rfc6979
---     :: FunPtr (NonceFunction Seed32)
---
--- TODO:
--- foreign import ccall
---     "secp256k1.h &secp256k1_nonce_function_default"
---     nonce_function_default
---     :: FunPtr (NonceFunction Seed32)
-
 foreign import ccall
     "secp256k1.h secp256k1_ecdsa_sign"
-    ecdsa_sign
+    ecdsaSign
     :: Ptr Ctx
     -> Ptr Sig64
     -> Ptr Msg32
@@ -319,14 +308,14 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_seckey_verify"
-    ec_seckey_verify
+    ecSecKeyVerify
     :: Ptr Ctx
     -> Ptr SecKey32
     -> IO Ret
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_create"
-    ec_pubkey_create
+    ecPubKeyCreate
     :: Ptr Ctx
     -> Ptr PubKey64
     -> Ptr SecKey32
@@ -334,7 +323,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_privkey_export"
-    ec_privkey_export
+    ecSecKeyExport
     :: Ptr Ctx
     -> Ptr CUChar -- ^ array to store BER-encoded key (allocate 279 bytes)
     -> Ptr CSize -- ^ size of previous array, will be updated
@@ -344,7 +333,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_privkey_import"
-    ec_privkey_import
+    ecSecKeyImport
     :: Ptr Ctx
     -> Ptr SecKey32
     -> Ptr CUChar -- ^ BER-encoded private key
@@ -353,7 +342,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_privkey_tweak_add"
-    ec_privkey_tweak_add
+    ecSecKeyTweakAdd
     :: Ptr Ctx
     -> Ptr SecKey32
     -> Ptr Tweak32
@@ -361,7 +350,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_tweak_add"
-    ec_pubkey_tweak_add
+    ecPubKeyTweakAdd
     :: Ptr Ctx
     -> Ptr PubKey64
     -> Ptr Tweak32
@@ -369,7 +358,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_privkey_tweak_mul"
-    ec_privkey_tweak_mul
+    ecSecKeyTweakMul
     :: Ptr Ctx
     -> Ptr SecKey32
     -> Ptr Tweak32
@@ -377,7 +366,7 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_tweak_mul"
-    ec_pubkey_tweak_mul
+    ecPubKeyTweakMul
     :: Ptr Ctx
     -> Ptr PubKey64
     -> Ptr Tweak32
@@ -385,14 +374,14 @@
 
 foreign import ccall
     "secp256k1.h secp256k1_context_randomize"
-    context_randomize
+    contextRandomize
     :: Ptr Ctx
     -> Ptr Seed32
     -> IO Ret
 
 foreign import ccall
     "secp256k1.h secp256k1_ec_pubkey_combine"
-    ec_pubkey_combine
+    ecPubKeyCombine
     :: Ptr Ctx
     -> Ptr PubKey64 -- ^ pointer to public key storage
     -> Ptr (Ptr PubKey64) -- ^ pointer to array of public keys
diff --git a/haskell/test/Crypto/Secp256k1/Internal/Tests.hs b/haskell/test/Crypto/Secp256k1/Internal/Tests.hs
--- a/haskell/test/Crypto/Secp256k1/Internal/Tests.hs
+++ b/haskell/test/Crypto/Secp256k1/Internal/Tests.hs
@@ -4,7 +4,7 @@
 import           Control.Monad
 import           Control.Monad.Trans
 import           Crypto.Secp256k1.Internal
-import           Data.ByteString                (packCStringLen,
+import           Data.ByteString                (ByteString, packCStringLen,
                                                  useAsCStringLen)
 import qualified Data.ByteString.Base16         as B16
 import           Foreign
@@ -17,91 +17,87 @@
 tests :: [Test]
 tests =
     [ testGroup "Housekeeping"
-        [ testCase "Create context"           create_context_test
-        , testCase "Randomize context"        randomize_context_test
-        , testCase "Clone context"            clone_context_test
-        -- TODO:
-        -- , testCase "Set illegal callback" set_illegal_callback_test
-        -- TODO:
-        -- , testCase "Set error callback" set_error_callback_test
+        [ testCase "Create context"           createContextTest
+        , testCase "Randomize context"        randomizeContextTest
+        , testCase "Clone context"            cloneContextTest
         ]
     , testGroup "Serialization"
-        [ testCase "Parse public key"         ec_pubkey_parse_test
-        , testCase "Serialize public key"     ec_pubkey_serialize_test
-        , testCase "Storable public key"      pubkey_storable_test
-        , testCase "Storable signature"       signature_storable_test
-        , testCase "Parse DER signature"      ecdsa_signature_parse_der_test
-        , testCase "Lax parse DER signature"  lax_der_parse_test
-        , testCase "Serialize DER signature"  ecdsa_signature_serialize_der_test
+        [ testCase "Parse public key"         ecPubkeyParseTest
+        , testCase "Serialize public key"     ecPubKeySerializeTest
+        , testCase "Storable public key"      pubkeyStorableTest
+        , testCase "Storable signature"       signatureStorableTest
+        , testCase "Parse DER signature"      ecdsaSignatureParseDerTest
+        , testCase "Lax parse DER signature"  laxDerParseTest
+        , testCase "Serialize DER signature"  ecdsaSignatureSerializeDerTest
         ]
     , testGroup "Signatures"
-        [ testCase "ECDSA verify"             ecdsa_verify_test
+        [ testCase "ECDSA verify"             ecdsaVerifyTest
         -- TODO:
         -- , testCase "RFC6979 nonce function"   nonce_function_rfc6979_test
-        , testCase "ECDSA sign"               ecdsa_sign_test
+        , testCase "ECDSA sign"               ecdsaSignTest
         ]
     , testGroup "Secret keys"
-        [ testCase "Verify secret key"        ec_seckey_verify_test
-        , testCase "Create public key"        ec_pubkey_create_test
-        , testCase "Serialize BER secret key" ec_privkey_export_test
-        , testCase "Import BER secret key"    ec_privkey_import_test
-        , testCase "Tweak add secret key"     ec_privkey_tweak_add_test
-        , testCase "Tweak mult. secret key"   ec_privkey_tweak_mul_test
+        [ testCase "Verify secret key"        ecSecKeyVerifyTest
+        , testCase "Create public key"        ecPubkeyCreateTest
+        , testCase "Serialize BER secret key" ecSecKeyExportTest
+        , testCase "Import BER secret key"    ecSecKeyImportTest
+        , testCase "Tweak add secret key"     ecSecKeyTweakAddTest
+        , testCase "Tweak mult. secret key"   ecSecKeyTweakMulTest
         ]
     , testGroup "Public keys"
-        [ testCase "Tweak add public key"     ec_pubkey_tweak_add_test
-        , testCase "Tweak mult. public key"   ec_pubkey_tweak_mul_test
-        , testCase "Combine public keys"      ec_pubkey_combine_test
+        [ testCase "Tweak add public key"     ecPubKeyTweakAddTest
+        , testCase "Tweak mult. public key"   ecPubKeyTweakMulTest
+        , testCase "Combine public keys"      ecPubKeyCombineTest
         ]
     ]
 
 withEntropy :: (Ptr Seed32 -> IO a) -> IO a
 withEntropy f = getEntropy 32 >>= \e -> alloca $ \s -> poke s (Seed32 e) >> f s
 
-create_context_test :: Assertion
-create_context_test = do
-    context_ptr <- liftIO $ context_create signVerify
+createContextTest :: Assertion
+createContextTest = do
+    context_ptr <- liftIO $ contextCreate signVerify
     assertBool "context not null" $ context_ptr /= nullPtr
 
-randomize_context_test :: Assertion
-randomize_context_test = do
-    ret <- liftIO $ context_create sign >>= \x ->
-        withEntropy (context_randomize x)
+randomizeContextTest :: Assertion
+randomizeContextTest = do
+    ret <- liftIO $ contextCreate sign >>= \x ->
+        withEntropy (contextRandomize x)
     assertBool "context randomized" $ isSuccess ret
 
-clone_context_test :: Assertion
-clone_context_test = do
+cloneContextTest :: Assertion
+cloneContextTest = do
     (x1, x2) <- liftIO $ do
-        x1 <- context_create signVerify
-        ret <- withEntropy $ context_randomize x1
+        x1 <- contextCreate signVerify
+        ret <- withEntropy $ contextRandomize x1
         unless (isSuccess ret) $ error "failed to randomize context"
-        x2 <- context_clone(x1)
+        x2 <- contextClone x1
         return (x1, x2)
     assertBool "original context not null" $ x1 /= nullPtr
     assertBool "cloned context not null" $ x2 /= nullPtr
     assertBool "context ptrs different" $ x1 /= x2
 
-ec_pubkey_parse_test :: Assertion
-ec_pubkey_parse_test = do
+ecPubkeyParseTest :: Assertion
+ecPubkeyParseTest = do
     ret <- liftIO $ useAsCStringLen der $ \(i, il) -> do
-        x <- context_create verify
+        x <- contextCreate verify
         alloca $ \pubkey ->
-            ec_pubkey_parse x pubkey (castPtr i) (fromIntegral il)
+            ecPubKeyParse x pubkey (castPtr i) (fromIntegral il)
     assertBool "parsed public key" (isSuccess ret)
   where
     der = fst $ B16.decode
         "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"
 
-ec_pubkey_serialize_test :: Assertion
-ec_pubkey_serialize_test = do
+ecPubKeySerializeTest :: Assertion
+ecPubKeySerializeTest = do
     (ret, dec) <- liftIO $ useAsCStringLen der $ \(i, il) ->
         alloca $ \k -> alloca $ \ol -> allocaBytes 72 $ \o -> do
         poke ol 72
-        x <- context_create verify
+        x <- contextCreate verify
         ret1 <-
-            ec_pubkey_parse x k (castPtr i) (fromIntegral il)
+            ecPubKeyParse x k (castPtr i) (fromIntegral il)
         unless (isSuccess ret1) $ error "failed to parse pubkey"
-        ret2 <- ec_pubkey_serialize
+        ret2 <- ecPubKeySerialize
             x o ol k compressed
         len <- fromIntegral <$> peek ol
         decoded <- packCStringLen (castPtr o, len)
@@ -112,20 +108,20 @@
     der = fst $ B16.decode
         "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"
 
-pubkey_storable_test :: Assertion
-pubkey_storable_test = do
+pubkeyStorableTest :: Assertion
+pubkeyStorableTest = do
     (pk1, pk2, dec) <- liftIO $ useAsCStringLen der $ \(i, il) -> do
-        x <- context_create verify
+        x <- contextCreate verify
         pk1 <- alloca $ \pk -> do
             ret <-
-                ec_pubkey_parse x pk (castPtr i) (fromIntegral il)
+                ecPubKeyParse x pk (castPtr i) (fromIntegral il)
             unless (isSuccess ret) $ error "failed to parse pubkey"
             peek pk
         (pk2, dec) <- alloca $ \pk -> alloca $ \ol -> allocaBytes 72 $ \o -> do
             poke ol 72
             poke pk pk1
             ret <-
-                ec_pubkey_serialize x o ol pk compressed
+                ecPubKeySerialize x o ol pk compressed
             unless (isSuccess ret) $ error "failed to serialize pubkey"
             len <- fromIntegral <$> peek ol
             dec <- packCStringLen (castPtr o, len)
@@ -138,18 +134,18 @@
     der = fst $ B16.decode
         "03dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705"
 
-signature_storable_test :: Assertion
-signature_storable_test = do
+signatureStorableTest :: Assertion
+signatureStorableTest = do
     (sig, ret) <- liftIO $ do
-        x <- context_create verify
+        x <- contextCreate verify
         g <- alloca $ \pc -> alloca $ \pg -> do
             poke pc cpt
-            ret <- ecdsa_signature_parse_compact x pg (castPtr pc)
+            ret <- ecdsaSignatureParseCompact x pg (castPtr pc)
             unless (isSuccess ret) $ error "failed to parse signature"
             peek pg
         alloca $ \pc -> alloca $ \pg -> do
             poke pg g
-            ret <- ecdsa_signature_serialize_compact x pc pg
+            ret <- ecdsaSignatureSerializeCompact x pc pg
             c <- peek pc
             return (c, ret)
     assertBool "successful serialization" (isSuccess ret)
@@ -159,111 +155,92 @@
         0xf502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb22
         0x6f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045
 
-ecdsa_signature_parse_der_test :: Assertion
-ecdsa_signature_parse_der_test = do
+ecdsaSignatureParseDerTest :: Assertion
+ecdsaSignatureParseDerTest = do
     ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do
-        x <- context_create verify
-        ecdsa_signature_parse_der x s (castPtr d) (fromIntegral dl)
+        x <- contextCreate verify
+        ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)
     assertBool "parsed signature successfully" $ isSuccess ret
   where
-    der = fst $ B16.decode $
+    der = fst $ B16.decode
         "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
         \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
         \45"
 
-lax_der_parse_test :: Assertion
-lax_der_parse_test = do
+laxDerParseTest :: Assertion
+laxDerParseTest = do
     ret <- liftIO $ useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do
-        x <- context_create verify
-        lax_der_parse x s (castPtr d) (fromIntegral dl)
+        x <- contextCreate verify
+        laxDerParse x s (castPtr d) (fromIntegral dl)
     assertBool "parsed signature successfully" $ isSuccess ret
   where
-    der = fst $ B16.decode $
+    der = fst $ B16.decode
         "30450220f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37fb\
         \2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e3045"
 
-ecdsa_signature_serialize_der_test :: Assertion
-ecdsa_signature_serialize_der_test = do
+parseDer :: Ptr Ctx -> ByteString -> IO Sig64
+parseDer x bs = useAsCStringLen bs $ \(d, dl) -> alloca $ \s -> do
+    ret <- ecdsaSignatureParseDer x s (castPtr d) (fromIntegral dl)
+    unless (isSuccess ret) $ error "could not parse DER"
+    peek s
+
+ecdsaSignatureSerializeDerTest :: Assertion
+ecdsaSignatureSerializeDerTest = do
     (ret, enc) <- liftIO $ do
-        x <- context_create verify
-        sig <- useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do
-            ret <-
-                ecdsa_signature_parse_der x s (castPtr d) (fromIntegral dl)
-            unless (isSuccess ret) $ error "could not parse DER"
-            peek s
+        x <- contextCreate verify
+        sig <- parseDer x der
         alloca $ \s -> alloca $ \ol -> allocaBytes 72 $ \o -> do
             poke ol 72
             poke s sig
             ret <-
-                ecdsa_signature_serialize_der x o ol s
+                ecdsaSignatureSerializeDer x o ol s
             len <- fromIntegral <$> peek ol
             enc <- packCStringLen (castPtr o, len)
             return (ret, enc)
     assertBool  "serialization successful" $ isSuccess ret
     assertEqual "signatures match" der enc
   where
-    der = fst $ B16.decode $
+    der = fst $ B16.decode
         "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
         \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
         \45"
 
-ecdsa_verify_test :: Assertion
-ecdsa_verify_test = do
+ecdsaVerifyTest :: Assertion
+ecdsaVerifyTest = do
     ret <- liftIO $ do
-        x <- context_create verify
-        sig <- useAsCStringLen der $ \(d, dl) -> alloca $ \s -> do
-            ret <-
-                ecdsa_signature_parse_der x s (castPtr d) (fromIntegral dl)
-            unless (isSuccess ret) $ error "could not parse DER"
-            peek s
+        x <- contextCreate verify
+        sig <- parseDer x der
         pk <- useAsCStringLen pub $ \(p, pl) -> alloca $ \k -> do
             ret <-
-                ec_pubkey_parse x k (castPtr p) (fromIntegral pl)
+                ecPubKeyParse x k (castPtr p) (fromIntegral pl)
             unless (isSuccess ret) $ error "could not parse public key"
             peek k
         alloca $ \m -> alloca $ \k -> alloca $ \s -> do
             poke m msg
             poke k pk
             poke s sig
-            ecdsa_verify x s m k
+            ecdsaVerify x s m k
     assertBool "signature valid" $ isSuccess ret
   where
-    der = fst $ B16.decode $
+    der = fst $ B16.decode
         "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
         \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
         \45"
-    pub = fst $ B16.decode $
+    pub = fst $ B16.decode
         "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
         \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-    msg = Msg32 $ fst $ B16.decode $
+    msg = Msg32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
 
--- TODO:
--- nonce_function_rfc6979_test :: Assertion
--- nonce_function_rfc6979_test = do
---     (ret, nonce) <- alloca $ \n -> alloca $ \m -> alloca $ \k -> do
---             poke m msg
---             poke k key
---             let ret = mkNonceFunction
---                     nonce_function_rfc6979 n m k nullPtr nullPtr 0
---             nonce <- peek n
---             return (ret, nonce)
---     assertBool "nonce calculated" $ isSuccess ret
---     assertEqual "nonce correct" expected nonce
---   where
---     msg = Msg32 $ fst $ B16.decode $
---         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
---     key = SecKey32 $ fst $ B16.decode $
---         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
---     expected = Nonce $ fst $ B16.decode $
---         "8f30c2bf5a3e1199b19a6703fa578376e5225d6ecfc7ecf817aa8b8b16203d64"
+signCtx :: IO (Ptr Ctx)
+signCtx = contextCreate sign >>= \c ->
+    withEntropy (contextRandomize c) >>= \r ->
+        unless (isSuccess r) (error "failed to randomize context") >> return c
 
-ecdsa_sign_test :: Assertion
-ecdsa_sign_test = do
+ecdsaSignTest :: Assertion
+ecdsaSignTest = do
     (ret, sig) <- liftIO $ do
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
-        unless (isSuccess retr) $ error "failed to randomize context"
+        x <- signCtx
         alloca $ \s -> alloca $ \m -> alloca $ \k -> alloca $ \ol ->
             allocaBytes 72 $ \o -> do
                 poke ol 72
@@ -271,9 +248,9 @@
                 poke k key
                 ret1 <-
                     -- TODO:
-                    -- ecdsa_sign x s m k nonce_function_default nullPtr
-                    ecdsa_sign x s m k nullFunPtr nullPtr
-                ret2 <- ecdsa_signature_serialize_der x o ol s
+                    -- ecdsaSign x s m k nonce_function_default nullPtr
+                    ecdsaSign x s m k nullFunPtr nullPtr
+                ret2 <- ecdsaSignatureSerializeDer x o ol s
                 unless (isSuccess ret2) $error "could not serialize signature"
                 len <- peek ol
                 sig <- packCStringLen (castPtr o, fromIntegral len)
@@ -281,39 +258,35 @@
     assertBool "successful signing" $ isSuccess ret
     assertEqual "signature matches" sig der
   where
-    msg = Msg32 $ fst $ B16.decode $
+    msg = Msg32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-    der = fst $ B16.decode $
+    der = fst $ B16.decode
         "3045022100f502bfa07af43e7ef265618b0d929a7619ee01d6150e37eb6eaaf2c8bd37\
         \fb2202206f0415ab0e9a977afd78b2c26ef39b3952096d319fd4b101c768ad6c132e30\
         \45"
 
-ec_seckey_verify_test :: Assertion
-ec_seckey_verify_test = do
+ecSecKeyVerifyTest :: Assertion
+ecSecKeyVerifyTest = do
     ret <- liftIO $ alloca $ \k -> do
         poke k key
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
-        unless (isSuccess retr) $ error "failed to randomize context"
-        ec_seckey_verify x k
+        x <- signCtx
+        ecSecKeyVerify x k
     assertBool "valid secret key" $ isSuccess ret
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
 
-ec_pubkey_create_test :: Assertion
-ec_pubkey_create_test = do
+ecPubkeyCreateTest :: Assertion
+ecPubkeyCreateTest = do
     (ret, pk) <- liftIO $ alloca $ \p -> alloca $ \k -> do
         poke k key
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
-        unless (isSuccess retr) $ error "failed to randomize context"
-        ret <- ec_pubkey_create x p k
+        x <- signCtx
+        ret <- ecPubKeyCreate x p k
         allocaBytes 65 $ \o -> alloca $ \ol -> do
             poke ol 65
-            rets <- ec_pubkey_serialize
+            rets <- ecPubKeySerialize
                 x o ol p uncompressed
             unless (isSuccess rets) $ error "failed to serialive public key"
             len <- fromIntegral <$> peek ol
@@ -322,187 +295,174 @@
     assertBool "successful pubkey creation" $ isSuccess ret
     assertEqual "public key matches" pub pk
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-    pub = fst $ B16.decode $
+    pub = fst $ B16.decode
         "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
         \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
 
-ec_privkey_export_test :: Assertion
-ec_privkey_export_test = do
+ecSecKeyExportTest :: Assertion
+ecSecKeyExportTest = do
     ret <- liftIO $ alloca $ \k ->
         allocaBytes 279 $ \o -> alloca $ \ol -> do
             poke ol 279
             poke k key
-            x <- context_create sign
-            retr <- withEntropy $ context_randomize x
-            unless (isSuccess retr) $ error "failed to randomize context"
-            ec_privkey_export x o ol k uncompressed
+            x <- signCtx
+            ecSecKeyExport x o ol k uncompressed
     assertBool "successful secret key BER serialization" $ isSuccess ret
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
 
-ec_privkey_import_test :: Assertion
-ec_privkey_import_test = do
+ecSecKeyImportTest :: Assertion
+ecSecKeyImportTest = do
     (ret, dec) <- liftIO $ do
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
-        unless (isSuccess retr) $ error "failed to randomize context"
+        x <- signCtx
         ber <- allocaBytes 279 $ \o -> alloca $ \ol -> alloca $ \k -> do
             poke ol 279
             poke k key
-            rets <- ec_privkey_export x o ol k uncompressed
+            rets <- ecSecKeyExport x o ol k uncompressed
             unless (isSuccess rets) $ error "failed to serialize key"
             len <- fromIntegral <$> peek ol
             packCStringLen (castPtr o, len)
         useAsCStringLen ber $ \(b, bl) -> alloca $ \k -> do
-            ret <- ec_privkey_import x k (castPtr b) (fromIntegral bl)
+            ret <- ecSecKeyImport x k (castPtr b) (fromIntegral bl)
             dec <- peek k
             return (ret, dec)
     assertBool "successful secret key BER deserialization" $ isSuccess ret
     assertEqual "keys match" key dec
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
 
-ec_privkey_tweak_add_test :: Assertion
-ec_privkey_tweak_add_test = do
+ecSecKeyTweakAddTest :: Assertion
+ecSecKeyTweakAddTest = do
     (ret, tweaked) <- liftIO $ do
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
-        unless (isSuccess retr) $ error "failed to randomize context"
+        x <- signCtx
         alloca $ \w -> alloca $ \k -> do
             poke w tweak
             poke k key
-            ret <- ec_privkey_tweak_add x k w
+            ret <- ecSecKeyTweakAdd x k w
             tweaked <- peek k
             return (ret, tweaked)
     assertBool "successful secret key tweak" $ isSuccess ret
     assertEqual "tweaked keys match" expected tweaked
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-    tweak = Tweak32 $ fst $ B16.decode $
+    tweak = Tweak32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-    expected = SecKey32 $ fst $ B16.decode $
+    expected = SecKey32 $ fst $ B16.decode
         "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"
 
-ec_privkey_tweak_mul_test :: Assertion
-ec_privkey_tweak_mul_test = do
+ecSecKeyTweakMulTest :: Assertion
+ecSecKeyTweakMulTest = do
     (ret, tweaked) <- liftIO $ do
-        x <- context_create sign
-        retr <- withEntropy $ context_randomize x
+        x <- contextCreate sign
+        retr <- withEntropy $ contextRandomize x
         unless (isSuccess retr) $ error "failed to randomize context"
         alloca $ \w -> alloca $ \k -> do
             poke w tweak
             poke k key
-            ret <- ec_privkey_tweak_mul x k w
+            ret <- ecSecKeyTweakMul x k w
             tweaked <- peek k
             return (ret, tweaked)
     assertBool "successful secret key tweak" $ isSuccess ret
     assertEqual "tweaked keys match" expected tweaked
   where
-    key = SecKey32 $ fst $ B16.decode $
+    key = SecKey32 $ fst $ B16.decode
         "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-    tweak = Tweak32 $ fst $ B16.decode $
+    tweak = Tweak32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-    expected = SecKey32 $ fst $ B16.decode $
+    expected = SecKey32 $ fst $ B16.decode
         "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"
 
-ec_pubkey_tweak_add_test :: Assertion
-ec_pubkey_tweak_add_test = do
+serializeKey :: Ptr Ctx -> Ptr PubKey64 -> IO ByteString
+serializeKey x p = allocaBytes 72 $ \d -> alloca $ \dl -> do
+    ret <- ecPubKeySerialize x d dl p uncompressed
+    unless (isSuccess ret) $ error "could not serialize public key"
+    len <- peek dl
+    packCStringLen (castPtr d, fromIntegral len)
+
+parseKey :: Ptr Ctx -> ByteString -> IO PubKey64
+parseKey x bs = alloca $ \p -> useAsCStringLen bs $ \(d, dl) -> do
+    ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)
+    unless (isSuccess ret) $ error "could not parse public key"
+    peek p
+
+ecPubKeyTweakAddTest :: Assertion
+ecPubKeyTweakAddTest = do
     (ret, tweaked) <- liftIO $ do
-        x <- context_create verify
-        pk <- alloca $ \p -> useAsCStringLen pub $ \(d, dl) -> do
-            ret <- ec_pubkey_parse x p (castPtr d) (fromIntegral dl)
-            unless (isSuccess ret) $ error "could not parse public key"
-            peek p
-        alloca $ \w -> alloca $ \p -> allocaBytes 72 $ \d -> alloca $ \dl -> do
+        x <- contextCreate verify
+        pk <- parseKey x pub
+        alloca $ \w -> alloca $ \p -> do
             poke w tweak
             poke p pk
-            poke dl 72
-            ret <- ec_pubkey_tweak_add x p w
-            rets <- ec_pubkey_serialize x d dl p uncompressed
-            unless (isSuccess rets) $ error "could not serialize public key"
-            len <- peek dl
-            tweaked <- packCStringLen (castPtr d, fromIntegral len)
+            ret <- ecPubKeyTweakAdd x p w
+            tweaked <- serializeKey x p
             return (ret, tweaked)
     assertBool "successful secret key tweak" $ isSuccess ret
     assertEqual "tweaked keys match" expected tweaked
   where
-    pub = fst $ B16.decode $
+    pub = fst $ B16.decode
         "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
         \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-    tweak = Tweak32 $ fst $ B16.decode $
+    tweak = Tweak32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-    expected = fst $ B16.decode $
+    expected = fst $ B16.decode
         "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\
         \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"
 
-ec_pubkey_tweak_mul_test :: Assertion
-ec_pubkey_tweak_mul_test = do
+ecPubKeyTweakMulTest :: Assertion
+ecPubKeyTweakMulTest = do
     (ret, tweaked) <- liftIO $ do
-        x <- context_create verify
-        pk <- alloca $ \p -> useAsCStringLen pub $ \(d, dl) -> do
-            ret <- ec_pubkey_parse x p (castPtr d) (fromIntegral dl)
-            unless (isSuccess ret) $ error "could not parse public key"
-            peek p
-        alloca $ \w -> alloca $ \p -> allocaBytes 72 $ \d -> alloca $ \dl -> do
+        x <- contextCreate verify
+        pk <- parseKey x pub
+        alloca $ \w -> alloca $ \p -> do
             poke w tweak
             poke p pk
-            poke dl 72
-            ret <- ec_pubkey_tweak_mul x p w
-            rets <- ec_pubkey_serialize x d dl p uncompressed
-            unless (isSuccess rets) $ error "could not serialize public key"
-            len <- peek dl
-            tweaked <- packCStringLen (castPtr d, fromIntegral len)
+            ret <- ecPubKeyTweakMul x p w
+            tweaked <- serializeKey x p
             return (ret, tweaked)
     assertBool "successful secret key tweak" $ isSuccess ret
     assertEqual "tweaked keys match" expected tweaked
   where
-    pub = fst $ B16.decode $
+    pub = fst $ B16.decode
         "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
         \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-    tweak = Tweak32 $ fst $ B16.decode $
+    tweak = Tweak32 $ fst $ B16.decode
         "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
-    expected = fst $ B16.decode $
+    expected = fst $ B16.decode
         "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\
         \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"
 
-ec_pubkey_combine_test :: Assertion
-ec_pubkey_combine_test = do
+ecPubKeyCombineTest :: Assertion
+ecPubKeyCombineTest = do
     (ret, com) <- liftIO $ alloca $ \p1 -> alloca $ \p2 -> alloca $ \p3 ->
-        allocaBytes 72 $ \d -> alloca $ \dl -> allocaArray 3 $ \a ->
-            alloca $ \p -> do
-                x <- context_create verify
-                parse x pub1 p1
-                parse x pub2 p2
-                parse x pub3 p3
-                pokeArray a [p1, p2, p3]
-                poke dl 72
-                ret <- ec_pubkey_combine x p a 3
-                rets <- ec_pubkey_serialize
-                    x d dl p uncompressed
-                unless (isSuccess rets) $ error "could not serialize public key"
-                len <- peek dl
-                com <- packCStringLen (castPtr d, fromIntegral len)
-                return (ret, com)
+        allocaArray 3 $ \a -> alloca $ \p -> do
+            x <- contextCreate verify
+            parse x pub1 p1
+            parse x pub2 p2
+            parse x pub3 p3
+            pokeArray a [p1, p2, p3]
+            ret <- ecPubKeyCombine x p a 3
+            com <- serializeKey x p
+            return (ret, com)
     assertBool "successful key combination" $ isSuccess ret
     assertEqual "combined keys match" expected com
   where
     parse x pub p = useAsCStringLen pub $ \(d, dl) -> do
-        ret <- ec_pubkey_parse x p (castPtr d) (fromIntegral dl)
+        ret <- ecPubKeyParse x p (castPtr d) (fromIntegral dl)
         unless (isSuccess ret) $ error "could not parse public key"
-    pub1 = fst $ B16.decode $
+    pub1 = fst $ B16.decode
         "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd447051221\
         \3d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-    pub2 = fst $ B16.decode $
+    pub2 = fst $ B16.decode
         "0487d82042d93447008dfe2af762068a1e53ff394a5bf8f68a045fa642b99ea5d153f5\
         \77dd2dba6c7ae4cfd7b6622409d7edd2d76dd13a8092cd3af97b77bd2c77"
-    pub3 = fst $ B16.decode $
+    pub3 = fst $ B16.decode
         "049b101edcbe1ee37ff6b2318526a425b629e823d7d8d9154417880595a28000ee3feb\
         \d908754b8ce4e491aa6fe488b41fb5d4bb3788e33c9ff95a7a9229166d59"
-    expected = fst $ B16.decode $
+    expected = fst $ B16.decode
         "043d9a7ec70011efc23c33a7e62d2ea73cca87797e3b659d93bea6aa871aebde56c3bc\
         \6134ca82e324b0ab9c0e601a6d2933afe7fb5d9f3aae900f5c5dc6e362c8"
diff --git a/haskell/test/Crypto/Secp256k1/Tests.hs b/haskell/test/Crypto/Secp256k1/Tests.hs
--- a/haskell/test/Crypto/Secp256k1/Tests.hs
+++ b/haskell/test/Crypto/Secp256k1/Tests.hs
@@ -33,7 +33,7 @@
 
 signMsgTest :: (Msg, SecKey) -> Bool
 signMsgTest (fm, fk) = verifySig fp fg fm where
-    fp = pubKey fk
+    fp = derivePubKey fk
     fg = signMsg fk fm
 
 badSignatureTest :: (Msg, SecKey, PubKey) -> Bool
@@ -41,7 +41,7 @@
     fg = signMsg fk fm
 
 normalizeSigTest :: (Msg, SecKey) -> Bool
-normalizeSigTest (fm, fk) = norm == False && sig == fg where
+normalizeSigTest (fm, fk) = not norm && sig == fg where
     fg = signMsg fk fm
     (sig, norm) = normalizeSig fg
 
@@ -86,12 +86,12 @@
     assertEqual "tweaked keys match" expected tweaked
   where
     tweaked = do
-        key <- secKey $ fst $ B16.decode $ B8.pack $
+        key <- secKey $ fst $ B16.decode $ B8.pack
             "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-        twk <- tweak $ fst $ B16.decode $ B8.pack $
+        twk <- tweak $ fst $ B16.decode $ B8.pack
             "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
         tweakAddSecKey key twk
-    expected = secKey $ fst $ B16.decode $ B8.pack $
+    expected = secKey $ fst $ B16.decode $ B8.pack
         "ec1e3ce1cefa18a671d51125e2b249688d934b0e28f5d1665384d9b02f929059"
 
 tweakMulSecKeyTest :: Assertion
@@ -99,12 +99,12 @@
     assertEqual "tweaked keys match" expected tweaked
   where
     tweaked = do
-        key <- secKey $ fst $ B16.decode $ B8.pack $
+        key <- secKey $ fst $ B16.decode $ B8.pack
             "f65255094d7773ed8dd417badc9fc045c1f80fdc5b2d25172b031ce6933e039a"
-        twk <- tweak $ fst $ B16.decode $ B8.pack $
+        twk <- tweak $ fst $ B16.decode $ B8.pack
             "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
         tweakMulSecKey key twk
-    expected = secKey $ fst $ B16.decode $ B8.pack $
+    expected = secKey $ fst $ B16.decode $ B8.pack
         "a96f5962493acb179f60a86a9785fc7a30e0c39b64c09d24fe064d9aef15e4c0"
 
 tweakAddPubKeyTest :: Assertion
@@ -112,13 +112,13 @@
     assertEqual "tweaked keys match" expected tweaked
   where
     tweaked = do
-        pub <- importPubKey $ fst $ B16.decode $ B8.pack $
+        pub <- importPubKey $ fst $ B16.decode $ B8.pack
             "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705\
             \12213d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-        twk <- tweak $ fst $ B16.decode $ B8.pack $
+        twk <- tweak $ fst $ B16.decode $ B8.pack
             "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
         tweakAddPubKey pub twk
-    expected = importPubKey $ fst $ B16.decode $ B8.pack $
+    expected = importPubKey $ fst $ B16.decode $ B8.pack
         "04441c3982b97576646e0df0c96736063df6b42f2ee566d13b9f6424302d1379e518fd\
         \c87a14c5435bff7a5db4552042cb4120c6b86a4bbd3d0643f3c14ad01368"
 
@@ -127,13 +127,13 @@
     assertEqual "tweaked keys match" expected tweaked
   where
     tweaked = do
-        pub <- importPubKey $ fst $ B16.decode $ B8.pack $
+        pub <- importPubKey $ fst $ B16.decode $ B8.pack
             "04dded4203dac96a7e85f2c374a37ce3e9c9a155a72b64b4551b0bfe779dd44705\
             \12213d5ed790522c042dee8e85c4c0ec5f96800b72bc5940c8bc1c5e11e4fcbf"
-        twk <- tweak $ fst $ B16.decode $ B8.pack $
+        twk <- tweak $ fst $ B16.decode $ B8.pack
             "f5cbe7d88182a4b8e400f96b06128921864a18187d114c8ae8541b566c8ace00"
         tweakMulPubKey pub twk
-    expected = importPubKey $ fst $ B16.decode $ B8.pack $
+    expected = importPubKey $ fst $ B16.decode $ B8.pack
         "04f379dc99cdf5c83e433defa267fbb3377d61d6b779c06a0e4ce29ae3ff5353b12ae4\
         \9c9d07e7368f2ba5a446c203255ce912322991a2d6a9d5d5761c61ed1845"
 
diff --git a/secp256k1.cabal b/secp256k1.cabal
--- a/secp256k1.cabal
+++ b/secp256k1.cabal
@@ -1,5 +1,5 @@
 name:                secp256k1
-version:             0.2.0
+version:             0.3.0
 synopsis:            secp256k1 bindings for Haskell
 description:         Please see README.md
 homepage:            http://github.com/haskoin/secp256k1#readme
