diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor.hs b/Codec/Encryption/OpenPGP/ASCIIArmor.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor.hs
@@ -1,5 +1,5 @@
 -- ASCIIArmor.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 -- ASCIIArmor/Decode.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
@@ -12,36 +12,34 @@
 
 import Codec.Encryption.OpenPGP.ASCIIArmor.Types
 import Codec.Encryption.OpenPGP.ASCIIArmor.Utils
-import Control.Applicative (many, (<|>), (<$>), Alternative, (<*), (<*>), (*>), optional)
+import Control.Applicative (many, (<|>), (<$>), (<*), (<*>), (*>), optional)
 import Data.Attoparsec.ByteString (Parser, many1, string, inClass, notInClass, satisfy, word8, (<?>))
 import qualified Data.Attoparsec.ByteString as AS
 import qualified Data.Attoparsec.ByteString.Lazy as AL
 import Data.Attoparsec.ByteString.Char8 (isDigit_w8, anyChar)
-import Data.Attoparsec.Combinator (manyTill)
 import Data.Bits (shiftL)
-import Data.ByteString (ByteString)
+import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.ByteString.Char8 as BC8
 import qualified Data.ByteString.Base64 as Base64
 import Data.Digest.CRC24 (crc24)
-import Data.Serialize (get)
-import Data.Serialize.Get (Get, runGet, getWord8)
-import Data.Serialize.Put (runPut, putWord32be)
+import Data.Binary.Get (Get, runGetOrFail, getWord8)
+import Data.Functor (($>))
 import Data.String (IsString, fromString)
 import Data.Word (Word32)
 
-decode :: IsString e => ByteString -> Either e [Armor]
+decode :: IsString e => B.ByteString -> Either e [Armor]
 decode bs = go (AS.parse parseArmors bs)
     where
-        go (AS.Fail t c e) = Left (fromString e)
+        go (AS.Fail _ _ e) = Left (fromString e)
         go (AS.Partial cont) = go (cont B.empty)
         go (AS.Done _ r) = Right r
 
 decodeLazy :: IsString e => BL.ByteString -> Either e [Armor]
 decodeLazy bs = go (AL.parse parseArmors bs)
     where
-        go (AL.Fail t c e) = Left (fromString e)
+        go (AL.Fail _ _ e) = Left (fromString e)
         go (AL.Done _ r) = Right r
 
 parseArmors :: Parser [Armor]
@@ -52,46 +50,46 @@
 
 clearsigned :: Parser Armor
 clearsigned = do
-    string "-----BEGIN PGP SIGNED MESSAGE-----" <?> "clearsign header"
-    lineEnding <?> "line ending"
+    _ <- string "-----BEGIN PGP SIGNED MESSAGE-----" <?> "clearsign header"
+    _ <- lineEnding <?> "line ending"
     headers <- armorHeaders <?> "clearsign headers"
-    blankishLine <?> "blank line"
+    _ <- blankishLine <?> "blank line"
     cleartext <- dashEscapedCleartext
     sig <- armor
-    return $ ClearSigned headers (BL.fromChunks [cleartext]) sig
+    return $ ClearSigned headers cleartext sig
 
 armor :: Parser Armor
 armor = do
     atype <- beginLine <?> "begin line"
     headers <- armorHeaders <?> "headers"
-    blankishLine <?> "blank line"
+    _ <- blankishLine <?> "blank line"
     payload <- base64Data <?> "base64 data"
-    endLine atype <?> "end line"
-    return $ Armor atype headers (BL.fromChunks [payload])
+    _ <- endLine atype <?> "end line"
+    return $ Armor atype headers payload
 
 beginLine :: Parser ArmorType
 beginLine = do
-    string "-----BEGIN PGP " <?> "leading minus-hyphens"
+    _ <- string "-----BEGIN PGP " <?> "leading minus-hyphens"
     atype <- pubkey <|> privkey <|> parts <|> message <|> signature
