diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,23 +7,28 @@
 # release of a major GHC version. Setting HPVER implictly sets
 # GHCVER. Omit lines with versions you don't need/want testing for.
 env:
-# - GHCVER=6.12.3
-# - GHCVER=7.0.1
-# - GHCVER=7.0.2
-# - GHCVER=7.0.3
-# - GHCVER=7.0.4
-# - GHCVER=7.2.1
-# - GHCVER=7.2.2
+ - GHCVER=6.12.3
+ - GHCVER=7.0.1
+ - GHCVER=7.0.2
+ - GHCVER=7.0.3
+ - GHCVER=7.0.4
+ - GHCVER=7.2.1
+ - GHCVER=7.2.2
  - GHCVER=7.4.1
  - GHCVER=7.4.2
  - GHCVER=7.6.1
  - GHCVER=7.6.2
  - GHCVER=7.6.3
+ - GHCVER=head
  - HPVER=2013.2.0.0
  - HPVER=2012.4.0.0
-# - HPVER=2012.2.0.0
-# - HPVER=2011.4.0.0
+ - HPVER=2012.2.0.0
+#- HPVER=2011.4.0.0
 
+matrix:
+  allow_failures:
+   - env: GHCVER=head
+
 # Note: the distinction between `before_install` and `install` is not
 #       important.
 before_install:
@@ -60,22 +65,22 @@
 
 install:
  - cabal-1.18 update
- - cabal-1.18 install happy alex
- - cabal-1.18 install --only-dependencies --enable-tests --enable-benchmarks
+ - cabal-1.18 install Cabal-1.18.1.2
+ - cabal-1.18 install --only-dependencies --enable-tests -f-test-hlint
 
 # Here starts the actual work to be performed for the package under
 # test; any command which exits with a non-zero exit code causes the
 # build to fail.
 script:
  # -v2 provides useful information for debugging
- - cabal-1.18 configure --enable-tests --enable-benchmarks -v2
+ - cabal-1.18 configure --enable-tests -f-test-hlint -v2
 
  # this builds all libraries and executables
  # (including tests/benchmarks)
  - cabal-1.18 build
 
  - cabal-1.18 test
-#- cabal-1.18 check
+ - cabal-1.18 check
 
  # tests that a source-distribution can be generated
  - cabal-1.18 sdist
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.0.2.0
+-------
+
+  * Portability improvements.
+
 0.0.1.0
 -------
 
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMain
diff --git a/Setup.lhs b/Setup.lhs
deleted file mode 100644
--- a/Setup.lhs
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/runhaskell
-\begin{code}
-{-# OPTIONS_GHC -Wall #-}
-module Main (main) where
-
-import Data.List ( nub )
-import Data.Version ( showVersion )
-import Distribution.Package ( PackageName(PackageName), Package, PackageId, InstalledPackageId, packageVersion, packageName )
-import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )
-import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )
-import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose, copyFiles )
-import Distribution.Simple.BuildPaths ( autogenModulesDir )
-import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), Flag(..), fromFlag, HaddockFlags(haddockDistPref))
-import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )
-import Distribution.Text ( display )
-import Distribution.Verbosity ( Verbosity, normal )
-import System.FilePath ( (</>) )
-
-main :: IO ()
-main = defaultMainWithHooks simpleUserHooks
-  { buildHook = \pkg lbi hooks flags -> do
-     generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi
-     buildHook simpleUserHooks pkg lbi hooks flags
-  , postHaddock = \args flags pkg lbi -> do
-     copyFiles normal (haddockOutputDir flags pkg) []
-     postHaddock simpleUserHooks args flags pkg lbi
-  }
-
-haddockOutputDir :: Package p => HaddockFlags -> p -> FilePath
-haddockOutputDir flags pkg = destDir where
-  baseDir = case haddockDistPref flags of
-    NoFlag -> "."
-    Flag x -> x
-  destDir = baseDir </> "doc" </> "html" </> display (packageName pkg)
-
-generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
-generateBuildModule verbosity pkg lbi = do
-  let dir = autogenModulesDir lbi
-  createDirectoryIfMissingVerbose verbosity True dir
-  withLibLBI pkg lbi $ \_ libcfg -> do
-    withTestLBI pkg lbi $ \suite suitecfg -> do
-      rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines
-        [ "module Build_" ++ testName suite ++ " where"
-        , "deps :: [String]"
-        , "deps = " ++ (show $ formatdeps (testDeps libcfg suitecfg))
-        ]
-  where
-    formatdeps = map (formatone . snd)
-    formatone p = case packageName p of
-      PackageName n -> n ++ "-" ++ showVersion (packageVersion p)
-
-testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]
-testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys
-
-\end{code}
diff --git a/ed25519.cabal b/ed25519.cabal
--- a/ed25519.cabal
+++ b/ed25519.cabal
@@ -1,5 +1,5 @@
 name:                ed25519
