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
@@ -2,7 +2,7 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-|
 Module      : Crypto.Secp256k1
-Description : Public SECP256K1 cryptographic functions
+Description : ECDSA on curve secp256k1
 License     : PublicDomain
 Maintainer  : root@haskoin.com
 Stability   : experimental
@@ -33,7 +33,6 @@
 
     -- * Signatures
     , Sig
-    , CompactSig(..)
     , signMsg
     , verifySig
     , normalizeSig
@@ -42,6 +41,7 @@
     , laxImportSig
     , exportSig
     -- ** Compact
+    , CompactSig(..)
     , exportCompactSig
     , importCompactSig
 
@@ -59,9 +59,11 @@
 import           Control.Applicative
 import           Control.Monad
 import           Crypto.Secp256k1.Internal
+import qualified Data.Binary               as Bin
 import           Data.ByteString           (ByteString)
 import qualified Data.ByteString           as BS
 import qualified Data.ByteString.Base16    as B16
+import qualified Data.ByteString.Lazy      as BL
 import           Data.Maybe
 import           Data.String
 import           Data.String.Conversions
@@ -89,83 +91,73 @@
 decodeHex str = if BS.null r then Just bs else Nothing where
     (bs, r) = B16.decode $ cs str
 
--- TODO: Test
 instance Read PubKey where
     readPrec = parens $ do
         Ident "PubKey" <- lexP
         String str <- lexP
         maybe pfail return $ importPubKey =<< decodeHex str
 
--- TODO: Test
 instance IsString PubKey where
     fromString = fromJust . (importPubKey <=< decodeHex)
 
--- TODO: Test
 instance Show PubKey where
     showsPrec d k = showParen (d > 10) $
         showString "PubKey " . shows (B16.encode $ exportPubKey True k)
 
--- TODO: Test
 instance Read Msg where
     readPrec = parens $ do
         Ident "Msg" <- lexP
         String str <- lexP
         maybe pfail return $ msg =<< decodeHex str
 
--- TODO: Test
 instance IsString Msg where
-    fromString = fromJust . msg . cs
+    fromString = fromJust . msg . fromJust . decodeHex
 
--- TODO: Test
 instance Show Msg where
     showsPrec d m = showParen (d > 10) $
         showString "Msg " . shows (B16.encode $ getMsg m)
 
--- TODO: Test
 instance Read Sig where
     readPrec = parens $ do
         Ident "Sig" <- lexP
         String str <- lexP
         maybe pfail return $ importSig =<< decodeHex str
 
--- TODO: Test
 instance IsString Sig where
-    fromString = fromJust . (importSig <=< decodeHex)
+    fromString hex = fromJust $ der <|> compact
+      where
+        compact = do
+            c <- (Bin.decode . BL.fromStrict) <$> decodeHex hex
+            importCompactSig c
+        der = importSig =<< decodeHex hex
 
--- TODO: Test
 instance Show Sig where
     showsPrec d s = showParen (d > 10) $
         showString "Sig " . shows (B16.encode $ exportSig s)
 
--- TODO: Test
 instance Read SecKey where
     readPrec = parens $ do
         Ident "SecKey" <- lexP
         String str <- lexP
         maybe pfail return $ secKey =<< decodeHex str
 
--- TODO: Test
 instance IsString SecKey where
     fromString str = fromJust $
         (secKey =<< decodeHex str) <|> (importSecKey =<< decodeHex str)
 
--- TODO: Test
 instance Show SecKey where
     showsPrec d k = showParen (d > 10) $
         showString "SecKey " . shows (B16.encode $ getSecKey k)
 
--- TODO: Test
 instance Read Tweak where
     readPrec = parens $ do
         Ident "Tweak" <- lexP
         String str <- lexP
         maybe pfail return $ tweak =<< decodeHex str
 
--- TODO: Test
 instance IsString Tweak where
     fromString = fromJust . (tweak <=< decodeHex)
 
--- TODO: Test
 instance Show Tweak where
     showsPrec d k = showParen (d > 10) $
         showString "Tweak " . shows (B16.encode $ getTweak k)
@@ -270,7 +262,7 @@
         unless (isSuccess ret) $ error "Could not obtain compact signature"
         peek pc
 
