diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for base16
 
+## 0.3.0.1
+
+* Allow for mixed-case lenient decoding + validation
+* Bump testing for mixed-case hex
+
 ## 0.3.0.0
 
 * API for `decodeBase16With` has changed to require `ByteString` instead of `Text`. This is in alignment with work done on `base64`, which reflects
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
 
 ### Summary
 
-The following types are supported for Hex alphabet codecs:
+The following types have supported codecs:
 
 - `Data.ByteString`
 - `Data.ByteString.Lazy`
@@ -21,6 +21,7 @@
 Additionally this library has
 
 - Much better performance than `base16-bytestring` for encode and decode, with a more conventional api.
+- Support for mixed-case hex decoding (defaults to lower-case encoding by convention)
 - Optics for handling more complex structures with Base16 representations via the `base16-lens` package
 - Checks for both validity and correctness of Base16 encodings.
 
diff --git a/base16.cabal b/base16.cabal
--- a/base16.cabal
+++ b/base16.cabal
@@ -1,6 +1,6 @@
 cabal-version:   2.0
 name:            base16
-version:         0.3.0.0
+version:         0.3.0.1
 synopsis:        Fast RFC 4648-compliant Base16 encoding
 description:
   RFC 4648-compliant Base16 encodings and decodings.
@@ -23,8 +23,8 @@
   GHC ==8.2.2
    || ==8.4.4
    || ==8.6.5
-   || ==8.8.3
-   || ==8.10.1
+   || ==8.8.4
+   || ==8.10.2
 
 source-repository head
   type:     git
diff --git a/src/Data/ByteString/Base16.hs b/src/Data/ByteString/Base16.hs
--- a/src/Data/ByteString/Base16.hs
+++ b/src/Data/ByteString/Base16.hs
@@ -121,5 +121,5 @@
 -- True
 --
 isValidBase16 :: ByteString -> Bool
