diff --git a/Codec/Encryption/OpenPGP/Arbitrary.hs b/Codec/Encryption/OpenPGP/Arbitrary.hs
--- a/Codec/Encryption/OpenPGP/Arbitrary.hs
+++ b/Codec/Encryption/OpenPGP/Arbitrary.hs
@@ -1,10 +1,8 @@
 -- Arbitrary.hs: QuickCheck instances
--- Copyright © 2014-2016  Clint Adams
+-- Copyright © 2014-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
-
 module Codec.Encryption.OpenPGP.Arbitrary () where
 
 import Codec.Encryption.OpenPGP.Types
@@ -171,9 +169,3 @@
 
 instance Arbitrary NotationValue where
     arbitrary = fmap NotationValue arbitrary
-
-#if !MIN_VERSION_QuickCheck(2,9,0)
--- FIXME: this should be elsewhere
-instance Arbitrary a => Arbitrary (NE.NonEmpty a) where
-    arbitrary = NE.fromList `fmap` listOf1 arbitrary
-#endif
diff --git a/Codec/Encryption/OpenPGP/CFB.hs b/Codec/Encryption/OpenPGP/CFB.hs
--- a/Codec/Encryption/OpenPGP/CFB.hs
+++ b/Codec/Encryption/OpenPGP/CFB.hs
@@ -1,11 +1,9 @@
 -- CFB.hs: OpenPGP (RFC4880) CFB mode
--- Copyright © 2013-2016  Clint Adams
+-- Copyright © 2013-2018  Clint Adams
 -- Copyright © 2013  Daniel Kahn Gillmor
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
-
 module Codec.Encryption.OpenPGP.CFB (
    decrypt
  , decryptNoNonce
@@ -16,9 +14,6 @@
 import Codec.Encryption.OpenPGP.BlockCipher (withSymmetricCipher)
 import Codec.Encryption.OpenPGP.Internal.HOBlockCipher
 import Codec.Encryption.OpenPGP.Types
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>), (<*>))
-#endif
 import qualified Data.ByteString as B
 
 decryptOpenPGPCfb :: SymmetricAlgorithm -> B.ByteString -> B.ByteString -> Either String B.ByteString
diff --git a/Codec/Encryption/OpenPGP/Internal.hs b/Codec/Encryption/OpenPGP/Internal.hs
--- a/Codec/Encryption/OpenPGP/Internal.hs
+++ b/Codec/Encryption/OpenPGP/Internal.hs
@@ -72,8 +72,8 @@
   where pkParams f = MPI . f . DSA.public_params $ k
 
 pubkeyToMPIs (ElGamalPubKey p g y) = [MPI p, MPI g, MPI y]
-pubkeyToMPIs (ECDHPubKey ((ECDSA_PublicKey (ECDSA.PublicKey _ q))) _ _) = [MPI (os2ip (point2BS q))]
-pubkeyToMPIs (ECDSAPubKey ((ECDSA_PublicKey (ECDSA.PublicKey _ q)))) = [MPI (os2ip (point2BS q))]
+pubkeyToMPIs (ECDHPubKey (ECDSA_PublicKey (ECDSA.PublicKey _ q)) _ _) = [MPI (os2ip (point2BS q))]
+pubkeyToMPIs (ECDSAPubKey (ECDSA_PublicKey (ECDSA.PublicKey _ q))) = [MPI (os2ip (point2BS q))]
 
 multiplicativeInverse :: Integral a => a -> a -> a
 multiplicativeInverse _ 1 = 1
@@ -118,4 +118,4 @@
 
 point2BS :: ECCT.PublicPoint -> B.ByteString
 point2BS (ECCT.Point x y) = B.concat [B.singleton 0x04, i2osp x, i2osp y] -- FIXME: check for length equality?
-point2BS (ECCT.PointO) = error "FIXME: point at infinity"
+point2BS ECCT.PointO = error "FIXME: point at infinity"
diff --git a/Codec/Encryption/OpenPGP/KeySelection.hs b/Codec/Encryption/OpenPGP/KeySelection.hs
--- a/Codec/Encryption/OpenPGP/KeySelection.hs
+++ b/Codec/Encryption/OpenPGP/KeySelection.hs
@@ -1,9 +1,8 @@
 -- KeySelection.hs: OpenPGP (RFC4880) ways to ask for keys