--- | Read DER-encoded signature.
+-- | Read compact signature.
 importCompactSig :: CompactSig -> Maybe Sig
 importCompactSig c = unsafePerformIO $ alloca $ \pc -> do
     poke pc c
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
@@ -1,6 +1,6 @@
 {-|
 Module      : Crypto.Secp256k1.Internal
-Description : Internal SECP256K1 cryptographic functions
+Description : secp256k1 C bindings
 License     : PublicDomain
 Maintainer  : root@haskoin.com
 Stability   : experimental
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
@@ -1,8 +1,13 @@
 module Crypto.Secp256k1.Tests (tests) where
 
 import           Crypto.Secp256k1
+import qualified Data.Binary                          as Bin
 import qualified Data.ByteString.Base16               as B16
 import qualified Data.ByteString.Char8                as B8
+import qualified Data.ByteString.Lazy                 as BL
+import           Data.Maybe                           (fromJust)
+import           Data.String                          (fromString)
+import           Data.String.Conversions              (cs)
 import           Test.Framework                       (Test, testGroup)
 import           Test.Framework.Providers.HUnit       (testCase)
 import           Test.Framework.Providers.QuickCheck2 (testProperty)
@@ -21,6 +26,17 @@
         , testProperty "Serialize lax DER signature" serializeLaxSigTest
         , testProperty "Serialize compact signature" serializeCompactSigTest
         , testProperty "Serialize secret key" serializeSecKeyTest
+        , testProperty "Show/Read public key" (showRead :: PubKey -> Bool)
+        , testProperty "Show/Read secret key" (showRead :: SecKey -> Bool)
+        , testProperty "Show/Read tweak" (showReadTweak :: SecKey -> Bool)
+        , testProperty "Show/Read signature" (showReadSig :: (SecKey, Msg) -> Bool)
+        , testProperty "Show/Read message" (showRead :: Msg -> Bool)
+        , testProperty "String public key" isStringPubKey
+        , testProperty "String secret key" isStringSecKey
+        , testProperty "String signature" isStringSig
+        , testProperty "String compact signature" isStringCompactSig
+        , testProperty "String message" isStringMsg
+        , testProperty "String tweak" isStringTweak
         ]
     , testGroup "Tweaks"
         [ testCase "Tweak add secret key" tweakAddSecKeyTest
@@ -30,6 +46,44 @@
         , testCase "Combine public keys" combinePubKeyTest
         ]
     ]
+
+isStringPubKey :: (PubKey, Bool) -> Bool
+isStringPubKey (k, c) = k == fromString (cs hex) where
+    hex = B16.encode $ exportPubKey c k
+
+isStringSig :: (SecKey, Msg) -> Bool
+isStringSig (k, m) = g == fromString (cs hex) where
+    g = signMsg k m
+    hex = B16.encode $ exportSig g
+
+isStringCompactSig :: (SecKey, Msg) -> Bool
+isStringCompactSig (k, m) = g == fromString (cs hex) where
+    g = signMsg k m
+    hex = B16.encode . BL.toStrict . Bin.encode $ exportCompactSig g
+
+isStringMsg :: Msg -> Bool
+isStringMsg m = m == fromString (cs m') where
+    m' = B16.encode $ getMsg m
+
+isStringSecKey :: SecKey -> Bool
+isStringSecKey k = k == fromString (cs hex) where
+    hex = B16.encode $ getSecKey k
+
+isStringTweak :: SecKey -> Bool
+isStringTweak k = t == fromString (cs hex) where
+    t = fromJust . tweak $ getSecKey k
+    hex = B16.encode $ getTweak t
+
+showReadTweak :: SecKey -> Bool
+showReadTweak k = showRead t where
+    t = tweak $ getSecKey k
+
+showReadSig :: (SecKey, Msg) -> Bool
+showReadSig (k, m) = showRead sig where
+    sig = signMsg k m
+
+showRead :: (Show a, Read a, Eq a) => a -> Bool
+showRead x = read (show x) == x
 
 signMsgTest :: (Msg, SecKey) -> Bool
 signMsgTest (fm, fk) = verifySig fp fg fm where
diff --git a/secp256k1.cabal b/secp256k1.cabal
--- a/secp256k1.cabal
+++ b/secp256k1.cabal
@@ -1,5 +1,5 @@
 name:                secp256k1
-version:             0.3.1
+version:             0.3.2
 synopsis:            secp256k1 bindings for Haskell
 description:         Please see README.md
 homepage:            http://github.com/haskoin/secp256k1#readme
@@ -116,6 +116,7 @@
                        , Crypto.Secp256k1.Internal.Tests
     build-depends:       base
                        , base16-bytestring
+                       , binary
                        , bytestring
                        , cryptohash
                        , entropy
@@ -123,6 +124,7 @@
                        , mtl
                        , QuickCheck
                        , secp256k1
+                       , string-conversions
                        , test-framework
                        , test-framework-hunit
                        , test-framework-quickcheck2