-isValidBase16 = all (flip elem "0123456789abcdef")
+isValidBase16 = all (flip elem "0123456789abcdefABCDEF")
 {-# INLINE isValidBase16 #-}
diff --git a/src/Data/ByteString/Lazy/Base16.hs b/src/Data/ByteString/Lazy/Base16.hs
--- a/src/Data/ByteString/Lazy/Base16.hs
+++ b/src/Data/ByteString/Lazy/Base16.hs
@@ -99,7 +99,7 @@
 decodeBase16Lenient = fromChunks
   . fmap B16.decodeBase16Lenient_
   . reChunk
-  . fmap (B.filter (flip elem "0123456789abcdef"))
+  . fmap (B.filter (flip elem "0123456789abcdefABCDEF"))
   . toChunks
 {-# INLINE decodeBase16Lenient #-}
 
@@ -132,5 +132,5 @@
 -- True
 --
 isValidBase16 :: ByteString -> Bool
-isValidBase16 = all (flip elem "0123456789abcdef")
+isValidBase16 = all (flip elem "0123456789abcdefABCDEF")
 {-# INLINE isValidBase16 #-}
diff --git a/test/Internal.hs b/test/Internal.hs
--- a/test/Internal.hs
+++ b/test/Internal.hs
@@ -21,11 +21,14 @@
 
 
 import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BS8
 import qualified Data.ByteString.Lazy as LBS
+import qualified Data.ByteString.Lazy.Char8 as LBS8
 import qualified Data.ByteString.Short as SBS
 import "base16" Data.ByteString.Base16 as B16
 import "base16" Data.ByteString.Lazy.Base16 as LB16
 import "base16" Data.ByteString.Short.Base16 as SB16
+import Data.Char (toLower)
 import Data.Proxy
 import Data.String
 import Data.Text (Text)
@@ -85,6 +88,7 @@
   decode :: bs -> Either Text bs
   lenient :: bs -> bs
 
+  lower :: bs -> bs
   correct :: bs -> Bool
   validate :: bs -> Bool
 
@@ -97,6 +101,7 @@
   lenient = B16.decodeBase16Lenient
   correct = B16.isBase16
   validate = B16.isValidBase16
+  lower = BS8.map toLower
 
 instance Harness 'LB16 LBS.ByteString where
   label = "Lazy ByteString"
@@ -106,6 +111,7 @@
   lenient = LB16.decodeBase16Lenient
   correct = LB16.isBase16
   validate = LB16.isValidBase16
+  lower = LBS8.map toLower
 
 instance Harness 'SB16 SBS.ShortByteString where
   label = "Short ByteString"
@@ -115,6 +121,7 @@
   lenient = SB16.decodeBase16Lenient
   correct = SB16.isBase16
   validate = SB16.isValidBase16
+  lower = SBS.toShort . BS8.map toLower . SBS.fromShort
 
 instance Harness 'T16 Text where
   label = "Text"
@@ -124,6 +131,7 @@
   lenient = T16.decodeBase16Lenient
   correct = T16.isBase16
   validate = T16.isValidBase16
+  lower = T.map toLower
 
 instance Harness 'TL16 TL.Text where
   label = "Lazy Text"
@@ -133,6 +141,7 @@
   lenient = TL16.decodeBase16Lenient
   correct = TL16.isBase16
   validate = TL16.isValidBase16
+  lower = TL.map toLower
 
 instance Harness 'TS16 TS.ShortText where
   label = "Short Text"
@@ -142,6 +151,7 @@
   lenient = TS16.decodeBase16Lenient
   correct = TS16.isBase16
   validate = TS16.isValidBase16
+  lower = TS.fromText . T.map toLower . TS.toText
 
 class Harness a cs
   => TextHarness (a :: Impl) cs bs
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -174,19 +174,39 @@
 
 rfcVectors :: forall a b proxy. Harness a b => proxy a -> TestTree
 rfcVectors _ = testGroup "RFC 4648 Test Vectors"
-    [ testCaseB16 "" ""
-    , testCaseB16 "f" "66"
-    , testCaseB16 "fo" "666f"
-    , testCaseB16 "foo" "666f6f"
-    , testCaseB16 "foob" "666f6f62"
-    , testCaseB16 "fooba" "666f6f6261"
-    , testCaseB16 "foobar" "666f6f626172"
+    [ testGroup "lower-case"
+      [ testCaseB16 "" ""
+      , testCaseB16 "f" "66"
+      , testCaseB16 "fo" "666f"
+      , testCaseB16 "foo" "666f6f"
+      , testCaseB16 "foob" "666f6f62"
+      , testCaseB16 "fooba" "666f6f6261"
+      , testCaseB16 "foobar" "666f6f626172"
+      ]
+    ,  testGroup "upper-case"
+      [ testCaseB16 "" ""
+      , testCaseB16 "f" "66"
+      , testCaseB16 "fo" "666F"
+      , testCaseB16 "foo" "666F6F"
+      , testCaseB16 "foob" "666F6F62"
+      , testCaseB16 "fooba" "666F6F6261"
+      , testCaseB16 "foobar" "666F6F626172"
+      ]
+    ,  testGroup "mixed-case"
+      [ testCaseB16 "" ""
+      , testCaseB16 "f" "66"
+      , testCaseB16 "fo" "666F"
+      , testCaseB16 "foo" "666F6f"
+      , testCaseB16 "foob" "666F6f62"
+      , testCaseB16 "fooba" "666F6f6261"
+      , testCaseB16 "foobar" "666F6f626172"
+      ]
     ]
   where
     testCaseB16 s t =
       testCaseSteps (show $ if s == "" then "empty" else s) $ \step -> do
         step "encode is sound"
-        t @=? encode @a s
+        lower t @=? encode @a s
 
         step "decode is sound"
         Right s @=? decode (encode s)
@@ -230,9 +250,9 @@
     [ testCaseB16 "" ""
     , testCaseB16 "f" "6+6"
     , testCaseB16 "fo" "6$6+6|f"
-    , testCaseB16 "foo" "==========6$$66()*f6f"
-    , testCaseB16 "foob" "66^%$&^6f6f62"
-    , testCaseB16 "fooba" "666f()*#@6f#)(@*)6()*)2()61"
+    , testCaseB16 "foo" "==========6$$66()*F6f"
+    , testCaseB16 "foob" "66^%$&^6f6F62"
+    , testCaseB16 "fooba" "666f()*#@6F#)(@*)6()*)2()61"
     , testCaseB16 "foobar" "6@6@6@f@6@f@6@2@6@1@7@2++++++++++++++++++++++++"
     ]
   where