--- Copyright © 2014-2016  Clint Adams
+-- Copyright © 2014-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 module Codec.Encryption.OpenPGP.KeySelection (
@@ -12,9 +11,6 @@
 ) where
 
 import Codec.Encryption.OpenPGP.Types
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>), (*>))
-#endif
 import Control.Applicative (optional)
 import Control.Monad ((<=<))
 import Crypto.Number.Serialize (i2osp)
diff --git a/Codec/Encryption/OpenPGP/KeyringParser.hs b/Codec/Encryption/OpenPGP/KeyringParser.hs
--- a/Codec/Encryption/OpenPGP/KeyringParser.hs
+++ b/Codec/Encryption/OpenPGP/KeyringParser.hs
@@ -1,10 +1,8 @@
 -- KeyringParser.hs: OpenPGP (RFC4880) transferable keys parsing
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
-
 module Codec.Encryption.OpenPGP.KeyringParser (
  -- * Parsers
    parseAChunk
@@ -30,13 +28,7 @@
 ) where
 
 import Control.Applicative (many, (<|>))
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>))
-#endif
 import Data.Maybe (catMaybes)
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid (Monoid, mconcat)
-#endif
 import Data.Monoid ((<>))
 
 import Data.Text (Text)
diff --git a/Codec/Encryption/OpenPGP/SecretKey.hs b/Codec/Encryption/OpenPGP/SecretKey.hs
--- a/Codec/Encryption/OpenPGP/SecretKey.hs
+++ b/Codec/Encryption/OpenPGP/SecretKey.hs
@@ -1,5 +1,5 @@
 -- SecretKey.hs: OpenPGP (RFC4880) secret key encryption/decryption
--- Copyright © 2013-2016  Clint Adams
+-- Copyright © 2013-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
diff --git a/Codec/Encryption/OpenPGP/Serialize.hs b/Codec/Encryption/OpenPGP/Serialize.hs
--- a/Codec/Encryption/OpenPGP/Serialize.hs
+++ b/Codec/Encryption/OpenPGP/Serialize.hs
@@ -1,10 +1,8 @@
 -- Serialize.hs: OpenPGP (RFC4880) serialization (using cereal)
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
-
 module Codec.Encryption.OpenPGP.Serialize (
   -- * Serialization functions
    putSKAddendum
@@ -13,9 +11,6 @@
  , parsePkts
 ) where
 
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>))
-#endif
 import Control.Applicative (many, some)
 import Control.Lens ((^.), _1)
 import Control.Monad (guard, replicateM, replicateM_)
@@ -36,9 +31,6 @@
 import Data.Binary.Get (Get, getByteString, getLazyByteString, getRemainingLazyByteString, getWord8, getWord16be, getWord32be, getWord16le, runGetOrFail, ByteOffset)
 import Data.Binary.Put (Put, putWord8, putWord16be, putWord32be, putByteString, putLazyByteString, putWord16le, runPut)
 import qualified Data.Foldable as F
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid (mempty)
-#endif
 import Data.Set (Set)
 import qualified Data.Set as Set
 import qualified Data.Text as T
@@ -1270,7 +1262,8 @@
 
 putTK :: TK -> Put
 putTK key = do
-    put (PublicKey (key^.tkKey._1))
+    let pkp = key^.tkKey._1
+    maybe (put (PublicKey pkp)) (\ska -> put (SecretKey pkp ska)) (snd (key^.tkKey))
     mapM_ (put . Signature) (_tkRevs key)
     mapM_ putUid' (_tkUIDs key)
     mapM_ putUat' (_tkUAts key)
diff --git a/Codec/Encryption/OpenPGP/Signatures.hs b/Codec/Encryption/OpenPGP/Signatures.hs
--- a/Codec/Encryption/OpenPGP/Signatures.hs
+++ b/Codec/Encryption/OpenPGP/Signatures.hs
@@ -1,10 +1,8 @@
 -- Signatures.hs: OpenPGP (RFC4880) signature verification
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
-
 module Codec.Encryption.OpenPGP.Signatures (
    verifySigWith
  , verifyAgainstKeyring
@@ -12,9 +10,6 @@
  , verifyTKWith
 ) where
 
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>), (<*>))
-#endif
 import Control.Error.Util (hush)
 import Control.Lens ((^.), _1)
 import Control.Monad (liftM2)
@@ -27,12 +22,7 @@
 
 import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString.Lazy as BL
-import Data.Either (lefts, rights)
-#if MIN_VERSION_base(4,7,0)
-import Data.Either (isRight)
-#else
-import Control.Error.Util (isRight)
-#endif
+import Data.Either (isRight, lefts, rights)
 import Data.IxSet.Typed ((@=))
 import qualified Data.IxSet.Typed as IxSet
 import Data.List.NonEmpty (NonEmpty(..))