-version:             0.0.1.0
+version:             0.0.2.0
 category:            Cryptography
 license:             MIT
 synopsis:            ed25519 cryptographic signatures
@@ -9,10 +9,11 @@
 copyright:           Copyright (c) Austin Seipp 2013
 author:              Austin Seipp
 maintainer:          Austin Seipp <aseipp@pobox.com>
-build-type:          Custom
+build-type:          Simple
 cabal-version:       >=1.10
-tested-with:         GHC == 7.4.1, GHC == 7.4.2,
-                     GHC == 7.6.1, GHC == 7.6.2, GHC == 7.6.3
+tested-with:         GHC == 6.12.3, GHC == 7.0.1, GHC == 7.0.2, GHC == 7.0.3,
+                     GHC == 7.0.4,  GHC == 7.2.1, GHC == 7.2.2, GHC == 7.4.1,
+                     GHC == 7.4.2,  GHC == 7.6.1,  GHC == 7.6.2, GHC == 7.6.3
 
 description:
   This package provides a simple, portable implementation of the
@@ -45,32 +46,10 @@
   default: True
   manual: True
 
--- Enable these when/if we need them.
-flag test-hunit
-  default: False
-  manual: True
-
--- Can't run due to needing C library apparently?
-flag test-doctests
-  default: False
-  manual: True
-
 flag test-hlint
   default: True
   manual: True
 
-flag threaded
-  default: True
-  manual: True
-
-flag llvm
-  default: False
-  manual: True
-
-flag optimized
-  default: True
-  manual: True
-
 -------------------------------------------------------------------------------
 -- Build pt 1: main project
 
@@ -82,16 +61,9 @@
   exposed-modules:
     Crypto.Sign.Ed25519
 
-  if flag(optimized)
-    ghc-options: -O2
-
-  if flag(llvm)
-    ghc-options: -fllvm
-
   ghc-options:        -Wall -fwarn-tabs
-  default-language:   Haskell2010
+  default-language:   Haskell98
   hs-source-dirs:     src
-  cc-options:         -O3 -march=native
   c-sources:          src/cbits/ed25519.c
   include-dirs:       src/cbits src/cbits/include
 
@@ -103,13 +75,7 @@
   main-is: properties.hs
   ghc-options: -w
   hs-source-dirs: tests
-  default-language:   Haskell2010
-
-  if flag(threaded)
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N
-
-  if flag(llvm)
-    ghc-options: -fllvm
+  default-language:   Haskell98
 
   if !flag(test-properties)
     buildable: False
@@ -118,37 +84,7 @@
       base,
       ed25519,
       bytestring,
-      deepseq,
-      QuickCheck       >= 2.4,
-      tasty            >= 0.3,
-      tasty-quickcheck >= 0.3,
-      tasty-th         >= 0.1.1
-
-test-suite hunit
-  type: exitcode-stdio-1.0
-  main-is: hunit.hs
-  ghc-options: -w
-  hs-source-dirs: tests
-  default-language:   Haskell2010
-
-  if flag(threaded)
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N
-
-  if flag(llvm)
-    ghc-options: -fllvm
-
-  if !flag(test-hunit)
-    buildable: False
-  else
-    build-depends:
-      base,
-      ed25519,
-      bytestring,
-      deepseq,
-      QuickCheck       >= 2.4,
-      tasty            >= 0.3,
-      tasty-hunit      >= 0.2,
-      tasty-th         >= 0.1.1
+      QuickCheck  >= 2.4
 
 --
 -- Style/doc tests below
@@ -159,13 +95,7 @@
   main-is: hlint.hs
   ghc-options: -w
   hs-source-dirs: tests