-    string "-----" <?> "trailing minus-hyphens"
-    many (satisfy (inClass " \t")) <?> "whitespace"
-    lineEnding <?> "line ending"
+    _ <- string "-----" <?> "trailing minus-hyphens"
+    _ <- many (satisfy (inClass " \t")) <?> "whitespace"
+    _ <- lineEnding <?> "line ending"
     return atype
     where
-        message = string "MESSAGE" *> return ArmorMessage
-        pubkey = string "PUBLIC KEY BLOCK" *> return ArmorPublicKeyBlock
-        privkey = string "PRIVATE KEY BLOCK" *> return ArmorPrivateKeyBlock
-        signature = string "SIGNATURE" *> return ArmorSignature
+        message = string "MESSAGE" $> ArmorMessage
+        pubkey = string "PUBLIC KEY BLOCK" $> ArmorPublicKeyBlock
+        privkey = string "PRIVATE KEY BLOCK" $> ArmorPrivateKeyBlock
+        signature = string "SIGNATURE" $> ArmorSignature
         parts = string "MESSAGE, PART " *> (partsdef <|> partsindef)
         partsdef = do
             firstnum <- num
-            word8 (fromIntegral . fromEnum $ '/')
+            _ <- word8 (fromIntegral . fromEnum $ '/')
             secondnum <- num
             return $ ArmorSplitMessage (BL.pack firstnum) (BL.pack secondnum)
         partsindef = ArmorSplitMessageIndefinite . BL.pack <$> num
         num = many1 (satisfy isDigit_w8) <?> "number"
 
-lineEnding :: Parser ByteString
+lineEnding :: Parser B.ByteString
 lineEnding = string "\n" <|> string "\r\n"
 
 armorHeaders :: Parser [(String, String)]
@@ -100,30 +98,30 @@
 armorHeader :: Parser (String, String)
 armorHeader = do
     key <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))
-    string ": "
+    _ <- string ": "
     val <- many1 (satisfy (notInClass "\n\r"))
-    lineEnding
+    _ <- lineEnding
     return (w8sToString key, w8sToString val)
     where
         w8sToString = BC8.unpack . B.pack
 
-blankishLine ::  Parser ByteString
+blankishLine ::  Parser B.ByteString
 blankishLine = many (satisfy (inClass " \t")) *> lineEnding
 
-endLine :: ArmorType -> Parser ByteString
+endLine :: ArmorType -> Parser B.ByteString
 endLine atype = do
-    string $ "-----END PGP " `B.append` aType atype `B.append` "-----"
+    _ <- string $ "-----END PGP " `B.append` aType atype `B.append` "-----"
     lineEnding
 
-aType :: ArmorType -> ByteString
-aType (ArmorMessage) = BC8.pack "MESSAGE"
-aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK"
-aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK"
+aType :: ArmorType -> B.ByteString
+aType ArmorMessage = BC8.pack "MESSAGE"
+aType ArmorPublicKeyBlock = BC8.pack "PUBLIC KEY BLOCK"
+aType ArmorPrivateKeyBlock = BC8.pack "PRIVATE KEY BLOCK"
 aType (ArmorSplitMessage x y) = BC8.pack "MESSAGE, PART " `B.append` l2s x `B.append` BC8.singleton '/' `B.append` l2s y
 aType (ArmorSplitMessageIndefinite x) = BC8.pack "MESSAGE, PART " `B.append` l2s x
-aType (ArmorSignature) = BC8.pack "SIGNATURE"
+aType ArmorSignature = BC8.pack "SIGNATURE"
 
-l2s :: BL.ByteString -> ByteString
+l2s :: BL.ByteString -> B.ByteString
 l2s = B.concat . BL.toChunks
 
 base64Data :: Parser ByteString
@@ -132,24 +130,24 @@
     cksum <- checksumLine
     let payload = B.concat ls
     let ourcksum = crc24 payload