diff --git a/Codec/Encryption/OpenPGP/Types/Internal/Base.hs b/Codec/Encryption/OpenPGP/Types/Internal/Base.hs
--- a/Codec/Encryption/OpenPGP/Types/Internal/Base.hs
+++ b/Codec/Encryption/OpenPGP/Types/Internal/Base.hs
@@ -1,9 +1,8 @@
 -- Base.hs: OpenPGP (RFC4880) data types
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
@@ -16,9 +15,6 @@
 
 import GHC.Generics (Generic)
 
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>))
-#endif
 import Control.Applicative ((<|>))
 import Control.Arrow ((***))
 import Control.Lens (makeLenses)
@@ -41,9 +37,6 @@
 import qualified Data.List.NonEmpty as NE
 import Data.List.Split (chunksOf)
 import Data.Maybe (fromMaybe)
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid (Monoid, mempty)
-#endif
 import Data.Monoid ((<>))
 import Data.Ord (comparing)
 import Data.Semigroup (Semigroup)
@@ -992,7 +985,7 @@
 
 $(ATH.deriveJSON ATH.defaultOptions ''ImageFormat)
 
-data ImageHeader = ImageHV1 ImageFormat
+newtype ImageHeader = ImageHV1 ImageFormat
     deriving (Data, Eq, Generic, Show, Typeable)
 
 instance Ord ImageHeader where
diff --git a/Codec/Encryption/OpenPGP/Types/Internal/CryptoniteNewtypes.hs b/Codec/Encryption/OpenPGP/Types/Internal/CryptoniteNewtypes.hs
--- a/Codec/Encryption/OpenPGP/Types/Internal/CryptoniteNewtypes.hs
+++ b/Codec/Encryption/OpenPGP/Types/Internal/CryptoniteNewtypes.hs
@@ -1,11 +1,10 @@
 -- CryptoniteNewtypes.hs: OpenPGP (RFC4880) newtype wrappers for some cryptonite types
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 module Codec.Encryption.OpenPGP.Types.Internal.CryptoniteNewtypes where
 
diff --git a/Codec/Encryption/OpenPGP/Types/Internal/PacketClass.hs b/Codec/Encryption/OpenPGP/Types/Internal/PacketClass.hs
--- a/Codec/Encryption/OpenPGP/Types/Internal/PacketClass.hs
+++ b/Codec/Encryption/OpenPGP/Types/Internal/PacketClass.hs
@@ -1,5 +1,5 @@
 -- PacketClass.hs: OpenPGP (RFC4880) data types
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
@@ -51,7 +51,7 @@
 instance Pretty PKESK where
     pretty = pretty . toPkt
 
-data Signature = Signature   -- FIXME?
+newtype Signature = Signature   -- FIXME?
     { _signaturePayload :: SignaturePayload
     } deriving (Data, Eq, Show, Typeable)
 instance Packet Signature where
@@ -116,7 +116,7 @@
 instance Pretty SecretKey where
     pretty = pretty . toPkt
 
-data PublicKey = PublicKey
+newtype PublicKey = PublicKey
     { _publicKeyPKPayload :: PKPayload
     } deriving (Data, Eq, Show, Typeable)
 instance Packet PublicKey where
@@ -160,7 +160,7 @@
 instance Pretty CompressedData where
     pretty = pretty . toPkt
 
-data SymEncData = SymEncData
+newtype SymEncData = SymEncData
     { _symEncDataPayload :: ByteString
     } deriving (Data, Eq, Show, Typeable)
 instance Packet SymEncData where
@@ -174,7 +174,7 @@
 instance Pretty SymEncData where
     pretty = pretty . toPkt
 
-data Marker = Marker
+newtype Marker = Marker
     { _markerPayload :: ByteString
     } deriving (Data, Eq, Show, Typeable)
 instance Packet Marker where
@@ -205,7 +205,7 @@
 instance Pretty LiteralData where
     pretty = pretty . toPkt
 
-data Trust = Trust
+newtype Trust = Trust
     { _trustPayload :: ByteString
     } deriving (Data, Eq, Show, Typeable)
 instance Packet Trust where
@@ -219,7 +219,7 @@
 instance Pretty Trust where
     pretty = pretty . toPkt
 
-data UserId = UserId
+newtype UserId = UserId
     { _userIdPayload :: Text
     } deriving (Data, Eq, Show, Typeable)
 instance Packet UserId where