-  default-language:   Haskell2010
-
-  if flag(threaded)
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N
-
-  if flag(llvm)
-    ghc-options: -fllvm
+  default-language:   Haskell98
 
   if !flag(test-hlint)
     buildable: False
@@ -174,35 +104,6 @@
       base,
       hlint >= 1.7
 
-test-suite doctests
-  type:           exitcode-stdio-1.0
-  main-is:        doctests.hs
-  ghc-options:    -Wall
-  hs-source-dirs: tests
-  default-language:   Haskell2010
-
-  if flag(threaded)
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N
-
-  if flag(llvm)
-    ghc-options: -fllvm
-
-  if !flag(test-doctests)
-    buildable: False
-  else
-    build-depends:
-      base,
-      bytestring,
-      containers,
-      directory      >= 1.0,
-      deepseq,
-      doctest        >= 0.9.1,
-      filepath,
-      semigroups     >= 0.9
-
-  if impl(ghc<7.6.1)
-    ghc-options: -Werror
-
 -------------------------------------------------------------------------------
 -- Build pt 3: benchmarks
 
@@ -215,12 +116,6 @@
     deepseq,
     ed25519
 
-  if flag(optimized)
-    ghc-options: -O2
-
-  if flag(llvm)
-    ghc-options: -fllvm
-
-  default-language:   Haskell2010
+  default-language:   Haskell98
   hs-source-dirs:     benchmarks
   main-is:            bench1.hs
diff --git a/src/Crypto/Sign/Ed25519.hs b/src/Crypto/Sign/Ed25519.hs
--- a/src/Crypto/Sign/Ed25519.hs
+++ b/src/Crypto/Sign/Ed25519.hs
@@ -29,7 +29,6 @@
        , sign'               -- :: SecretKey -> ByteString -> Signature
        , verify'             -- :: PublicKey -> ByteString -> Signature -> Bool
        ) where
-import           Control.Monad            (liftM, void)
 import           Foreign.C.Types
 import           Foreign.ForeignPtr       (withForeignPtr)
 import           Foreign.Marshal.Alloc    (alloca)
@@ -61,9 +60,11 @@
   pk <- SI.mallocByteString cryptoSignPUBLICKEYBYTES
   sk <- SI.mallocByteString cryptoSignSECRETKEYBYTES
 
-  void . withForeignPtr pk $ \ppk ->
-    void . withForeignPtr sk $ \psk ->
-      c_crypto_sign_keypair ppk psk
+  _ <- withForeignPtr pk $ \ppk -> do
+    _ <- withForeignPtr sk $ \psk -> do
+      _ <- c_crypto_sign_keypair ppk psk
+      return ()
+    return ()
 
   return (PublicKey $ SI.fromForeignPtr pk 0 cryptoSignPUBLICKEYBYTES,
           SecretKey $ SI.fromForeignPtr sk 0 cryptoSignSECRETKEYBYTES)
@@ -83,9 +84,9 @@
     SU.unsafeUseAsCString sk $ \psk ->
       SI.createAndTrim (mlen+cryptoSignBYTES) $ \out ->
         alloca $ \smlen -> do