-    case runGet d24 cksum of
-        Left err -> fail err
-        Right theircksum -> if theircksum == ourcksum then return payload else fail ("CRC24 mismatch: " ++ show (B.unpack cksum) ++  "/" ++ show theircksum ++ " vs. " ++ show ourcksum)
+    case runGetOrFail d24 (BL.fromStrict cksum) of
+        Left (_,_,err) -> fail err
+        Right (_,_,theircksum) -> if theircksum == ourcksum then return (BL.fromStrict payload) else fail ("CRC24 mismatch: " ++ show (B.unpack cksum) ++ "/" ++ show theircksum ++ " vs. " ++ show ourcksum)
     where
-        base64Line :: Parser ByteString
+        base64Line :: Parser B.ByteString
         base64Line = do
                         b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
                         pad <- many (word8 (fromIntegral . fromEnum $ '='))
-                        lineEnding
+                        _ <- lineEnding
                         let line = B.pack b64 `B.append` B.pack pad
                         case Base64.decode line of
                             Left err -> fail err
                             Right bs -> return bs
-        checksumLine :: Parser ByteString
+        checksumLine :: Parser B.ByteString
         checksumLine = do
-                        word8 (fromIntegral . fromEnum $ '=')
+                        _ <- word8 (fromIntegral . fromEnum $ '=')
                         b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
-                        lineEnding
+                        _ <- lineEnding
                         let line = B.pack b64
                         case Base64.decode line of
                             Left err -> fail err
@@ -169,9 +167,9 @@
 dashEscapedCleartext :: Parser ByteString
 dashEscapedCleartext = do
     ls <- many1 ((deLine <|> unescapedLine) <* lineEnding)
-    return $ crlfUnlines ls
+    return . BL.fromStrict $ crlfUnlines ls
     where
-        deLine :: Parser ByteString
+        deLine :: Parser B.ByteString
         deLine = B.pack <$> (string "- " *> many (satisfy (notInClass "\n\r")))
-        unescapedLine :: Parser ByteString
+        unescapedLine :: Parser B.ByteString
         unescapedLine = maybe B.empty B.pack <$> optional ((:) <$> satisfy (notInClass "-\n\r") <*> many (satisfy (notInClass "\n\r")))
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
@@ -1,5 +1,5 @@
 -- ASCIIArmor/Encode.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012-2018  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
@@ -12,13 +12,10 @@
 import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
-import qualified Data.ByteString.Char8 as BC8
 import qualified Data.ByteString.Lazy.Char8 as BLC8
 import qualified Data.ByteString.Base64 as Base64
 import Data.Digest.CRC24 (crc24Lazy)
-import Data.Serialize (put)
-import Data.Serialize.Put (runPutLazy, putWord32be)
-import Data.String (IsString, fromString)
+import Data.Binary.Put (runPut, putWord32be)
 
 encode :: [Armor] -> B.ByteString
 encode = B.concat . BL.toChunks . encodeLazy
@@ -40,15 +37,15 @@
 endLine atype = BLC8.pack "-----END PGP " `BL.append` aType atype `BL.append` BLC8.pack "-----\n"
 
 aType :: ArmorType -> ByteString
-aType (ArmorMessage) = BLC8.pack "MESSAGE"
-aType (ArmorPublicKeyBlock) = BLC8.pack "PUBLIC KEY BLOCK"
-aType (ArmorPrivateKeyBlock) = BLC8.pack "PRIVATE KEY BLOCK"
+aType ArmorMessage = BLC8.pack "MESSAGE"
+aType ArmorPublicKeyBlock = BLC8.pack "PUBLIC KEY BLOCK"
+aType ArmorPrivateKeyBlock = BLC8.pack "PRIVATE KEY BLOCK"
 aType (ArmorSplitMessage x y) = BLC8.pack $ "MESSAGE, PART " ++ show x ++ "/" ++ show y
 aType (ArmorSplitMessageIndefinite x) = BLC8.pack $ "MESSAGE, PART " ++ show x