@@ -233,7 +233,7 @@
 instance Pretty UserId where
     pretty = pretty . toPkt
 
-data PublicSubkey = PublicSubkey
+newtype PublicSubkey = PublicSubkey
     { _publicSubkeyPKPayload :: PKPayload
     } deriving (Data, Eq, Show, Typeable)
 instance Packet PublicSubkey where
@@ -247,7 +247,7 @@
 instance Pretty PublicSubkey where
     pretty = pretty . toPkt
 
-data UserAttribute = UserAttribute
+newtype UserAttribute = UserAttribute
     { _userAttributeSubPackets :: [UserAttrSubPacket]
     } deriving (Data, Eq, Show, Typeable)
 instance Packet UserAttribute where
@@ -276,7 +276,7 @@
 instance Pretty SymEncIntegrityProtectedData where
     pretty = pretty . toPkt
 
-data ModificationDetectionCode = ModificationDetectionCode
+newtype ModificationDetectionCode = ModificationDetectionCode
     { _modificationDetectionCodePayload :: ByteString
     } deriving (Data, Eq, Show, Typeable)
 instance Packet ModificationDetectionCode where
diff --git a/Codec/Encryption/OpenPGP/Types/Internal/Pkt.hs b/Codec/Encryption/OpenPGP/Types/Internal/Pkt.hs
--- a/Codec/Encryption/OpenPGP/Types/Internal/Pkt.hs
+++ b/Codec/Encryption/OpenPGP/Types/Internal/Pkt.hs
@@ -1,9 +1,8 @@
 -- Pkt.hs: OpenPGP (RFC4880) Pkt data types
--- Copyright © 2012-2016  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the Expat license.
 -- (See the LICENSE file).
 
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
@@ -28,9 +27,6 @@
 import Data.Hashable (Hashable(..))
 import Data.List.NonEmpty (NonEmpty)
 import qualified Data.List.NonEmpty as NE
-#if !MIN_VERSION_base(4,8,0)
-import Data.Monoid (mempty)
-#endif
 import Data.Monoid ((<>))
 import Data.Ord (comparing)
 import Data.Text (Text)
diff --git a/hOpenPGP.cabal b/hOpenPGP.cabal
--- a/hOpenPGP.cabal
+++ b/hOpenPGP.cabal
@@ -1,5 +1,5 @@
 Name:                hOpenPGP
-Version:             2.7
+Version:             2.7.1
 Synopsis:            native Haskell implementation of OpenPGP (RFC4880)
 Description:         native Haskell implementation of OpenPGP (RFC4880), plus Camellia (RFC5581), plus ECC (RFC6637)
 Homepage:            https://salsa.debian.org/clint/hOpenPGP
@@ -191,7 +191,7 @@
   Build-depends: aeson
                , asn1-encoding
                , attoparsec
-               , base                  > 4       && < 5
+               , base                  > 4.8     && < 5
                , base16-bytestring
                , base64-bytestring
                , bifunctors
@@ -241,7 +241,7 @@
                , aeson
                , asn1-encoding
                , attoparsec
-               , base                  > 4       && < 5
+               , base                  > 4.8     && < 5
                , base16-bytestring
                , bifunctors
                , bytestring
@@ -275,7 +275,7 @@
                , tasty
                , tasty-hunit
                , tasty-quickcheck
-               , QuickCheck
+               , QuickCheck             > 2.9
                , quickcheck-instances
                , resourcet              > 0.4
   if flag(network-uri)
@@ -290,7 +290,7 @@
   Ghc-options: -Wall
   Build-depends: hOpenPGP
                , aeson
-               , base                  > 4       && < 5
+               , base                  > 4.8     && < 5
                , base16-bytestring
                , base64-bytestring
                , bifunctors
@@ -338,4 +338,4 @@
 source-repository this
   type:     git
   location: https://salsa.debian.org/clint/hOpenPGP.git
-  tag:      v2.7
+  tag:      v2.7.1
diff --git a/tests/suite.hs b/tests/suite.hs
--- a/tests/suite.hs
+++ b/tests/suite.hs
@@ -49,6 +49,8 @@
 runGet :: Get a -> BL.ByteString -> Either String a
 runGet g bs = bimap (\(_,_,x) -> x) (\(_,_,x) -> x) (runGetOrFail g bs)
 
+-- FIXME: nothing tests serialization of TKs
+
 testSerialization :: FilePath -> Assertion
 testSerialization fpr = do
     bs <- BL.readFile $ "tests/data/" ++ fpr