-          void (c_crypto_sign out smlen mstr (fromIntegral mlen) psk)
-          fromIntegral `liftM` peek smlen
-{-# INLINEABLE sign #-}
+          _ <- (c_crypto_sign out smlen mstr (fromIntegral mlen) psk)
+          fromIntegral `fmap` peek smlen
+{-# INLINE sign #-}
 
 -- | Verifies a signed message against a 'PublicKey'.
 verify :: PublicKey
@@ -103,7 +104,7 @@
                c_crypto_sign_open pout pmlen smstr (fromIntegral smlen) ppk
 
         return (r == 0)
-{-# INLINEABLE verify #-}
+{-# INLINE verify #-}
 
 --------------------------------------------------------------------------------
 -- Detached signature support
@@ -124,7 +125,7 @@
   let sm = sign sk xs
       l  = S.length sm
   in Signature $! S.take (l - S.length xs) sm
-{-# INLINEABLE sign' #-}
+{-# INLINE sign' #-}
 
 -- | Verify a message with a detached 'Signature', for a given
 -- 'PublicKey'.
@@ -136,7 +137,7 @@
         -- ^ Message signature
         -> Bool
 verify' pk xs (Signature sig) = verify pk (sig `S.append` xs)
-{-# INLINEABLE verify' #-}
+{-# INLINE verify' #-}
 
 --
 -- FFI signature binding
@@ -151,13 +152,13 @@
 cryptoSignBYTES :: Int
 cryptoSignBYTES = 64
 
-foreign import ccall unsafe "crypto_sign_keypair"
+foreign import ccall unsafe "ed25519_sign_keypair"
   c_crypto_sign_keypair :: Ptr Word8 -> Ptr Word8 -> IO CInt
 
-foreign import ccall unsafe "crypto_sign"
+foreign import ccall unsafe "ed25519_sign"
   c_crypto_sign :: Ptr Word8 -> Ptr CULLong ->
                    Ptr CChar -> CULLong -> Ptr CChar -> IO CULLong
 
-foreign import ccall unsafe "crypto_sign_open"
+foreign import ccall unsafe "ed25519_sign_open"
   c_crypto_sign_open :: Ptr Word8 -> Ptr CULLong ->
                         Ptr CChar -> CULLong -> Ptr CChar -> IO CInt
diff --git a/src/cbits/include/ed25519.h b/src/cbits/include/ed25519.h
--- a/src/cbits/include/ed25519.h
+++ b/src/cbits/include/ed25519.h
@@ -8,12 +8,12 @@
 #define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
 #define crypto_sign_VERSION crypto_sign_ed25519_VERSION
 
-int crypto_sign_keypair(unsigned char *pk,unsigned char *sk);
-int crypto_sign(unsigned char *sm,unsigned long long *smlen,
-                  const unsigned char *m,unsigned long long mlen,
-                  const unsigned char *sk);
-int crypto_sign_open(unsigned char *m,unsigned long long *mlen,
-                     const unsigned char *sm,unsigned long long smlen,
-                     const unsigned char *pk);
+int ed25519_sign_keypair(unsigned char *pk,unsigned char *sk);
+int ed25519_sign(unsigned char *sm,unsigned long long *smlen,
+                 const unsigned char *m,unsigned long long mlen,
+                 const unsigned char *sk);
+int ed25519_sign_open(unsigned char *m,unsigned long long *mlen,
+                      const unsigned char *sm,unsigned long long smlen,
+                      const unsigned char *pk);
 
 #endif /* _ED25519_H_ */
diff --git a/src/cbits/keypair.c b/src/cbits/keypair.c
--- a/src/cbits/keypair.c
+++ b/src/cbits/keypair.c
@@ -3,7 +3,7 @@
 #include "sha512.h"
 #include "ge.h"
 
-int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)
+int ed25519_sign_keypair(unsigned char *pk,unsigned char *sk)
 {
   unsigned char h[64];
   ge_p3 A;
diff --git a/src/cbits/open.c b/src/cbits/open.c
--- a/src/cbits/open.c
+++ b/src/cbits/open.c
@@ -4,7 +4,7 @@
 #include "ge.h"
 #include "sc.h"
 
-int crypto_sign_open(
+int ed25519_sign_open(
   unsigned char *m,unsigned long long *mlen,
   const unsigned char *sm,unsigned long long smlen,
   const unsigned char *pk
diff --git a/src/cbits/sign.c b/src/cbits/sign.c
--- a/src/cbits/sign.c
+++ b/src/cbits/sign.c
@@ -3,7 +3,7 @@
 #include "ge.h"
 #include "sc.h"
 
-int crypto_sign(
+int ed25519_sign(
   unsigned char *sm,unsigned long long *smlen,
   const unsigned char *m,unsigned long long mlen,
   const unsigned char *sk
diff --git a/src/cbits/test.c b/src/cbits/test.c
--- a/src/cbits/test.c
+++ b/src/cbits/test.c
@@ -9,21 +9,21 @@
 {
   int r = 0;
 
-  crypto_sign_keypair(pk,sk);
+  ed25519_sign_keypair(pk,sk);
   printf("Keypair generated.\n");
 
   unsigned char *msg = "Hello";
   unsigned char sm[5+crypto_sign_BYTES];
   unsigned long long smlen;
 
-  r = crypto_sign(sm, &smlen, msg, 5, sk);
+  r = ed25519_sign(sm, &smlen, msg, 5, sk);
   assert(r == 0);
   printf("Signed message (length = %u)\n",smlen);
 
   unsigned long long mlen;
   unsigned char m[5+crypto_sign_BYTES];
 
-  r = crypto_sign_open(m, &mlen, sm, smlen, pk);
+  r = ed25519_sign_open(m, &mlen, sm, smlen, pk);
   assert(r == 0);
   printf("Verified message (length = %u)\n",mlen);
 
diff --git a/tests/doctests.hs b/tests/doctests.hs
deleted file mode 100644
--- a/tests/doctests.hs
+++ /dev/null
@@ -1,73 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
------------------------------------------------------------------------------
--- |
--- Module      :  Main (doctests)
--- Copyright   :  (C) 2012-13 Edward Kmett
--- License     :  BSD-style (see the file LICENSE)
--- Maintainer  :  Edward Kmett <ekmett@gmail.com>
--- Stability   :  provisional
--- Portability :  portable
---
--- This module provides doctests for a project based on the actual versions
--- of the packages it was built with. It requires a corresponding Setup.lhs
--- to be added to the project
------------------------------------------------------------------------------
-module Main where
-
-import Build_doctests (deps)
-import Control.Applicative
-import Control.Monad
-import Data.List
-import System.Directory
-import System.FilePath
-import Test.DocTest
-
-#if defined(mingw32_HOST_OS)
-#if defined(i386_HOST_ARCH)
-#define USE_CP
-import Control.Applicative
-import Control.Exception
-import Foreign.C.Types
-foreign import stdcall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool
-foreign import stdcall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt
-#elif defined(x86_64_HOST_ARCH)
-#define USE_CP
-import Control.Applicative
-import Control.Exception
-import Foreign.C.Types
-foreign import ccall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool
-foreign import ccall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt
-#endif
-#endif
-
--- | Run in a modified codepage where we can print UTF-8 values on Windows.
-withUnicode :: IO a -> IO a
-#ifdef USE_CP
-withUnicode m = do
-  cp <- c_GetConsoleCP
-  (c_SetConsoleCP 65001 >> m) `finally` c_SetConsoleCP cp
-#else
-withUnicode m = m
-#endif
-
-main :: IO ()
-main = withUnicode $ getSources >>= \sources -> doctest $
-    "-isrc"
-  : "-idist/build/autogen"
-  : "-optP-include"
-  : "-optPdist/build/autogen/cabal_macros.h"
-  : "-hide-all-packages"
-  : map ("-package="++) deps ++ sources
-
-getSources :: IO [FilePath]
-getSources = filter (isSuffixOf ".hs") <$> go "src"
-  where
-    go dir = do
-      (dirs, files) <- getFilesAndDirectories dir
-      (files ++) . concat <$> mapM go dirs
-
-getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])
-getFilesAndDirectories dir = do
-  c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir
-  (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c
diff --git a/tests/hlint.hs b/tests/hlint.hs
--- a/tests/hlint.hs
+++ b/tests/hlint.hs
@@ -1,5 +1,6 @@
 module Main where
 
+import Data.Monoid
 import Control.Monad
 import Language.Haskell.HLint
 import System.Environment
@@ -8,5 +9,6 @@
 main :: IO ()
 main = do
     args <- getArgs
-    hints <- hlint $ ["src", "--cpp-define=HLINT"] ++ args
+    hints <- hlint $ ["src", "benchmarks", "tests",
+                      "--cpp-define=HLINT"] `mappend` args
     unless (null hints) exitFailure
diff --git a/tests/hunit.hs b/tests/hunit.hs
deleted file mode 100644
--- a/tests/hunit.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# LANGUAGE TemplateHaskell #-}
-module Main
-       ( main  -- :: IO ()
-       ) where
-import Prelude as Prelude
-import Data.List as List
-import Data.Maybe
-import Data.Function
-import Control.Monad
-import Control.DeepSeq
-import Debug.Trace
-
-import Test.Tasty
-import Test.Tasty.TH
-import Test.Tasty.HUnit as HUnit
-
---------------------------------------------------------------------------------
--- Driver
-
-main :: IO ()
-main = $(defaultMainGenerator)
diff --git a/tests/properties.hs b/tests/properties.hs
--- a/tests/properties.hs
+++ b/tests/properties.hs
@@ -1,28 +1,24 @@
-{-# LANGUAGE TemplateHaskell #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP #-}
 module Main
        ( main  -- :: IO ()
        ) where
-import Prelude
-import Data.List as List
-import Data.Maybe
-import Data.Function
-import Control.Monad
-import Control.DeepSeq
-import Debug.Trace
+import           Control.Monad
+import           Data.ByteString          (ByteString)
+import qualified Data.ByteString          as S
 
-import Test.Tasty
-import Test.Tasty.TH
-import Test.Tasty.QuickCheck as QC
-import Test.QuickCheck.Property
+import           Crypto.Sign.Ed25519
 
-import Data.ByteString as S
-import Crypto.Sign.Ed25519
+import           System.Environment       (getArgs)
+import           Test.QuickCheck
+import           Test.QuickCheck.Property (morallyDubiousIOProperty)
+import           Text.Printf
 
 --------------------------------------------------------------------------------
 -- Orphans
 
 instance Arbitrary ByteString where
-  arbitrary = pack `liftM` arbitrary
+  arbitrary = S.pack `liftM` arbitrary
 
 instance Arbitrary SecretKey where
   arbitrary = SecretKey `liftM` arbitrary
@@ -36,34 +32,63 @@
 keypairProp :: ((PublicKey, SecretKey) -> Bool) -> Property
 keypairProp k = morallyDubiousIOProperty $ k `liftM` createKeypair
 
-prop_sign_verify :: ByteString -> Property
-prop_sign_verify xs
+roundtrip :: ByteString -> Property
+roundtrip xs
   = keypairProp $ \(pk,sk) -> verify pk (sign sk xs)
 
+roundtrip' :: ByteString -> Property
+roundtrip' xs
+  = keypairProp $ \(pk,sk) -> verify' pk xs (sign' sk xs)
+
 -- Generally the signature format is '<signature><original message>'
 -- and <signature> is of a fixed length (crypto_sign_BYTES), which in
 -- ed25519's case is 64. sign' drops the message appended at the end,
 -- so we just make sure we have constant length signatures.
-prop_sign'_length :: ByteString -> ByteString -> Property
-prop_sign'_length xs xs2
-  = keypairProp $ \(pk,sk) ->
+signLength :: (ByteString,ByteString) -> Property
+signLength (xs,xs2)
+  = keypairProp $ \(_,sk) ->
       let s1 = unSignature $ sign' sk xs
           s2 = unSignature $ sign' sk xs2
       in S.length s1 == S.length s2
 
 -- ed25519 has a sig length of 64
-prop_sign'_length2 :: ByteString -> Property
-prop_sign'_length2 xs
-  = keypairProp $ \(pk,sk) ->
+signLength2 :: ByteString -> Property
+signLength2 xs
+  = keypairProp $ \(_,sk) ->
       (64 == S.length (unSignature $ sign' sk xs))
 
-prop_verify' :: ByteString -> Property
-prop_verify' xs
-  = keypairProp $ \(pk,sk) ->
-      verify' pk xs (sign' sk xs)
-
 --------------------------------------------------------------------------------
 -- Driver
 
 main :: IO ()
-main = $(defaultMainGenerator)
+main = do
+  args <- fmap (drop 1) getArgs
+  let n = if null args then 100 else read (head args) :: Int
+  (results, passed) <- runTests n
+  printf "Passed %d tests!\n" (sum passed)
+  unless (and results) (fail "Not all tests passed!")
+
+runTests :: Int -> IO ([Bool], [Int])
+runTests ntests = fmap unzip . forM (tests ntests) $ \(s, a) ->
+  printf "%-40s: " s >> a
+
+tests :: Int -> [(String, IO (Bool,Int))]
+tests ntests =
+  [ ("Signature roundtrip",            wrap roundtrip)
+  , ("Detached signature roundtrip",   wrap roundtrip')
+  , ("Detached signature length",      wrap signLength)
+  , ("Detached signature length (#2)", wrap signLength2)
+  ]
+  where
+    wrap :: Testable prop => prop -> IO (Bool, Int)
+    wrap prop = do
+      r <- quickCheckWithResult stdArgs{maxSize=ntests} prop
+      case r of
+        Success n _ _           -> return (True, n)
+        GaveUp  n _ _           -> return (True, n)
+#if MIN_VERSION_QuickCheck(2,6,0)
+        Failure n _ _ _ _ _ _ _ -> return (False, n)
+#else
+        Failure n _ _ _ _ _ _   -> return (False, n)
+#endif
+        _                       -> return (False, 0)