-aType (ArmorSignature) = BLC8.pack "SIGNATURE"
+aType ArmorSignature = BLC8.pack "SIGNATURE"
 
 armorHeaders :: [(String, String)] -> ByteString
-armorHeaders ahs = BLC8.unlines . map armorHeader $ ahs
+armorHeaders = BLC8.unlines . map armorHeader
     where
         armorHeader :: (String, String) -> ByteString
         armorHeader (k, v) = BLC8.pack k `BL.append` BLC8.pack ": " `BL.append` BLC8.pack v
@@ -63,7 +60,7 @@
     | otherwise = BL.take (fromIntegral lw) bs : wordWrap lw (BL.drop (fromIntegral lw) bs)
 
 armorChecksum :: ByteString -> ByteString
-armorChecksum = BLC8.cons '=' . armorData . BL.tail . runPutLazy . putWord32be . crc24Lazy
+armorChecksum = BLC8.cons '=' . armorData . BL.tail . runPut . putWord32be . crc24Lazy
 
 dashEscape :: ByteString -> ByteString
 dashEscape = BLC8.unlines . map escapeLine . BLC8.lines
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Multipart.hs
@@ -1,5 +1,5 @@
 -- ASCIIArmor/Multipart.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
@@ -13,11 +13,12 @@
 import qualified Data.ByteString.Lazy as BL
 
 multipartMerge :: [Armor] -> Armor
-multipartMerge as = go as (Armor ArmorMessage [] BL.empty)
+multipartMerge as' = go as' (Armor ArmorMessage [] BL.empty)
     where
         go :: [Armor] -> Armor -> Armor
         go [] state = state
         go (Armor at hs bs:as) state = go as (go' at hs bs state)
+        go _ _ = error "This shouldn't happen."
         go' :: ArmorType -> [(String,String)] -> ByteString -> Armor -> Armor
         go' (ArmorSplitMessage _ _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `BL.append` bs)
         go' (ArmorSplitMessageIndefinite _) hs bs (Armor _ ohs obs) = Armor ArmorMessage (ohs ++ hs) (obs `BL.append` bs)
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Types.hs
@@ -1,5 +1,5 @@
 -- ASCIIArmor/Decode.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Utils.hs
@@ -1,5 +1,5 @@
 -- ASCIIArmor/Utils.hs: OpenPGP (RFC4880) ASCII armor implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
diff --git a/Data/Digest/CRC24.hs b/Data/Digest/CRC24.hs
--- a/Data/Digest/CRC24.hs
+++ b/Data/Digest/CRC24.hs
@@ -1,5 +1,5 @@
 -- CRC24.hs: OpenPGP (RFC4880) CRC24 implementation
--- Copyright Ⓒ 2012  Clint Adams
+-- Copyright © 2012  Clint Adams
 -- This software is released under the terms of the ISC license.
 -- (See the LICENSE file).
 
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Ⓒ 2012 Clint Adams <clint@debian.org>
+Copyright © 2012 Clint Adams <clint@debian.org>
 
 Permission to use, copy, modify, and/or distribute this software
 for any purpose with or without fee is hereby granted, provided
diff --git a/bench/mark.hs b/bench/mark.hs
new file mode 100644
--- /dev/null
+++ b/bench/mark.hs
@@ -0,0 +1,16 @@
+-- mark.hs: openpgp-asciiarmor benchmark suite
+-- Copyright © 2018  Clint Adams
+-- This software is released under the terms of the ISC license.
+-- (See the LICENSE file).
+
+{-# LANGUAGE FlexibleContexts, OverloadedStrings #-}
+
+import Criterion.Main
+
+import Data.Digest.CRC24
+
+main :: IO ()
+main = defaultMain [
+  bgroup "crc" [ bench "crc24"  $ whnf crc24 "test"
+               ]
+                   ]
diff --git a/openpgp-asciiarmor.cabal b/openpgp-asciiarmor.cabal
--- a/openpgp-asciiarmor.cabal
+++ b/openpgp-asciiarmor.cabal
@@ -1,13 +1,13 @@
 Name:                openpgp-asciiarmor
-Version:             0.1
+Version:             0.1.1
 Synopsis:            OpenPGP (RFC4880) ASCII Armor codec
 Description:         OpenPGP (RFC4880) ASCII Armor codec
 Homepage:            http://floss.scru.org/openpgp-asciiarmor
-License:             OtherLicense
+License:             ISC
 License-file:        LICENSE
 Author:              Clint Adams
 Maintainer:          Clint Adams <clint@debian.org>
-Copyright:           2012, Clint Adams
+Copyright:           2012-2018 Clint Adams
 Category:            Codec, Data
 Build-type:          Simple
 Extra-source-files: tests/suite.hs
@@ -36,27 +36,43 @@
   Other-Modules: Data.Digest.CRC24
                , Codec.Encryption.OpenPGP.ASCIIArmor.Multipart
                , Codec.Encryption.OpenPGP.ASCIIArmor.Utils
+  Ghc-options: -Wall
   Build-depends: attoparsec
                , base                  > 4       && < 5
                , base64-bytestring
+               , binary
                , bytestring
-               , cereal
-  default-language: Haskell98
+  default-language: Haskell2010
 
 
 Test-Suite tests
   type:       exitcode-stdio-1.0
   main-is:    tests/suite.hs
+  Ghc-options: -Wall
   Build-depends: attoparsec
                , base                  > 4       && < 5
                , base64-bytestring
+               , binary
                , bytestring
-               , cereal
-               , HUnit
-               , test-framework
-               , test-framework-hunit
-  default-language: Haskell98
+               , tasty
+               , tasty-hunit
+  default-language: Haskell2010
 
+Benchmark benchmark
+  type:       exitcode-stdio-1.0
+  main-is:    bench/mark.hs
+  Ghc-options: -Wall
+  Build-depends: openpgp-asciiarmor
+               , base
+               , bytestring
+               , criterion
+  default-language: Haskell2010
+
 source-repository head
   type:     git
-  location: git://git.debian.org/users/clint/openpgp-asciiarmor.git
+  location: https://salsa.debian.org/clint/openpgp-asciiarmor.git
+
+source-repository this
+  type:     git
+  location: https://salsa.debian.org/clint/openpgp-asciiarmor.git
+  tag:      openpgp-asciiarmor/v0.1.1
diff --git a/tests/suite.hs b/tests/suite.hs
--- a/tests/suite.hs
+++ b/tests/suite.hs
@@ -1,7 +1,5 @@
-import Test.Framework (defaultMain, testGroup)
-import Test.Framework.Providers.HUnit
-
-import Test.HUnit
+import Test.Tasty (defaultMain, testGroup, TestTree)
+import Test.Tasty.HUnit (Assertion, assertEqual, assertFailure, testCase)
 
 import Codec.Encryption.OpenPGP.ASCIIArmor (decode, decodeLazy, encode, encodeLazy, multipartMerge)
 import Codec.Encryption.OpenPGP.ASCIIArmor.Types
@@ -27,6 +25,7 @@
         Right as -> assertEqual ("for " ++ fp) tbss (map getPayload as)
     where
         getPayload (Armor _ _ pl) = pl
+        getPayload _ = error "This should not happen."
 
 testArmorMultipartDecode :: FilePath -> FilePath -> Assertion
 testArmorMultipartDecode fp target = do
@@ -37,6 +36,7 @@
         Right as -> assertEqual ("for " ++ fp) tbs (getPayload (multipartMerge as))
     where
         getPayload (Armor _ _ pl) = pl
+        getPayload _ = error "This should not happen."
 
 testClearsignedDecodeBody :: FilePath -> FilePath -> Assertion
 testClearsignedDecodeBody fp target = do
@@ -45,8 +45,10 @@
     case decodeLazy bs of
         Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
         Right [a] -> assertEqual ("for " ++ fp) (convertEndings tbs) (getBody a)
+        _ -> assertFailure "This shouldn't happen."
     where
         getBody (ClearSigned _ txt _) = txt
+        getBody _ = error "This should not happen."
         convertEndings = crlfUnlinesLazy . BLC8.lines
 
 testClearsignedDecodeSig :: FilePath -> FilePath -> Assertion
@@ -56,34 +58,37 @@
     case decodeLazy bs of
         Left e -> assertFailure $ "Decode failed (" ++ e ++ ") on " ++ fp
         Right [a] -> assertEqual ("for " ++ fp) tbs (getSig a)
+        _ -> assertFailure "This shouldn't happen."
     where
         getSig (ClearSigned _ _ (Armor _ _ sig)) = sig
+        getSig _ = error "This should not happen."
 
 testArmorEncode :: [FilePath] -> FilePath -> Assertion
 testArmorEncode fps target = do
     bss <- mapM (\fp -> BL.readFile $ "tests/data/" ++ fp) fps
     tbs <- BL.readFile $ "tests/data/" ++ target
-    assertEqual ("literaldata") tbs (encodeLazy (map (\bs -> Armor ArmorMessage [("Version","OpenPrivacy 0.99")] bs) bss))
+    assertEqual "literaldata" tbs (encodeLazy (map (Armor ArmorMessage [("Version","OpenPrivacy 0.99")]) bss))
 
 testClearsignedEncode :: FilePath -> FilePath -> FilePath -> Assertion
 testClearsignedEncode ftxt fsig ftarget = do
     txt <- BL.readFile $ "tests/data/" ++ ftxt
     sig <- BL.readFile $ "tests/data/" ++ fsig
     target <- BL.readFile $ "tests/data/" ++ ftarget
-    assertEqual ("clearsigned encode") target (encodeLazy [ClearSigned [("Hash","SHA1")] txt (Armor ArmorSignature [("Version","OpenPrivacy 0.99")] sig)])
+    assertEqual "clearsigned encode" target (encodeLazy [ClearSigned [("Hash","SHA1")] txt (Armor ArmorSignature [("Version","OpenPrivacy 0.99")] sig)])
 
 testStrictDecode :: FilePath -> Assertion
 testStrictDecode fp = do
     bs <- BL.readFile $ "tests/data/" ++ fp
-    assertEqual ("strict decode") (decodeLazy bs :: Either String [Armor]) (decode (B.concat . BL.toChunks $ bs) :: Either String [Armor])
+    assertEqual "strict decode" (decodeLazy bs :: Either String [Armor]) (decode (B.concat . BL.toChunks $ bs) :: Either String [Armor])
 
 testStrictEncode :: FilePath -> Assertion
 testStrictEncode fp = do
     bs <- BL.readFile $ "tests/data/" ++ fp
     let fakearmors = [Armor ArmorMessage [("Version","OpenPrivacy 0.99")] bs, ClearSigned [("Hash","SHA1")] bs (Armor ArmorSignature [("Version","OpenPrivacy 0.99")] bs)]
-    assertEqual ("strict encode") (encodeLazy fakearmors) (BL.fromChunks [(encode fakearmors)])
+    assertEqual "strict encode" (encodeLazy fakearmors) (BL.fromChunks [encode fakearmors])
 
-tests = [
+tests :: TestTree
+tests = testGroup "openpgp-asciiarmor" [
    testGroup "CRC24" [
       testCase "CRC24: A" (testCRC24 (BC8.pack "A") 16680698)
     , testCase "CRC24: Haskell" (testCRC24 (BC8.pack "Haskell") 15612750)
@@ -105,4 +110,5 @@
     ]
  ]
 
+main :: IO ()
 main = defaultMain tests
